/*<![CDATA[*/
// Element Animator (24-January-2008) DRAFT
// by Vic Phillips http://www.vicsjavascripts.org.uk

// To progressively change the Left, Top, Width, Height, Color, Opacity, border style
// (or other properties) of an element over a specified period of time.

// **** Application Notes

// **** The HTML Code
//
// when moving an element the inline or class rule style position of the element should be assigned as
// 'position:relative;' or 'position:absolute;'
// If not assigned the style position of the element will be assigned as 'position:relative;' by the script.
//
// The element would normally be assigned a unique ID name.
//

// **** Executing the Effect(Script)
//
// The effect is executed by an event call to function 'zxcAnimator('left','tst1',20,260,'sin',2000);'
// where:
// parameter 0 = 'left', 'top', 'width', 'height', 'color', 'background-Color', 'opacity' etc.             (string)
//               Note: the first character after the hyphen must be upper case, all others lower case.
//                     With the exception of opacity and color the property value units is in 'px'.
// parameter 1 = the unique ID name or element object.                                                     (string or element object)
// parameter 2 = the start position of the effect.                                                         (digits, for opacity minimum 0, maximum 100)
// parameter 3 = the finish position of the effect.                                                        (digits, for opacity minimum 0, maximum 100)
// parameter 4 = (optional) there are two types of progressive change 'sin' and 'cos' plus a liner change. ('sin', 'cos' or liner, defaults to liner)
//                'sin' progression starts fast and ends slow.
//                'cos' progression starts slow and ends fast.
// parameter 5 = (optional) period of time between the start and finish of the effect in milliseconds.     (digits or defaults to 2000 milliSeconds)
// parameter 6 =  The script may be used to animate border color and size for 'border'                     (string)
//                parameter 0 = border, border-Top, border-Bottom, border-Left or border-Right. (string)
//                parameter 6 is required the default border value.
//                example: 'solid #ffffff 1px'. Note type, color in HEX and size separated by spaces.
//
//  Note 1:  To 'toggle' the effect include '#' in parameter 0.
//           The first call will set the toggle parameters.
//           Subsequent calls with '#' in parameter 0 and the same start and finish parameters will 'toggle' the effect.
//  Note 2:  The function may be re-executed with a different set of parameters (start/finish time or period)
//           whenever required, say from an onclick/mouseover/out event.
//           The period parameter will be retained unless re-specified.

// **** Advanced Applications
//
//  It may be required to access the current value of the effect.
//  The element effect is accessible from the element property
//  element effect = elementobject[mode.replace(/[-#]/g,'')+'oop'];
//  where mode is parameter 0 of the initial call.
//  An array storing the current, start and finish values of the element effect may be accessed
//  from the element effect.data as fields 0, 1 and 2 respectively
//  For color each field is an array storing the R, G, B values.
//

// **** 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 4.4K) is best as an External JavaScript.
//
// Tested with IE7 and Mozilla FireFox on a PC.
//



// **** Functional Code - NO NEED to Change

var zxcOOPCnt=0;

function zxcAnimator(zxcmde,zxcobj,zxcsrt,zxcfin,zxccurve,zxctime,zxcborder){
 if (typeof(zxcobj)=='string'){ zxcobj=document.getElementById(zxcobj); }
 if (!zxcobj||(!zxcsrt&&!zxcfin)||zxcsrt==zxcfin) return;
 var zxcoop=zxcobj[zxcmde.replace(/[-#]/g,'')+'oop'];
 var zxcunits=zxcsrt.toString().replace(/\d|-/g,'')||'px';
 zxcsrt=zxcNuRGB(zxcsrt); zxcfin=zxcNuRGB(zxcfin);
 if (zxcoop){
  if (zxcmde.match('#')&&zxcsrt.compare(zxcoop.srtfin[0])&&zxcfin.compare(zxcoop.srtfin[1])) zxcoop.update([zxcoop.data[0],(zxcoop.srtfin[0].compare(zxcoop.data[2]))?zxcfin:zxcsrt],zxccurve,zxctime,zxcborder,zxcunits);
  else zxcoop.update([zxcsrt,zxcfin],zxccurve,zxctime,zxcborder);
 }
 else zxcobj[zxcmde.replace(/[-#]/g,'')+'oop']=new zxcAnimatorOOP(zxcmde.replace(/[-#]/g,''),zxcobj,zxcsrt,zxcfin,zxccurve,zxctime,zxcborder,zxcunits);
}

function zxcAnimatorOOP(zxcmde,zxcobj,zxcsrt,zxcfin,zxccurve,zxctime,zxcborder,zxcunits){
 if (zxcStyleValue(zxcobj,'position')=='static'&&(zxcmde=='left'||zxcmde=='top')) zxcobj.style.position='relative';
 this.srtfin=[[],[]];
 for (var zxc0=0;zxc0<zxcsrt.length;zxc0++){ this.srtfin[0].push(zxcsrt[zxc0]); this.srtfin[1].push(zxcfin[zxc0]); }
 this.to=null;
 this.obj=zxcobj;
 this.mde=zxcmde;
 this.update([zxcsrt,zxcfin],zxccurve,zxctime,zxcborder,zxcunits);
}

zxcAnimatorOOP.prototype.update=function(zxcsrtfin,zxccurve,zxctime,zxcborder,zxcunits){
 clearTimeout(this.to);
 zxccurve=zxccurve||this.curve||'';
 this.time=zxctime||this.time||2000;
 this.units=zxcunits;
 if (zxcsrtfin[0]==zxcsrtfin[1]) return;
 for (var zxc0=0;zxc0<zxcsrtfin.length;zxc0++){
  var zxcobj=document.getElementById(zxcsrtfin[zxc0]);
  if (zxcobj){ zxcsrtfin[zxc0]=zxcStyleValue(zxcobj,zxcmde); if (!this.mde.match('olor')) zxcsrtfin[zxc0]=parseInt(zxcsrtfin[zxc0]); }
  if (zxcsrtfin[zxc0]==[0]) zxcsrtfin[zxc0]=[0.00001];
 }
 if (this.mde=='opacity'&&(zxcsrtfin[0]<0||zxcsrtfin[0]>100||zxcsrtfin[0]<0||zxcsrtfin[0]>100)) return;
 if (zxcborder) this.brd=zxcborder.split(' ');
 this.curve=zxccurve.charAt(0).toLowerCase();
 var zxcmatch=zxcsrtfin[0].toString();
 this.data=[[],zxcsrtfin[0],zxcsrtfin[1]];
 for (var zxc0 in this.data[1]) this.data[0][zxc0]=(this.data[1][zxc0]);
 this.srttime=new Date().getTime();

 this.inc=Math.PI/(2*this.time);
 this.cng();
}

zxcAnimatorOOP.prototype.cng=function(){
 var zxcms=new Date().getTime()-this.srttime;
 for (var zxc0 in this.data[2]){ this.data[0][zxc0]=(this.curve=='s')?Math.floor((this.data[2][zxc0]-this.data[1][zxc0])*Math.sin(this.inc*zxcms)+this.data[1][zxc0]):(this.curve=='c')?(this.data[2][0])-Math.floor((this.data[2][zxc0]-this.data[1][zxc0])*Math.cos(this.inc*zxcms)):(this.data[2][zxc0]-this.data[1][zxc0])/this.time*zxcms+this.data[1][zxc0]; }
 this.cngstyle();
 if (zxcms<this.time) this.to=setTimeout(function(zxcoop){return function(){zxcoop.cng();}}(this), 10);
 else { this.data[0]=this.data[2]; this.cngstyle();
 }
}

zxcAnimatorOOP.prototype.cngstyle=function(zxcpar){
 var zxcval=this.data[0];
 if (this.mde.match('border')){
  if (zxcval.length==1) this.obj.style[this.mde]=this.brd[0]+' '+this.brd[1]+' '+zxcval[0]+this.units;
  if (zxcval.length==3) this.obj.style[this.mde]=this.brd[0]+' rgb('+zxcval[0]+','+zxcval[1]+','+zxcval[2]+') '+this.brd[2];
 }
 else if (this.mde.match('olor')) this.obj.style[this.mde]='rgb('+zxcval[0]+','+zxcval[1]+','+zxcval[2]+')';
 else if (this.mde!='opacity') this.obj.style[this.mde]=zxcval[0]+this.units;
 else this.opacity(zxcval[0]);
}

zxcAnimatorOOP.prototype.opacity=function(zxcopc){
 if (zxcopc<0||zxcopc>100){ return; }
 this.obj.style.filter='alpha(opacity='+zxcopc+')';
 this.obj.style.opacity=this.obj.style.MozOpacity=this.obj.style.KhtmlOpacity=zxcopc/100-.001;
}

function zxcStyleValue(zxcel,zxcp){
 if (zxcel.currentStyle) return zxcel.currentStyle[zxcp.replace('-','')];
 return document.defaultView.getComputedStyle(zxcel,null).getPropertyValue(zxcp.toLowerCase());
}

function zxcNuRGB(zxccol){
 if (typeof(zxccol)=='object') return zxccol;
 if (!zxccol.toString().match('#')) return [parseInt(zxccol)];
 zxccol=parseInt(zxccol.substring(1,3),16)+','+parseInt(zxccol.substring(3,5),16)+','+parseInt(zxccol.substring(5,7),16);
 zxccol=zxccol.replace(/[rgb()\s]/g,'').split(',');
 return [parseInt(zxccol[0]),parseInt(zxccol[1]),parseInt(zxccol[2])];
}

Array.prototype.compare=function(zxcary){
 for (var zxc0=0;zxc0<this.length;zxc0++){ if (this[zxc0]!=zxcary[zxc0]) return false; }
 return true;
}

/*]]>*/

