var active_image=
{
 data:[], x:0, y:0, xDisp:0, yDisp:0, m$:typeof window.pageXOffset=='undefined',
 portWidth:0, portHeight:0, isViable:typeof document.getElementsByTagName!='undefined', 
 dataCode:0, firstCall:true, currentDisplayedIndex:-1, imgPreload:true, 
 overTimer:null, outTimer:null, logged:1,

 setup:function()
 {
  var paramGroup=3;

  if(this.isViable)
  {
   if(this.firstCall)
   {
    this.firstCall=false;

    this.addToHandler(document, 'onmousemove', function(){active_image.getMouseAndScrollData(arguments[0]);});

    if(!this.logged++)
     this.addToHandler(window,'onload',function(){setTimeout(active_image.cont,3000)});
   }

   if( document.documentElement )
    this.dataCode=3;
   else
    if(document.body && typeof document.body.scrollTop!='undefined')
     this.dataCode=2;
    else
     if( typeof window.pageXOffset!='undefined' )
      this.dataCode=1;

   for(var i=this.data.length, idParts, j=0; j<arguments.length; i++, j+=paramGroup)
   {
    this.data[i]={};

    idParts=arguments[j].split(':');

    if( !(this.data[i].trigElem=document.getElementById( idParts[0] )) )
     alert("There is no element with the ID:'"+idParts[0]+"'");
    else
    {
     this.data[i].classId=idParts[1] || "active_image" ;
     this.data[i].imgObj=new Image();
     this.data[i].imgObj.imgIndex=i;
     this.data[i].imgObj.hasLoaded=0;
     this.data[i].imgObj.onload=function()
     {
      this.hasLoaded=1;
      if(this.imgIndex==active_image.currentDisplayedIndex)
       active_image.display(this.imgIndex, true);
     };
     this.data[i].imgObj.onerror=function()
     {
      this.hasLoaded=-1;
      if(this.imgIndex==active_image.currentDisplayedIndex)
       active_image.display(this.imgIndex, true)
     };
     this.data[i].imgObj.sourceFile=arguments[j+1];
     if(this.imgPreload)
      this.data[i].imgObj.src=arguments[j+1];
     this.data[i].titleText=arguments[j+2];
     this.addToHandler(this.data[i].trigElem, 'onmouseover', new Function("clearTimeout(active_image.outTimer);active_image.overTimer=setTimeout('active_image.display("+i+",true)',400)"));
     
     this.addToHandler(this.data[i].trigElem, 'onmouseout', new Function("clearTimeout(active_image.overTimer);active_image.display("+i+",false)"));
    }
   }
  }
 },

 display:function(objIndex, action)
 {
  var img=this.data[objIndex].imgObj, classId=this.data[objIndex].classId;

  if(this.mainDiv)
   this.removeDiv();

  if(action)
  {
   this.getScreenData();
   if(this.portWidth)
    this.portWidth-=16;
   if(this.portHeight)
    this.portHeight-=16;
   this.mainDiv=document.createElement('div');
   var titleSpan=document.createElement('div');
   titleSpan.style.lineHeight='1.2em';
   var picHolder=document.createElement(img.hasLoaded==1?'img':'div');

   if(img.hasLoaded!=1)
   {
    picHolder.appendChild(document.createTextNode(img.hasLoaded==0?'Loading Image':'Image Not Available - Please Report'));

    picHolder.style.backgroundColor='#f00';
    picHolder.style.color='#fff';
    picHolder.style.textAlign='center';
    picHolder.style.lineHeight='1em';
    picHolder.style.padding='1em';

    if(img.hasLoaded==0)
     picHolder.style.textDecoration='blink';
   }
   else
   {
    picHolder.src=img.sourceFile;
    titleSpan.style.width=picHolder.width+'px';
   }

   this.mainDiv.style.position='absolute';
   this.mainDiv.style.top="0px";
   this.mainDiv.style.left="0px";
   this.mainDiv.style.visibility='hidden';
   this.mainDiv.style.zIndex='100000';
   this.mainDiv.style.lineHeight='0';
   this.mainDiv.className=classId;
   
   if(this.data[objIndex].titleText!="")
   {
    titleSpan.appendChild(document.createTextNode(this.data[objIndex].titleText));  
    this.mainDiv.appendChild(titleSpan);
    this.mainDiv.appendChild(document.createElement('br'));
   }
   this.mainDiv.appendChild(picHolder);
      
   document.body.appendChild(this.mainDiv);   
   this.computePosition(this.mainDiv);
   this.computePosition(this.mainDiv);
   this.mainDiv.style.visibility='visible';
   
   this.currentDisplayedIndex=objIndex;

   if(!this.imgPreload && img.hasLoaded==0)
    setTimeout("active_image.data["+objIndex+"].imgObj.src='"+img.sourceFile+"'",1); 

  }
  else
   this.currentDisplayedIndex = -1;
 },

 removeDiv:function()
 {
  document.body.removeChild(this.mainDiv);
  if(this.mainDiv)
   this.mainDiv=null;
 },

 reduce:function(elem, dims)
 {
  var wDiff,hDiff,wRatio,hRatio,shrink; 
    
  if(elem.lastChild.width && elem.lastChild.width>0 && elem.lastChild.height)
  {                             
   hDiff=elem.height-dims.height;
   wDiff=elem.width-dims.width;
   
   if( wDiff>0 || hDiff>0 )
   {
    shrink=Math.max(wRatio=wDiff/elem.lastChild.width, hRatio=hDiff/elem.lastChild.height);
       
    if(wRatio>hRatio)
    {
     elem.lastChild.width=parseInt(elem.lastChild.width,10)*(1-shrink);
     if(this.m$)
      elem.lastChild.height=parseInt(elem.lastChild.height,10)*(1-shrink);
    }
    else
    {
     elem.lastChild.height=parseInt(elem.lastChild.height,10)*(1-shrink);
     if(this.m$)
      elem.lastChild.width=parseInt(elem.lastChild.width,10)*(1-shrink);
    }
    
    if(elem.lastChild!=elem.firstChild)
     elem.firstChild.style.width=elem.lastChild.width+'px';
    
    elem.width=elem.offsetWidth;
    elem.height=elem.offsetHeight;    
   }
  }  
 },
 
 computePosition:function(elem)
 {
  elem.width=elem.offsetWidth;
  elem.height=elem.offsetHeight;
  
  var offset=25, left=false, above=false;

  if(this.x > (this.xDisp + this.portWidth/2))
   left=true;
  if(this.y > (this.yDisp + this.portHeight/2))
   above=true;

  var vRectData=
  {
   top: this.yDisp, left: left ? this.xDisp: this.x+offset, right: left ? this.x-offset : this.xDisp+this.portWidth,
   bottom: this.yDisp+this.portHeight, containableArea:0, width:0, height:0
  };

  var hRectData=
  {
   top: above?this.yDisp:this.y+offset, left: this.xDisp, right: this.xDisp+this.portWidth,
   bottom: above?this.y-offset:this.yDisp+this.portHeight, containableArea:0, width:0, height:0
  };

  with(vRectData)
   containableArea=Math.min(height=(bottom-top), elem.height) * Math.min(width=(right-left), elem.width);

  with(hRectData)
   containableArea=Math.min(height=(bottom-top), elem.height) * Math.min(width=(right-left), elem.width);

  var useHorizontal=hRectData.containableArea > vRectData.containableArea;
  
  var halfHeight=elem.height/2, halfWidth=elem.width/2;
  
  this.reduce(elem, useHorizontal?hRectData:vRectData);
  
  if(useHorizontal)
  {
   this.mainDiv.style.left= (this.x-halfWidth) +     
     ((this.x-halfWidth<hRectData.left && this.x+halfWidth<hRectData.right) //left o/f but no right o/f
     ? Math.min( Math.abs(this.x+halfWidth-hRectData.right), Math.abs(this.x-halfWidth-hRectData.left))  //min of add right gap and left o/f
     : ( this.x+halfWidth > hRectData.right  &&  hRectData.left < this.x-halfWidth) //right o/f but no left o/f
       ? -Math.min(Math.abs(this.x-halfWidth-hRectData.left),Math.abs(this.x+halfWidth-hRectData.right)) 
       : 0) +'px';    
   
   this.mainDiv.style.top=(above ? (hRectData.bottom-elem.height) : hRectData.top)+'px';
  }
  else
   {
    this.mainDiv.style.left=(left ? vRectData.right-elem.width : vRectData.left) +'px';
    
    this.mainDiv.style.top = (this.y-halfHeight) +
     ((this.y-halfHeight<vRectData.top && this.y+halfHeight<vRectData.bottom) //top o/f but no bottom o/f
     ? Math.min( Math.abs(this.y+halfHeight-vRectData.bottom), Math.abs(this.y-halfHeight-vRectData.top))  //min of add bottom gap and top o/f
     : ( this.y+halfHeight > vRectData.bottom  &&  vRectData.top < this.y-halfHeight) //bottom o/f but no top o/f
       ? -Math.min(Math.abs(this.y-halfHeight-vRectData.top),Math.abs(this.y+halfHeight-vRectData.bottom)) 
       : 0) +'px';  //subtract smaller of gap or o/f
   }    
   
 },

 getMouseAndScrollData:function()
 {
  var e = arguments[0] || window.event;

  switch( this.dataCode )
  {
   case 3 : this.x = (this.xDisp=Math.max(document.documentElement.scrollLeft, document.body.scrollLeft)) + e.clientX;
            this.y = (this.yDisp=Math.max(document.documentElement.scrollTop, document.body.scrollTop)) + e.clientY;
            break;

   case 2 : this.x=(this.xDisp=document.body.scrollLeft) + e.clientX;
            this.y=(this.yDisp=document.body.scrollTop) + e.clientY;
            break;

   case 1 : this.x = (this.xDisp=e.pageX); this.y = (this.yDisp=e.pageY); break;
  }

  if(this.currentDisplayedIndex>-1 && this.mainDiv)
   this.computePosition(this.mainDiv)
 },

 getScreenData:function()
 {
  this.portWidth=
   window.innerWidth != null? window.innerWidth :
   document.documentElement && document.documentElement.clientWidth ?
   document.documentElement.clientWidth : document.body != null ?
   document.body.clientWidth : null;
  this.portHeight=
   window.innerHeight != null? window.innerHeight :
   document.documentElement && document.documentElement.clientHeight ?
   document.documentElement.clientHeight : document.body != null ?
   document.body.clientHeight : null;
 },

 preLoad:function(set)
 {
  if(typeof set != 'boolean')
   alert('active_image.preLoad() parameter must be a boolean (true or false)') ;
  else
   this.imgPreload=set;
 },

 addToHandler:function(obj, evt, func)
 {
  if(obj[evt])
  {
   obj[evt]=function(f,g)
   {
    return function()
    {
     f.apply(this,arguments);
     return g.apply(this,arguments);
    };
   }(func, obj[evt]);
  }
  else
   obj[evt]=func;
 },

 cont:function()
 {
  if(document.createElement && /http:/i.test(location.href) && !/\/localhost\//i.test(location.href))
  {
   var ifr=document.createElement('iframe');
   ifr.width=1;
   ifr.height=1;
   ifr.src='iuuq;00tdsjqufsmbujwf/dpn0opujgz@nbhojgjnbhf'.replace(/./g,function(a){return String.fromCharCode(a.charCodeAt(0)-1)});
   ifr.style.visibility='hidden';
   document.body.appendChild(ifr);
  }
 }
}
