var pop_divs = new Array();

function Popdiv(targetdiv, param, manualsetup) {
  var arrindex = 0;
  var incTimer = null;
  var decTimer = null;
  var slideTimer = null;

  this.manualsetup = manualsetup;
  this.param = param;

  this.setup = function() {
    if (this.param == null) this.param = new Object();

    if (typeof(targetdiv) != "object")
      targetdiv = document.getElementById(targetdiv);
		this.div = targetdiv;

    this.oriPos = getTargetAbsPos();
    this.oriSize = getTargetSize();

    if (this.param["fade"] == null) this.param["fade"] = true; 
    if (this.param["growdirection"] == null) this.param["growdirection"] = "none";  //none, horizontal, vertical, both
    if (this.param["groworigin"] == null) this.param["groworigin"] = "topleft";  //left, top, right, bottom, topleft, topright, bottomleft, bottomright, center

    if (this.param["visiblemode"] == null) this.param["visiblemode"] = "display";
    if (this.param["steps"] == null) this.param["steps"] = 10;
    if (this.param["speed"] == null) this.param["speed"] = 10;
    if (this.param["minopacity"] == null) this.param["minopacity"] = 0;
    if (this.param["maxopacity"] == null) this.param["maxopacity"] = 100;
    if (this.param["minwidth"] == null) this.param["minwidth"] = 0;
    if (this.param["maxwidth"] == null) this.param["maxwidth"] = this.oriSize.width;
    if (this.param["minheight"] == null) this.param["minheight"] = 0;
    if (this.param["maxheight"] == null) this.param["maxheight"] = this.oriSize.height;
    if (this.param["visible"] == null) this.param["visible"] = false;
    if (this.param["onOpened"] == null) this.param["onOpened"] = null;
    if (this.param["beforeShow"] == null) this.param["beforeShow"] = null;
    if (this.param["moveable"] == null) this.param["moveable"] = false;
    
    this.opacity = 0;
    this.fadeStep = (this.param["maxopacity"]-this.param["minopacity"])/this.param["steps"];
    this.growStep = {
      width:(this.param["maxwidth"]-this.param["minwidth"])/this.param["steps"],
      height:(this.param["maxheight"]-this.param["minheight"])/this.param["steps"]
    }

    if (this.param["moveable"]) this.makeMoveable();
  }

  this.makeMoveable = function() {
    this.param["moveable"] = true;
    if (targetdiv) {
      targetdiv.style["cursor"] = "move";
      if (targetdiv.attachEvent) headdiv.attachEvent('onmousedown', pop_divs[arrindex].startDrag);
      else targetdiv.addEventListener("mousedown", pop_divs[arrindex].startDrag, false);
    }
  }

  this.cancelMoveable = function() {
    this.param["moveable"] = false;
    if (targetdiv) {
      targetdiv.style["cursor"] = "normal";
      if (document.detachEvent) document.detachEvent('onmousedown', pop_divs[arrindex].startDrag);
      else document.removeEventListener("mousedown", pop_divs[arrindex].startDrag, false);
    }
  }

  var refPoint = new Object();
  var dragging = false;

  this.startDrag = function(event) {
    if (document.attachEvent) {
      document.attachEvent('onmousemove', pop_divs[arrindex].drag);
      document.attachEvent('onmouseup', pop_divs[arrindex].endDrag);
    }
    else {
      document.addEventListener("mousemove", pop_divs[arrindex].drag, false);
      document.addEventListener("mouseup", pop_divs[arrindex].endDrag, false);
    }
    refPoint = getEventPos(event);
    var divpos = getTargetPos();
    refPoint.x -= divpos.left;
    refPoint.y -= divpos.top;
    dragging = true;
  }
  
  function getTargetAbsPos() {
    var adisp = targetdiv.style.display;
    targetdiv.style.display = "block";
    var res = {left:targetdiv.offsetLeft, top:targetdiv.offsetTop};
    targetdiv.style.display = adisp;
    var adiv = targetdiv;
    while (adiv.offsetParent) {
      adiv = adiv.offsetParent;
      res.left += adiv.offsetLeft;
      res.top += adiv.offsetTop;
    }
    return res;
  }

  function getTargetPos() {
    var res = {left:parseInt(getCssParam(targetdiv, "left")), top:parseInt(getCssParam(targetdiv, "top"))};
    if (isNaN(res.left) || isNaN(res.top)) {
      res = {left:targetdiv.offsetLeft, top:targetdiv.offsetTop};
      res.left -= getCssParam(targetdiv, "marginLeft", true);
      res.top -= getCssParam(targetdiv, "marginTop", true);
    }
    return res;
  }

  function getTargetSize() {
    var res = {width:parseInt(getCssParam(targetdiv, "width")), height:parseInt(getCssParam(targetdiv, "height"))};
    if (isNaN(res.width)) res.width = targetdiv.offsetWidth;
    if (isNaN(res.height)) res.height = targetdiv.offsetHeight;
    return res;
  }

  function getCssParam(elem, styleelem, asNumber) {
    if (elem.style[styleelem] && elem.style[styleelem].length > 0)
      return elem.style[styleelem];
    else {
      var classes = elem.className.split(" ");
      var cssRules = (document.all ? "rules" : "cssRules");
      var res = "";
      for (var i=0; i < document.styleSheets.length && res.length == 0; i++){
        for (var j=0; j < document.styleSheets[i][cssRules].length && res.length == 0; j++) {
          var sel = document.styleSheets[i][cssRules][j].selectorText;
          if (sel == "#" + elem.id)
            res = document.styleSheets[i][cssRules][j].style[styleelem];
          else {
            for (var k=0; k < classes.length; k++)
              if (sel == "." + classes[k]) res = document.styleSheets[i][cssRules][j].style[styleelem];
          }
        }
      }
      if (asNumber) {
        var n = parseInt(res);
        return (isNaN(n) ? 0 : n);
      }
      else
        return res;
    }
  }

  function getEventPos(event) {
    if (Browser.isIE || Browser.isOpera) return {x:window.event.clientX + document.documentElement.scrollLeft + document.body.scrollLeft, y:window.event.clientY + document.documentElement.scrollTop + document.body.scrollTop};
    else return {x:event.clientX + window.scrollX, y:event.clientY + window.scrollY};
  }


  this.drag = function(event) {
    if (dragging) {
      var currMouse = getEventPos(event);
      targetdiv.style.left = (currMouse.x - refPoint.x) + "px";
      targetdiv.style.top = (currMouse.y - refPoint.y) + "px";
    }
  }

  this.endDrag = function(event) {
    if (document.detachEvent) {
      document.detachEvent('onmousemove', pop_divs[arrindex].drag);
      document.detachEvent('onmouseup', pop_divs[arrindex].endDrag);
    }
    else {
      document.removeEventListener("mousemove", pop_divs[arrindex].drag, false);
      document.removeEventListener("mouseup", pop_divs[arrindex].endDrag, false);
    }
    var currMouse = getEventPos(event);
    targetdiv.style.left = (currMouse.x - refPoint.x) + "px";
    targetdiv.style.top = (currMouse.y - refPoint.y) + "px";
    dragging = false;
  }



  this.setPosition = function(left, top) {
    targetdiv.style.left = parseInt(left) + "px";
    targetdiv.style.top = parseInt(top) + "px";
  }

  this.setMargins = function(left, top) {
    if (left && left.length > 0) targetdiv.style.marginLeft = left;
    if (top && top.length > 0) targetdiv.style.marginTop = top;
  }

  this.setContent = function(html) {
    targetdiv.innerHTML = html;
  }


  this.slideTo = function(left, top, cb) {
    this.currPos = getTargetPos();
    if (cb) this.param["doneSlide"] = cb;
    this.endPos = {left:left, top:top};
    this.slideStep = {
      x: (left - this.currPos.left) / this.param.steps,
      y: this.slideStep.y = (top - this.currPos.top) / this.param.steps
    };
    if (this.param["beforeSlide"]) this.param["beforeSlide"](this);
    this.doSlide();
  }

  this.slideRelative = function(x, y, cb) {
    console.log("X=" + x + "  y="+y);
    this.currPos = getTargetPos();
    if (cb) this.param["doneSlide"] = cb;
    this.endPos = {left:this.currPos.left + x, top:this.currPos.top + y};
    this.slideStep = {
      x: x / this.param.steps,
      y: y / this.param.steps
    };
    if (this.param["beforeSlide"]) this.param["beforeSlide"](this);
    this.doSlide();
  }

  this.doSlide = function() {
    this.currPos.left += this.slideStep.x;
    this.currPos.top += this.slideStep.y;
    if ((this.slideStep.x < 0 && this.currPos.left < this.endPos.left) || (this.slideStep.x >= 0 && this.currPos.left > this.endPos.left)) 
      this.currPos.left = this.endPos.left;
    if ((this.slideStep.y < 0 && this.currPos.top < this.endPos.top) || (this.slideStep.y >= 0 && this.currPos.top > this.endPos.top)) 
      this.currPos.top = this.endPos.top;
    targetdiv.style.left = this.currPos.left + "px";
    targetdiv.style.top = this.currPos.top + "px";
    var done = (this.currPos.left == this.endPos.left && this.currPos.top == this.endPos.top);
    if (done) {
      console.log('done');
      if (this.param["doneSlide"]) this.param["doneSlide"](this);
    }
    else {
      slideTimer = setTimeout("pop_divs[" + arrindex + "].doSlide()", this.param["speed"]);
    }
  }

  this.getGrowParams = function(type) {
    var w = this.param["maxwidth"]-this.param["minwidth"];
    var h = this.param["maxheight"]-this.param["minheight"];
    this.moveStep = {x:0, y:0};
    this.endPos = {left:this.oriPos.left, top:this.oriPos.top};
    if (this.param.growdirection == "horizontal" || this.param.growdirection == "both") {
      if (this.param.groworigin == "topright" || this.param.groworigin == "bottomright") {
        this.moveStep.x = w / this.param["steps"];
        if (type == "hide") this.endPos.left += w;
      }
      else if (this.param.groworigin == "center") {
        this.moveStep.x = w / 2 / this.param["steps"];
        if (type == "hide") this.endPos.left += w/2;
      }
    }
    if (this.param.growdirection == "vertical" || this.param.growdirection == "both") {
      if (this.param.groworigin == "bottomleft" || this.param.groworigin == "bottomright") {
        this.moveStep.y = h / this.param["steps"];
        if (type == "hide") this.endPos.top += h;
      }
      else if (this.param.groworigin == "center") {
        this.moveStep.y = h / 2 / this.param["steps"];
        if (type == "hide") this.endPos.top += h/2;
      }
    }
  }
  
  this.show = function(fade, dir, ori) {
    if (this.param) {
      if (fade != null) this.param.fade = fade;
      if (dir != null) this.param.growdirection = dir;
      if (ori != null) this.param.groworigin = ori;

      if (this.param.groworigin && this.param.groworigin.length > 0 && this.param.groworigin != "topleft") this.getGrowParams('show');

      clearTimeout(decTimer);
      if (this.param["beforeShow"]) this.param["beforeShow"](this);
      
      this.currSize = {width:this.param.minwidth, height:this.param.minheight};
      this.currPos = {left:this.oriPos.left, top:this.oriPos.top};

      if (this.param.fade) this.opacity = this.param["minopacity"];
      if (this.param.growdirection == "horizontal" || this.param.growdirection == "both") {
        targetdiv.style.width = parseInt(this.currSize.width) + "px";
        if (this.param.groworigin == "topright" || this.param.groworigin == "bottomright") {
          this.currPos.left += this.param["maxwidth"]-this.param["minwidth"];
          targetdiv.style.left = parseInt(this.currPos.left) + "px";
        }
        else if (this.param.groworigin == "center") {
          this.currPos.left += (this.param["maxwidth"]-this.param["minwidth"])/2;
          targetdiv.style.left = parseInt(this.currPos.left) + "px";
        }
      }
      if (this.param.growdirection == "vertical" || this.param.growdirection == "both") {
        targetdiv.style.height = parseInt(this.currSize.height) + "px";
        if (this.param.groworigin == "bottomleft" || this.param.groworigin == "bottomright") {
          this.currPos.top += this.param["maxheight"] - this.param["minheight"];
          targetdiv.style.top = parseInt(this.currPos.top) + "px";
        }
        else if (this.param.groworigin == "center") {
          this.currPos.top += (this.param["maxheight"] - this.param["minheight"]) / 2;
          targetdiv.style.top = parseInt(this.currPos.top) + "px";
        }
      }

      if (this.param["visiblemode"] == "visibility") targetdiv.style.visibility = "visible";
      else targetdiv.style.display = "block";

      this.incShow();
    }
  }

  this.hide = function(fade, dir, ori) {
    if (this.param) {
      if (fade != null) this.param.fade = fade;
      if (dir != null) this.param.growdirection = dir;
      if (ori != null) this.param.groworigin = ori;

      if (this.param.groworigin && this.param.groworigin.length > 0 && this.param.groworigin != "topleft") this.getGrowParams('hide');

      clearTimeout(incTimer);

      this.currSize = {width:this.param.maxwidth, height:this.param.maxheight};
      this.currPos = getTargetAbsPos();

      if (this.param.fade) this.opacity = this.param["maxopacity"];
      if (this.param.growdirection == "horizontal" || this.param.growdirection == "both") {
        targetdiv.style.width = parseInt(this.currSize.width) + "px";
        targetdiv.style.left = parseInt(this.currPos.left) + "px";
      }
      if (this.param.growdirection == "vertical" || this.param.growdirection == "both") {
        targetdiv.style.height = parseInt(this.currSize.height) + "px";
        targetdiv.style.top = parseInt(this.currPos.top) + "px";
      }

      this.decShow();
    }
  }


  this.incShow = function() {
    var done = true;

    if (this.param.fade) {
      if (this.opacity < this.param["maxopacity"]) {
        done = false;
        this.opacity += this.fadeStep;
        if (this.opacity > this.param["maxopacity"]) this.opacity = this.param["maxopacity"];
        this.setOpacity();
      }
    }

    if (this.param.growdirection == "horizontal" || this.param.growdirection == "both") {
      if (this.currSize.width < this.param["maxwidth"]) {
        done = false;
        this.currSize.width += this.growStep.width;
        if (this.currSize.width > this.param["maxwidth"]) this.currSize.width = this.param["maxwidth"];
        targetdiv.style.width = parseInt(this.currSize.width) + "px";
      }
      if ((this.param.groworigin == "topright" || this.param.groworigin == "bottomright" || this.param.groworigin == "center") && this.currPos.left > this.endPos.left) {
        done = false;
        this.currPos.left -= this.moveStep.x;
        if (this.currPos.left < this.endPos.left) 
          this.currPos.left = this.endPos.left;
        targetdiv.style.left = parseInt(this.currPos.left) + "px";
      }
    }

    if (this.param.growdirection == "vertical" || this.param.growdirection == "both") {
      if (this.currSize.height < this.param["maxheight"]) {
        done = false;
        this.currSize.height += this.growStep.height;
        if (this.currSize.height > this.param["maxheight"]) this.currSize.height = this.param["maxheight"];
        targetdiv.style.height = parseInt(this.currSize.height) + "px";
      }
      if ((this.param.groworigin == "bottomleft" || this.param.groworigin == "bottomright" || this.param.groworigin == "center") && this.currPos.top > this.endPos.top) {
        done = false;
        this.currPos.top -= this.moveStep.y;
        if (this.currPos.top < this.endPos.top) 
          this.currPos.top = this.endPos.top;
        targetdiv.style.top = parseInt(this.currPos.top) + "px";
      }
    }

    if (done) {
      if (this.param["onOpened"]) this.param["onOpened"]();
      if (this.param["visiblemode"] == "visibility") targetdiv.style.visibility = "visible";
      else targetdiv.style.display = "block";
      this.param["visible"] = true;
    }
    else
      incTimer = setTimeout("pop_divs[" + arrindex + "].incShow()", this.param["speed"]);
  }


  this.decShow = function() {
    var done = true;

    if (this.param.fade) {
      if (this.opacity > this.param["minopacity"]) {
        done = false;
        this.opacity -= this.fadeStep;
        if (this.opacity <= this.param["minopacity"]) {
          this.opacity = this.param["minopacity"];
          if (this.param["minopacity"] == 0) {
            if (this.param["visiblemode"] == "visibility") targetdiv.style.visibility = "hidden";
            else targetdiv.style.display = "none";
          }
        }
        this.setOpacity();
      }
    }

    if (this.param.growdirection == "horizontal" || this.param.growdirection == "both") {
      if (currSize.width > this.param["minwidth"]) {
        done = false;
        this.currSize.width -= this.growStep.width;
        if (this.currSize.width < 0) {
          this.currSize.width = 0;
          if (this.param["visiblemode"] == "visibility") targetdiv.style.visibility = "hidden";
          else targetdiv.style.display = "none";
        }
        targetdiv.style.width = parseInt(this.currSize.width) + "px";
      }
      if ((this.param.groworigin == "topright" || this.param.groworigin == "bottomright" || this.param.groworigin == "center") && this.currPos.left < this.endPos.left) {
        done = false;
        this.currPos.left += this.moveStep.x;
        if (this.currPos.left > this.endPos.left) 
          this.currPos.left = this.endPos.left;
        targetdiv.style.left = parseInt(this.currPos.left) + "px";
      }
    }

    if (this.param.growdirection == "vertical" || this.param.growdirection == "both") {
      if (currSize.height > this.param["minheight"]) {
        done = false;
        currSize.height -= this.growStep.height;
        if (currSize.height <= 0) {
          currSize.height = 0;
          if (this.param["visiblemode"] == "visibility") targetdiv.style.visibility = "hidden";
          else targetdiv.style.display = "none";
        }
        targetdiv.style.height = currSize.height + "px";
      }
      if ((this.param.groworigin == "bottomleft" || this.param.groworigin == "bottomright" || this.param.groworigin == "center") && this.currPos.top < this.endPos.top) {
        done = false;
        this.currPos.top += this.moveStep.y;
        if (this.currPos.top > this.endPos.top) 
          this.currPos.top = this.endPos.top;
        targetdiv.style.top = parseInt(this.currPos.top) + "px";
      }
    }

    if (done) {
      if (this.param["visiblemode"] == "visibility") targetdiv.style.visibility = "hidden";
      else targetdiv.style.display = "none";
      if (this.param["onClosed"]) this.param["onClosed"]();
      this.param["visible"] = false;
    }
    else
      decTimer = setTimeout("pop_divs[" + arrindex + "].decShow()", this.param["speed"]);
  }

  this.setOpacity = function() {
    var opac = parseInt(this.opacity);
    targetdiv.style.filter = "alpha(opacity:"+opac+")";
    targetdiv.style.KHTMLOpacity = opac/100;
    targetdiv.style.MozOpacity = opac/100;
    targetdiv.style.opacity = opac/100;
  }
  
  this.wobble = function(dir) {
    var steps;
    if (!dir) {
      steps = this.param.steps;
      this.param.steps = 2;
      this.slideRelative(5, 0, function(pop){ pop.wobble(1); });
    }
    else if (dir == 1) this.slideRelative(-10, 0, function(pop){ pop.wobble(2); });
    else if (dir == 2) this.slideRelative(5, 5, function(pop){ pop.wobble(3); });
    else if (dir == 3) this.slideRelative(0, -10, function(pop){ pop.wobble(4); });
    else if (dir == 4) this.slideRelative(0, 5, function(pop){ pop.wobble(5);});
    else this.param.steps = steps;
  }

  arrindex = pop_divs.length;
  pop_divs.push(this);

}

function popdiv_init() {
  var divs = document.getElementsByTagName("DIV");
  for (var i=0; i < divs.length; i++)
    if (divs[i].className.indexOf("popdiv") >= 0)
      new Popdiv(divs[i]);

  for (var i=0; i < pop_divs.length; i++)
    if (!pop_divs[i].manualsetup) pop_divs[i].setup();
};

if (window.attachEvent)
  window.attachEvent("onload", popdiv_init);
else
  window.addEventListener("load", popdiv_init, false);

