function getAbsolutePos(el) {
  var r = { x: el.offsetLeft, y: el.offsetTop };
  if (el.offsetParent) {
    var tmp = getAbsolutePos(el.offsetParent);
    r.x += tmp.x;
    r.y += tmp.y;
  }
  return r;
}

function get_ww() {
  var frameWidth = 800;
  if (self.innerWidth) {
    frameWidth = self.innerWidth;
  } else if (document.documentElement && document.documentElement.clientWidth) {
    frameWidth = document.documentElement.clientWidth;
  } else if (document.body) frameWidth = document.body.clientWidth;
  return(frameWidth);
}

function get_wh() {
  var frameHeight = 640;
  if (self.innerHeight) {
    frameHeight = self.innerHeight;
  } else if (document.documentElement && document.documentElement.clientHeight) {
    frameHeight = document.documentElement.clientHeight;
  } else if (document.body) frameHeight = document.body.clientHeight;
  return(frameHeight);
}

function getScrollXY() {
  var scrOfX = 0, scrOfY = 0;
  if (typeof(window.pageYOffset) == 'number') {
    scrOfY = window.pageYOffset;
    scrOfX = window.pageXOffset;
  } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
    scrOfY = document.body.scrollTop;
    scrOfX = document.body.scrollLeft;
  } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
    scrOfY = document.documentElement.scrollTop;
    scrOfX = document.documentElement.scrollLeft;
  }
  return([scrOfX, scrOfY]);
}

function ImageExpander(oThumb, sImgSrc, bigWidth, bigHeight) {
  this.oThumb = oThumb;
  this.oThumb.expander = this;
  this.oThumb.onclick = function() {
    this.expander.expand();
  }

  this.smallWidth = oThumb.offsetWidth;
  this.smallHeight = oThumb.offsetHeight;

  this.bigWidth = bigWidth;
  this.bigHeight = bigHeight;

  this.bExpand = true;
  this.bTicks = false;

  if (!window.aImageExpanders) window.aImageExpanders = new Array();
  window.aImageExpanders.push(this);

  this.oImg = new Image();
  this.oImg.expander = this;
  this.oImg.onload = function() {
    this.expander.onload();
  }
  this.oImg.src = sImgSrc;
}
 
ImageExpander.prototype.onload = function() {
  this.oDiv = document.createElement('div');
  document.body.appendChild(this.oDiv);
  this.oDiv.appendChild(this.oImg);
  this.oDiv.style.position = 'absolute';
  this.oDiv.expander = this;
  this.oDiv.onclick = function() {
    this.expander.toggle();
  }
  this.oImg.title = 'Нажмите для закрытия картинки';
  this.oImg.style.cursor = 'Pointer';
  this.oImg.style.cursor = 'Hand';

  if (this.bExpand) {
    this.expand();
  } else {
    this.oDiv.style.visibility = 'hidden';
    this.oImg.style.visibility = 'hidden';
  }
}

ImageExpander.prototype.toggle = function() {
  this.bExpand = !this.bExpand;
  if (this.bExpand) {
    for (var i in window.aImageExpanders) if (window.aImageExpanders[i] !== this) window.aImageExpanders[i].reduce();
  }
}

ImageExpander.prototype.expand = function() {
  this.bExpand = true;

  for (var i in window.aImageExpanders) if (window.aImageExpanders[i] !== this) window.aImageExpanders[i].reduce();

  if (!this.oDiv) return;

  this.oThumb.style.visibility = 'hidden';

  var r = getAbsolutePos(this.oThumb);
  this.x = r.x;
  this.y = r.y;
  this.w = this.oThumb.clientWidth;
  this.h = this.oThumb.clientHeight;

  this.oDiv.style.left = this.x + 'px';
  this.oDiv.style.top = this.y + 'px';
  this.oImg.style.width = this.w + 'px';
  this.oImg.style.height = this.h + 'px';
  this.oDiv.style.visibility = 'visible';
  this.oImg.style.visibility = 'visible';

  if (!this.bTicks) {
    this.bTicks = true;
    var pThis = this;
    window.setTimeout(function() {pThis.tick()}, 25);
  }
}

ImageExpander.prototype.reduce = function() {
  this.bExpand = false;
}

ImageExpander.prototype.tick = function() {
  var cw = get_ww();
  var ch = get_wh();
  var scroll = getScrollXY();
  var cx = scroll[0] + cw / 2;
  var cy = scroll[1] + ch / 2;

  var tw, th, tx, ty;
  if (this.bExpand) {
    tw = this.bigWidth;
    th = this.bigHeight;
    if (tw > cw) {
      th *= cw / tw;
      tw = cw;
    }
    if (th > ch) {
      tw *= ch / th;
      th = ch;
    }
    tx = cx - tw / 2;
    ty = cy - th / 2; 
  } else {
    tw = this.smallWidth;
    th = this.smallHeight;
    var r = getAbsolutePos(this.oThumb);
    tx = r.x;
    ty = r.y;
  }

  var nHit = 0;
  var fMove = function(n, tn) {
    var dn = tn - n;
    if (Math.abs(dn) < 3) {
      nHit++;
      return tn;
    } else {
      return n + dn / 3;
    }
  }
  this.x = fMove(this.x, tx);
  this.y = fMove(this.y, ty);
  this.w = fMove(this.w, tw);
  this.h = fMove(this.h, th);

  this.oDiv.style.left = this.x + 'px';
  this.oDiv.style.top = this.y + 'px';
  this.oImg.style.width = this.w + 'px';
  this.oImg.style.height = this.h + 'px';

  if ((!this.bExpand)&&(nHit == 4)) {
    this.oImg.style.visibility = 'hidden';
    this.oDiv.style.visibility = 'hidden';
    this.oThumb.style.visibility = 'visible';
    this.bTicks = false;
  }

  if (this.bTicks) {
    var pThis = this;
    window.setTimeout(function() {pThis.tick()}, 25);
  }
}