// Image Expand & Display (30-June-2006)
// by Vic Phillips http://www.vicsjavascripts.org.uk

// Click a ThumbNail Image and move a expanding copy to a specified display element.
// The expanded image is centered in the display element.
// The move is progressive and the move time may be specified.
// Move another expanding image to the display element
// and the previous display image will be removed.

// Elements other than images may be copied, moved and displayed.
// There may be as many applications as required on a page.

// ***** Application Notes
//
// **** The Anchor Element
//
// The Anchor Element must be defined in the HTML Code
// and must be assigned a unique ID name
// and have a style position of 'position:relative;' or 'position:absolute;'
// e.g.
//  <div id="Anchor" style="position:absolute;left:500px;top:50px;width:200px;height:0px;border:solid black 1px;" onmousedown="zxcDragDrop(event);" ></div>
//



// **** The Image to Copy, Move, Expand and Display
//
// The thumbnail images are defined in the HTML Code.
// If it is to be moved by an event call from an element other than itself,
// it must be assigned a unique ID name.
// An event call to function  'zxcImgExp(this,'Anchor1',600,'http://www.vicsjavascripts.org.uk/StdImages/Three.gif',400,300);' instigates the move
// where:
// parameter 0 = the object or the unique ID name of the object.         (object or string)
// parameter 1 = the unique ID name of the Anchor element.               (string)
// parameter 2 = (optional) the time to move in milliSeconds.            (digits or null for 2000 milliSeconds)
// parameter 3 = (optional) image src to replace the thumbnail copy src. (string or null for the thumbnail src)
// parameter 4 = the expanded image width.                               (digits)
// parameter 5 = the expanded image height.                              (digits)
//

// **** Example HTML Code
//
// <img  src="http://www.vicsjavascripts.org.uk/StdImages/One.gif" width="50" height="50" onclick="zxcImgExp(this,'Anchor1',600,'http://www.vicsjavascripts.org.uk/StdImages/Three.gif',400,300);zxcImgExp('Mess1','Anchor1A',600,null,200,20);" >
// <div id="Mess1" style="position:relative;overflow:hidden;visibility:hidden;left:0px;top:0px;width:10px;height:10px;border:solid black 1px;text-align:center;" >
// The Message for Image 1
// </div>
// <div id="Anchor1" style="position:absolute;left:300px;top:50px;width:500px;height:500px;border:solid black 1px;" ></div>
// <div id="Anchor1A" style="position:absolute;left:300px;top:550px;width:500px;height:50px;border:solid black 0px;" ></div>


// **** General
//
// All variable, function etc. names are prefixed with 'zxc' to minimise conflicts with other JavaScripts.
// These characters may be changed to characters of choice using global find and replace.
//
// The Functional Code (about 3.6K) is best as an External JavaScript.
//
// Tested with IE6 and Mozilla FireFox.




// **** Functional Code - NO NEED to Change


function zxcImgExp(zxcobj,zxcanch,zxcspd,zxcimg,zxcw,zxch){
 if (typeof(zxcobj)=='string'){ zxcobj=document.getElementById(zxcobj); }
 if (typeof(zxcanch)=='string'){ zxcanch=document.getElementById(zxcanch); }
 if (zxcobj&&zxcanch){
  if (zxcobj.parentNode==zxcanch){ return; }
  window['zxcIEOOP'+zxcOOPCnt]=new zxcImgExpOOP(zxcobj,zxcanch,zxcspd,zxcimg,zxcw,zxch);
 }
}

var zxcOOPCnt=0;

function zxcImgExpOOP(zxcobj,zxcanch,zxcspd,zxcimg,zxcw,zxch){
 zxcw=zxcw||zxcobj.offsetWidth;
 zxch=zxch||zxcobj.offsetHeight;
 this.anch=zxcanch;
 this.obj=zxcobj.cloneNode(true);
 this.style({position:'absolute',zIndex:'1',visibility:'visible',left:(zxcPos(zxcobj)[0]-zxcPos(zxcanch)[0])+'px',top:(zxcPos(zxcobj)[1]-zxcPos(zxcanch)[1])+'px',width:(zxcobj.style.width||zxcobj.offsetWidth+'px'),height:(zxcobj.style.height||zxcobj.offsetHeight+'px')});
 zxcanch.appendChild(this.obj);
 if (this.obj.tagName=='IMG'&&zxcimg){ this.obj.src=zxcimg; }
 this.data=[zxcw,(zxcanch.offsetWidth-zxcw)/2,(zxcanch.offsetHeight-zxch)/2,zxcw/zxch];
 this.spd=zxcspd||2000;
 this.to=null;
 this.ref='zxcieoop'+zxcOOPCnt++;
 window[this.ref]=this;
 if (this.anch.last){ this.anch.removeChild(this.anch.last); this.anch.last=null; }
 this.anch.last=this.obj;
 this.getpos();
}

zxcImgExpOOP.prototype.style=function(zxcstyle){
 for (key in zxcstyle){ this.obj.style[key]=zxcstyle[key]; }
}

zxcImgExpOOP.prototype.getpos=function(){
 this.run=false;
 this.inc=Math.PI/(2*this.spd);
 this.nowx=parseInt(this.obj.style.left);
 this.ckx=this.data[1];
 if (this.nowx!=this.ckx){
  if (this.ckx!=this.newx){
   this.newx=this.ckx;
   this.cngx=this.newx-this.nowx;
   this.lsttimex=new Date().getTime();
   this.lstposx=this.nowx;
  }
  this.run=true; this.movex();
 }
 this.nowy=parseInt(this.obj.style.top);
 this.cky=this.data[2];
 if (this.nowy!=this.cky){
  if (this.cky!=this.newy){
   this.newy=this.cky;
   this.cngy=this.newy-this.nowy;
   this.lsttimey=new Date().getTime();
   this.lstposy=this.nowy;
  }
  this.run=true; this.movey();
 }
 this.noww=parseInt(this.obj.style.width);
 this.ckw=this.data[0];
 if (this.noww!=this.ckw){
  if (this.ckw!=this.neww){
   this.neww=this.ckw;
   this.cngw=this.neww-this.noww;
   this.lsttimew=new Date().getTime();
   this.lstposw=this.noww;
  }
  this.run=true; this.expand();
 }
 if (this.run){ this.setTimeOut('getpos();',10); }
}

zxcImgExpOOP.prototype.movex=function(){
 this.posx=Math.round(this.cngx*Math.sin(this.inc*(new Date().getTime()-this.lsttimex))+this.lstposx);
 if (( this.cngx>0&&this.posx>this.nowx)||(this.cngx<0&&this.posx<this.nowx)){
  this.style({left:(this.posx)+'px'});
 }
 else { clearTimeout(this.to); }
}

zxcImgExpOOP.prototype.movey=function(){
 this.posy=Math.round(this.cngy*Math.sin(this.inc*(new Date().getTime()-this.lsttimey))+this.lstposy);
 if ((this.cngy>0&&this.posy>this.nowy)||(this.cngy<0&&this.posy<this.nowy)){
  this.style({top:(this.posy)+'px'});
 }
}

zxcImgExpOOP.prototype.expand=function(){
 this.w=Math.round(this.cngw*Math.sin(this.inc*(new Date().getTime()-this.lsttimew))+this.lstposw);
 if ((this.cngw>0&&this.w>this.noww)||(this.cngw<0&&this.w<this.noww)){
  this.style({width:(this.w)+'px',height:(this.w/this.data[3])+'px'});
 }
}

zxcImgExpOOP.prototype.setTimeOut=function(zxcf,zxcd){
 this.to=setTimeout('window.'+this.ref+'.'+zxcf,zxcd);
}

function zxcPos(zxcobj){
 zxclft=zxcobj.offsetLeft;
 zxctop=zxcobj.offsetTop;
 while(zxcobj.offsetParent!=null){
  zxcpar=zxcobj.offsetParent;
  zxclft+=zxcpar.offsetLeft;
  zxctop+=zxcpar.offsetTop;
  zxcobj=zxcpar;
 }
 return [zxclft,zxctop];
}
