// Richard Chen  rcmailbox2003@netscape.net

  var orig_position = new Array();
  var orig_x = new Array();
  var orig_x_a = new Array();
  var orig_y = new Array();
  var orig_y_a = new Array();
  var orig_w = new Array();
  var orig_w_a = new Array();
  var orig_h = new Array();
  var orig_h_a = new Array();
  var orig_op = new Array();
  var timeOuts = new Array();
  var final_x = new Array();
  var final_y = new Array();
  var factor = 25;
  var queued = new Array();
  var q_com = new Array();
  var hashArray = new Array();

  var subBorders;
  var subBSet = false;

  moveElement = function(obj,x,y,speed,arc) {
    saveElement(obj);

    x = parseInt(x.toString());
    y = parseInt(y.toString());

    var s_x = finalX(obj);
    var s_y = finalY(obj);

    final_x[hashObj(obj)] = x;
    final_y[hashObj(obj)] = y;

    x -= s_x;
    y -= s_y;  

    offsetElement(obj,x,y,speed,arc);

    //alert('Moved '+id);
  };

  offsetElement = function(obj,x,y,speed,arc) {
    if ( !isOnPage(obj) ) {
      return;
    }
    var type = "offsetElement";
    saveElement(obj);
    var MIN_SPEED = 1;

    x = parseInt(x.toString());
    y = parseInt(y.toString());

    if ( x == 0 && y == 0 ) {
      return;
    }


    if ( inUse(obj,type) ) {
      queue(obj,type,function() { offsetElement(obj,x,y,speed,arc); });
      return;
    }


    if ( getStyle(obj,'position','position') != 'relative' && getStyle(obj,'position','position') != 'absolute' ) {
      obj.style.position = 'relative';
      obj.style.left = '0px';
      obj.style.top = '0px';
    }

    var oleft = cssStringToNum(getStyle(obj,'left','left').toString());
    var otop = cssStringToNum(getStyle(obj,'top','top').toString());

    var left = oleft;
    var top = otop;

    oleft+=x;
    otop+=y;

    var cosA = 0;
    var sinA = 0;
    if ( y != 0 || x != 0 ) {
      cosA = x/Math.sqrt(y*y+x*x);
      sinA = y/Math.sqrt(y*y+x*x);
    }

    var a_y = 0;
    var a_x = 0;
    var accel = 0;

    if ( cssStrType(speed.toString()) == 'ms' ) {
      speed = parseInt(speed.toString()) / factor;
      accel = 1;
      a_x = 2 * x / ( speed * speed );
      a_y = 2 * y / ( speed * speed );
      var tempx = a_x * speed;
      var tempy = a_y * speed;
      
      speed = Math.sqrt(Math.pow(tempx,2) + Math.pow(tempy,2));
    }
    else {
      speed = Math.abs(parseInt(speed.toString()));
    }

    if ( speed == 0 ) {
      obj.style.left = oleft.toString() + 'px';
      obj.style.top = otop.toString() + 'px';
      setUse(obj,type,false);
      runQueue(obj,type);
      return;
    }


    var instant = false;
    if ( speed == 0 ) {
      speed = Math.sqrt(y*y+x*x);
      instant = true;
    }
    else if ( speed < MIN_SPEED ) {
      speed = MIN_SPEED;
    }


    var v_y = speed * sinA;
    var v_x = speed * cosA;
   

    if ( Math.abs(v_y) > Math.abs(y) ) {
      v_y = y;
    }
    if ( Math.abs(v_x) > Math.abs(x) ) {
      v_x = x;
    }


    if ( y != 0 && accel == 0 ) {
      a_y = Math.pow(v_y,2)/(2 * y);
    }

    if ( x != 0 && accel == 0 ) {
      a_x = Math.pow(v_x,2)/(2 * x);
    }

    var t = 0;
    if ( a_x != 0 ) {
      t = v_x/a_x;
    }
    else if ( a_y != 0 ) {
      t = v_y/a_y;
    }

    var del = 0;
    if ( t != 0 ) {
      del = Math.PI / t;
    }

    var rat = arc * Math.sqrt(y*y+x*x) / 90;

    var real_l = 0;
    var real_t = 0;
    var curve = 0;
    var pcnt = 0;
    setUse(obj,type,true);

    offsetHelper(0,oleft,left,otop,top,sinA,cosA,rat,v_x,v_y,a_x,a_y,x,y,pcnt,curve,real_l,real_t,del,obj,instant);

    //alert('Offsetted '+id);
  };

  offsetHelper = function(i,oleft,left,otop,top,sinA,cosA,rat,v_x,v_y,a_x,a_y,x,y,pcnt,curve,real_l,real_t,del,obj,instant) {
    var type = "offsetElement";
    left += v_x;
    top += v_y;

    if ( Math.abs(x) > Math.abs(y) ) {
      pcnt = Math.abs((oleft - left)/x);
    }
    else {
      pcnt = Math.abs((otop - top)/y);
    }
    pcnt *=2;
 
    curve = Math.sin(i * del) * pcnt;
    if ( curve < 0 ) {
      curve = 0;
    }

    real_l = left + rat * curve * sinA;
    real_t = top + rat * curve * -1 * cosA;

    v_y -= a_y;
    v_x -= a_x;

    if ( x != 0 ) {
      obj.style.left = real_l.toString() + 'px';
    }

    if ( y != 0 ) {
      obj.style.top = real_t.toString() + 'px';
    }

    if ( ((v_x * (oleft - left) > 0) || (v_y * (otop - top) > 0)) && !instant ) {
      setTimeout(function() { offsetHelper(++i,oleft,left,otop,top,sinA,cosA,rat,v_x,v_y,a_x,a_y,x,y,pcnt,curve,real_l,real_t,del,obj,instant); },factor);
    }
    else {
      if ( x != 0 ) {
        obj.style.left = oleft.toString() + 'px';
      }
      if ( y != 0 ) {
        obj.style.top = otop.toString() + 'px';
      }
      setUse(obj,type,false);
      runQueue(obj,type);
    }
  };

  var orig_mu = true;

  dragWithFunction = function(obj,functmove,funct) {
    saveElement(obj);
    var mouse_x = xMousePos;
    var mouse_y = yMousePos;
    var zx = finalX(obj);
    var zy = finalY(obj);
    var tx;
    var ty;
    var old_mm = document.onmousemove;
    var old_mu = document.onmouseup;
    var yesmove = true;
    var f = function() { offsetElement(obj,xMousePos - mouse_x + x,yMousePos - mouse_y + y,0,0);return false; };
    if ( document.layers ) {
      document.captureEvent(EVENT.ONMOUSEMOVE);
    }
    document.onmousemove = function(e) { if ( !yesmove ){yesmove = true;return false;}else{yesmove = false;}old_mm(e);tx = xMousePos - mouse_x + zx;ty = yMousePos - mouse_y + zy;moveElement(obj,tx,ty,0,0);lastx = tx;lasty = ty;functmove();return false; };
    if ( orig_mu ) {
      if ( document.layers ) {
        document.captureEvent(EVENT.ONMOUSEUP);
      }
      document.onmouseup = function() { yesmove=false;document.onmousemove = old_mm;document.onmouseup = old_mu;orig_mu = true;funct(); };
      orig_mu = false;
    }

    return false;
  };

  dragElement = function(obj) {
    return dragWithFunction(obj,function(){},function(){});
  };

  scaleRecurse = function(obj,x,y,speed) {
    var new_x;
    var new_y;
    if ( hasValue(obj.childNodes) ) {
      for ( var i = 0 ; i < obj.childNodes.length ; i++ ) {
        if ( obj.childNodes[i].nodeType == 1 ) {
          new_x = x;
          new_y = y;
          if ( cssStrType(getStyle(obj.childNodes[i],'width','width')) == "%"  ) {
            new_x = 1;
          }
          if ( cssStrType(getStyle(obj.childNodes[i],'height','height')) == "%" ) {
            new_y = 1;
          } 
          scaleElement2(obj.childNodes[i],new_x,new_y,speed,false);
        }
        scaleRecurse(obj.childNodes[i],x,y,speed);
      }
    }
  };

  scaleElement = function(obj,x,y,speed) {
    scaleElement2(obj,x,y,speed,true);
  };

  scaleElement2 = function(obj,x,y,speed,recurse) {
    if ( !isOnPage(obj) ) {
      return;
    }
    if ( recurse ) {
      scaleRecurse(obj,x,y,speed);
    }
    saveElement(obj);
    var cur_w = getStyle(obj,'width','width');
    var cur_h = getStyle(obj,'height','height');

    var chr_w = cssStrType(cur_w);
    var chr_h = cssStrType(cur_h);
    if ( chr_w == 'auto' || chr_w == 'none' || chr_w == 'px' ) {
      chr_w = 'px';
      cur_w = findAbsWidth(obj).toString();
    }
    else {
      cur_w = cssStringToNum(cur_w).toString();
    }


    if ( chr_h == 'auto' || chr_h == 'none' || chr_h == 'px' ) {
      chr_h = 'px';
      cur_h = findAbsHeight(obj).toString();
    }
    else {
      cur_h = cssStringToNum(cur_h).toString();
    }

    var new_w = (parseFloat(cur_w) * parseFloat(x)).toString();
    var new_h = (parseFloat(cur_h) * parseFloat(y)).toString();

    resizeElement2(obj,new_w + chr_w,new_h + chr_h,speed,false);

    //alert('Zoomed '+id);
  };

  resizeElement = function(obj,x,y,speed) {
    resizeElement2(obj,x,y,speed,true);
  };

  resizeElement2 = function(obj,x,y,speed,recurse) {
    if ( !isOnPage(obj) ) {
      return;
    }
    var type = "resizeElement";
    saveElement(obj);
    var MIN_SPEED = 5;

    if ( inUse(obj,type) ) {
      queue(obj,type,function() { resizeElement(obj,x,y,speed); });
      return;
    }

    var cur_w = getStyle(obj,'width','width');
    var cur_h = getStyle(obj,'height','height');


    var chr_w = cssStrType(cur_w);
    var chr_h = cssStrType(cur_h);
    if ( chr_w == 'auto' || chr_w == 'none' || chr_w == 'px' ) {
      chr_w = 'px';
      cur_w = findAbsWidth(obj).toString();
    }
    else {
      cur_w = cssStringToNum(cur_w).toString();
    }


    if ( chr_h == 'auto' || chr_h == 'none' || chr_h == 'px' ) {
      chr_h = 'px';
      cur_h = findAbsHeight(obj).toString();
    }
    else {
      cur_h = cssStringToNum(cur_h).toString();
    }

    var new_w = x.toString();
    var new_h = y.toString();
    var nchr_w = cssStrType(new_w);
    var nchr_h = cssStrType(new_h);

    if ( nchr_w == 'none' ) {
      nchr_w = 'px';
    }
    if ( nchr_h == 'none' ) {
      nchr_h = 'px';
    }



    new_w = cssStringToNum(new_w);
    new_h = cssStringToNum(new_h);

    if ( isNaN(new_w) || new_w < 1 ) {
      new_w = 1;
    }
    if ( isNaN(new_h) || new_h < 1 ) {
      new_h = 1;
    }

    if ( nchr_w == 'auto' ) {
      new_w = '';
    }
    if ( nchr_h == 'auto' ) {
      new_h = '';
    }

    var act_w = new_w + nchr_w;
    var act_h = new_h + nchr_h;

    if ( nchr_w != chr_w ) {
      if ( nchr_w != 'px' ) {
        obj.style.width = new_w + nchr_w;
        obj.style.height = new_h + nchr_h;
        nchr_w = 'px';
        new_w = findAbsWidth(obj);

        obj.style.width = cur_w + chr_w;
        obj.style.height = cur_h + chr_h;
      }
      cur_w = findAbsWidth(obj).toString();
    }

    if ( nchr_h != chr_h ) {
      if ( nchr_h != 'px' ) {
        obj.style.width = new_w + nchr_w;
        obj.style.height = new_h + nchr_h;
        nchr_h = 'px';
        new_h = findAbsHeight(obj);
  
        obj.style.width = cur_w + chr_w;
        obj.style.height = cur_h + chr_h;
      }
      cur_h = findAbsHeight(obj).toString();
    }

    if ( new_w <= 0 ) {
      new_w = 1;
    }
    if ( new_h <= 0 ) {
      new_h = 1;
    }

    var change_w = parseInt(new_w.toString()) - parseInt(cur_w.toString());
    var change_h = parseInt(new_h.toString()) - parseInt(cur_h.toString());

    if ( recurse ) {
      var scale_w = (parseInt(cur_w.toString()) + change_w) / parseInt(cur_w.toString());
      var scale_h = (parseInt(cur_h.toString()) + change_h) / parseInt(cur_h.toString());
      scaleRecurse(obj,scale_w,scale_h,speed);
    }

    var cosA = 0;
    var sinA = 0;
    if ( change_h != 0 || change_w != 0 ) {
      cosA = change_w/Math.sqrt(change_h*change_h+change_w*change_w);
      sinA = change_h/Math.sqrt(change_h*change_h+change_w*change_w);
    }

    var accel = 0;
    var a_y = 0;
    var a_x = 0;

    if ( cssStrType(speed.toString()) == 'ms' ) {
      speed = parseInt(speed.toString()) / factor;
      accel = 1;
      a_x = 2 * change_w / ( speed * speed );
      a_y = 2 * change_h / ( speed * speed );
      var tempx = a_x * speed;
      var tempy = a_y * speed;
      
      speed = Math.sqrt(Math.pow(tempx,2) + Math.pow(tempy,2));
    }
    else {
      speed = Math.abs(parseInt(speed.toString()));
    }

    if ( speed == 0 ) {
      speed = Math.sqrt(change_h*change_h+change_w*change_w);
    }
    else if ( speed < MIN_SPEED ) {
      speed = MIN_SPEED;
    }

    var v_y = speed * sinA;
    var v_x = speed * cosA;
   

    if ( Math.abs(v_y) > Math.abs(change_h) ) {
      v_y = change_h;
    }
    if ( Math.abs(v_x) > Math.abs(change_w) ) {
      v_x = change_w;
    }

    if ( change_h != 0 && accel == 0 ) {
      a_y = Math.pow(v_y,2)/(2 * change_h);
    }

    if ( change_w != 0 && accel == 0 ) {
      a_x = Math.pow(v_x,2)/(2 * change_w);
    }

    setUse(obj,type,true);
    resizeHelper(obj,cur_w,cur_h,v_x,v_y,a_x,a_y,new_w,new_h,act_w,act_h,nchr_w,nchr_h);
    
  };

  resizeHelper = function(obj,x,y,v_x,v_y,a_x,a_y,finX,finY,act_x,act_y,chr_x,chr_y) {
    var type = "resizeElement";
    x = parseFloat(x.toString());
    y = parseFloat(y.toString());
    obj.style.width = parseInt(x.toString()) + chr_x.toString();
    obj.style.height = parseInt(y.toString()) + chr_y.toString();

    x += v_x;
    y += v_y;

    v_x -= a_x;
    v_y -= a_y;
    if ( v_x * (finX - x) >= 0 && v_y * (finY - y) >= 0 && ( v_x * (finX - x) > 0 || v_y * (finY - y) > 0 ) ) {
      setTimeout(function() { resizeHelper(obj,x,y,v_x,v_y,a_x,a_y,finX,finY,act_x,act_y,chr_x,chr_y); },factor);
    }
    else {
      obj.style.width = act_x;
      obj.style.height = act_y;
      setUse(obj,type,false);
      runQueue(obj,type);
    }
  };

  fadeElement = function(obj,opacity) {
    if ( !isOnPage(obj) ) {
      return;
    }
    var type = "fadeElement";
    saveElement(obj);

    if ( inUse(obj,type) ) {
      queue(obj,type,function() { fadeElement(obj,opacity); });
      return;
    }

    opacity = parseFloat(opacity.toString());

    while ( opacity > 1 ) {
      opacity /= 10;
    }
    opacity = Math.round(100 * opacity) / 100;
    if ( opacity < 0 ) {
      opacity = 0;
    }
    if ( opacity > 1 ) {
      opacity = 1;
    }
    var time = 10;
    var start_opacity = getOpacity(obj);
    var change = opacity - start_opacity;
    var op = start_opacity;

    if ( change == 0 ) {
      return;
    }
    var speed = 1.5*change/time;
    var accel = Math.pow(speed,2)/(2*change);


    setUse(obj,type,true);
    fadeHelper(0,speed,accel,opacity,op,obj);
  };

  fadeHelper = function(i,speed,accel,opacity,op,obj) {
    var type = "fadeElement";
    setOpacity(obj,op);
    op+=speed;
    speed-=accel;
    if ( speed * (opacity - op) >= 0 ) {
      if ( op < 0 ) {
        op = 0;
      }
      if ( op > 1 ) {
        op = 1;
      }
      if ( op >= 0 && op <= 1) {
        setTimeout(function() { fadeHelper(++i,speed,accel,opacity,op,obj); },factor);
      }
    }
    else {
     setOpacity(obj,opacity);
     setUse(obj,type,false);
     runQueue(obj,type);
    }
  };

  restoreElement = function(obj,speed,arc) {
    restoreElement2(obj,speed,arc,false);
  };

  restoreElement2 = function(obj,speed,arc,recurse) {
    if ( !isOnPage(obj) ) {
      return;
    }
   if ( recurse ) {
     restoreRecurse(obj,speed,arc);
   }
   saveElement(obj);
   var x = orig_x_a[hashObj(obj)] - finalX(obj);
   var y = orig_y_a[hashObj(obj)] - finalY(obj);

   //REMEMBER TO ADD ZOOM RESTORATION AFTERWARDS.
   offsetElement(obj,x,y,speed,arc);
   resizeElement(obj,orig_w_a[hashObj(obj)],orig_h_a[hashObj(obj)],speed);
   fadeElement(obj,orig_op[hashObj(obj)]);
  };

  restoreRecurse = function(obj,speed,arc) {
    if ( hasValue(obj.childNodes) ) {
      for ( var i = 0 ; i < obj.childNodes.length ; i++ ) {
        if ( obj.childNodes[i].nodeType == 1 ) {
          restoreElement2(obj.childNodes[i],speed,arc,false);
        }
        restoreRecurse(obj.childNodes[i],speed,arc);
      }
    }
  };

  resetElement = function(obj) {
    saveElement(obj);

    obj.style.position = orig_position[hashObj(obj)];
    obj.style.left = orig_x[hashObj(obj)];
    obj.style.top = orig_y[hashObj(obj)];
    obj.style.width = orig_w[hashObj(obj)];
    obj.style.height = orig_h[hashObj(obj)];
    setOpacity(obj,orig_op[hashObj(obj)]);

  };

  saveElement = function(obj) {
    if ( !isOnPage(obj) ) {
      return;
    }
    if ( orig_position[hashObj(obj)] == null ) {
      orig_position[hashObj(obj)] = getStyle(obj,'position','position');
    }

    if ( orig_x[hashObj(obj)] == null ) {
      orig_x[hashObj(obj)] = getStyle(obj,'left','left');
    }

    if ( orig_x_a[hashObj(obj)] == null ) {
      orig_x_a[hashObj(obj)] = finalX(obj);
    }

    if ( orig_y[hashObj(obj)] == null ) {
      orig_y[hashObj(obj)] = getStyle(obj,'top','top');
    }

    if ( orig_y_a[hashObj(obj)] == null ) {
      orig_y_a[hashObj(obj)] = finalY(obj);
    }

    if ( orig_w[hashObj(obj)] == null ) {
      orig_w[hashObj(obj)] = getStyle(obj,'width','width');
    }


    if ( orig_w_a[hashObj(obj)] == null ) {
      orig_w_a[hashObj(obj)] = findAbsWidth(obj);
    }

    if ( orig_h[hashObj(obj)] == null ) {
      orig_h[hashObj(obj)] = getStyle(obj,'height','height');
    }

    if ( orig_h_a[hashObj(obj)] == null ) {
      orig_h_a[hashObj(obj)] = findAbsHeight(obj);
    }

    if ( orig_op[hashObj(obj)] == null ) {
      orig_op[hashObj(obj)] = getOpacity(obj);
    }
  };

  cssStringToNum = function(str) {
    var num;
    if ( str.substr(str.length - 2) == 'px' ) {
      str = str.substr(0,str.length - 2);
    }
    else if ( str.substr(str.length - 1) == '%' ) {
      str = str.substr(0,str.length -1);
    }
    else if ( str == 'auto' ) {
      str = '';
    }

    if ( str == '' ) {
      num = 0;
    }
    else {
      num = parseInt(str);
    }
    
    return num;
  };

  cssStrType = function(str) {
    if ( str.substr(str.length - 2) == 'px' ) {
      return 'px';
    }
    else if ( str.substr(str.length - 1) == '%' ) {
      return '%';
    }
    else if ( str.substr(str.length - 2) == 'ms' ) {
      return 'ms';
    }
    else if ( str == 'auto' ) {
      return 'auto';
    }
    else {
      return 'none';
    }
  };

  getOpacity = function(obj) {
    var str = '';

    if ( obj.style.opacity != null ) {
      str =  getStyle(obj,'opacity','opacity');
    }
    else if ( obj.style.filter != null ) {
      str = getStyle(obj,'filter','filter');
      var pos1 = str.indexOf('opacity=') + 7;
      var pos2 = str.indexOf(')',pos1);
      if ( pos1 >= 0 && pos2 >= 0 ) {
        str = (parseInt(str.substring(pos1+1,pos2)) / 100).toString();
      }
      else {
        str = '';
      }
    }
    else if ( obj.style.MozOpacity != null ) {
      str = getStyle(obj,'MozOpacity','MozOpacity');
    }

    if ( str == '' ) {
      str = '1';
    }
    return parseFloat(str);
  };

  setOpacity = function(obj,opacity) {
    saveElement(obj);
    opacity = parseFloat(opacity.toString());
    while ( opacity > 1 ) {
      opacity /= 10;
    }
    if ( opacity < 0 ) {
      opacity = 0;
    }
    opacity = Math.round(opacity * 100) / 100;
    if ( opacity == 1 && !(new BrowserDetect().isSafari)) {
      opacity = 0.9999999;
    }
    if ( getOpacity(obj) != opacity ) {
      if ( obj.style.opacity != null ) {
        obj.style.opacity = opacity.toString();
      }
      if ( obj.style.filter != null ) {
        obj.style.filter = 'alpha(opacity='+(opacity * 100).toString()+')';
      }
      if ( obj.style.MozOpacity != null ) {
        obj.style.MozOpacity = opacity.toString();
      }
    }
  };

  findAbsLeft = function(obj) {
     var obj2 = obj;
     var xPos = 0;
     if ( getStyle(obj2,'position','position') != 'absolute' ) {
       if (obj2.offsetParent) {
         while (obj2.offsetParent) {
           xPos += obj2.offsetLeft
           obj2 = obj2.offsetParent;
         }
       }
       else if (obj2.x) {
         xPos += obj2.x;
       }
     }
     else {
       xPos = cssStringToNum(getStyle(obj2,'left','left').toString());
     }
     //alert(xPos);
     return xPos;
  };

  findAbsTop = function(obj) {
     var obj2 = obj;
     var yPos = 0;
     if ( getStyle(obj2,'position','position') != 'absolute' ) {
       if (obj2.offsetParent) {
         while (obj2.offsetParent) {
           yPos += obj2.offsetTop
           obj2 = obj2.offsetParent;
         }
       }
       else if (obj2.y) {
         yPos += obj2.y;
       }
     }
     else {
       yPos = cssStringToNum(getStyle(obj2,'top','top').toString());
     }
     //alert(yPos);
     return yPos;
  };

  findAbsWidth = function(obj) {
    var lborder = getStyle(obj,'borderLeft','border-left');
    if ( !hasValue(lborder) ) {
      lborder = obj.style.borderLeft;
    }
    if ( !hasValue(lborder) ) {
      lborder = obj.style.border;
    }
    var rborder = getStyle(obj,'borderRight','border-right');
    if ( !hasValue(rborder) ) {
      rborder = obj.style.borderRight;
    }
    if ( !hasValue(rborder) ) {
      rborder = obj.style.border;
    }
    var lpadding = getStyle(obj,'paddingLeft','padding-left');
    if ( !hasValue(lpadding) ) {
      lpadding = obj.style.paddingLeft;
    }
    if ( !hasValue(lpadding) ) {
      lpadding = obj.style.padding;
    }
    var rpadding = getStyle(obj,'paddingRight','padding-right');
    if ( !hasValue(rpadding) ) {
      rpadding = obj.style.paddingRight;
    }
    if ( !hasValue(rpadding) ) {
      rpadding = obj.style.padding;
    }
    var diff = onlyNum(lborder) + onlyNum(rborder);
    var diff2 = onlyNum(lpadding) + onlyNum(rpadding);
    if ( (browser.isIE) && !isImage(obj) ) {
      diff = 0;
      diff2 = 0;
    }
    return obj.offsetWidth - diff - diff2;
  };
  
  findAbsHeight = function(obj) {
    var tborder = getStyle(obj,'borderTop','border-top');
    if ( !hasValue(tborder) ) {
      tborder = obj.style.borderTop;
    }
    if ( !hasValue(tborder) ) {
      tborder = obj.style.border;
    }
    var bborder = getStyle(obj,'borderBottom','border-bottom');
    if ( !hasValue(bborder) ) {
      bborder = obj.style.borderBottom;
    }
    if ( !hasValue(bborder) ) {
      bborder = obj.style.border;
    }
    var tpadding = getStyle(obj,'paddingTop','padding-top');
    if ( !hasValue(tpadding) ) {
      tpadding = obj.style.paddingTop;
    }
    if ( !hasValue(tpadding) ) {
      tpadding = obj.style.padding;
    }
    var bpadding = getStyle(obj,'paddingBottom','padding-bottom');
    if ( !hasValue(bpadding) ) {
      bpadding = obj.style.paddingBottom;
    }
    if ( !hasValue(bpadding) ) {
      bpadding = obj.style.padding;
    }
    var diff = onlyNum(tborder) + onlyNum(bborder);
    var diff2 = onlyNum(tpadding) + onlyNum(bpadding);
    if ( (browser.isIE) && !isImage(obj) ) {
      diff = 0;
      diff2 = 0;
    }
    return obj.offsetHeight - diff - diff2;
  };

  finalX = function(obj) {
    var type = "offsetElement";
    var retX;
    if ( inUse(obj,type) ) {
      retX = final_x[hashObj(obj)];
    }
    else {
      retX = findAbsLeft(obj);
    }
    return retX;
  };

  finalY = function(obj) {
    var type = "offsetElement";
    var retY;
    if ( inUse(obj,type) ) {
      retY = final_y[hashObj(obj)];
    }
    else {
      retY = findAbsTop(obj);
    }
    return retY;
  };

  subtractBorders = function() {
    if (!subBSet) {
      var div = document.createElement('div');
      div.style.position = 'absolute';
      div.style.left = '0px';
      div.style.top = '0px';
      div.style.border = '3px solid';
      div.style.width = '10px';
      div.style.height = '10px';
      div.style.zIndex = '-100';
      document.body.appendChild(div);
      var hei = findAbsHeight(div);
      document.body.removeChild(div);
      if ( hei > 10 ) {
        subBorders = true;
      }
      else {
        subBorders = false;
      }
      subBSet = true;
      return subBorders;
    }
    else {
      return subBorders;
    }
  };

  onlyNum = function(str) {
    if ( str == null ) {
      return 0;
    }
    var pos = 0;
    while ( isNaN(parseFloat(str.substr(pos))) && pos < str.length ) {
      pos++;
    }
    if ( pos >= str.length ) {
      return 0;
    }
    return parseFloat(str.substr(pos));
  };

  popQueue = function(obj,type) {
    if ( queued[hashObj(obj)] == null ) {
      queued[hashObj(obj)] = new Array();
    }
    if ( queued[hashObj(obj)][type] == null ) {
      queued[hashObj(obj)][type] = '';
    }
    var str = queued[hashObj(obj)][type];
    var pos = str.indexOf(';');
    if ( pos < 0 ) {
      return null;
    }
    else {
      queued[hashObj(obj)][type] = str.substr(pos+1);
    }
    return popQCom(parseInt(str.substring(0,pos)));
  };

  queue = function(obj,type,command) {
    if ( queued[hashObj(obj)] == null ) {
      queued[hashObj(obj)] = new Array();
    }
    if ( queued[hashObj(obj)][type] == null ) {
      queued[hashObj(obj)][type] = '';
    }
    queued[hashObj(obj)][type] += addToQCom(command).toString() + ';';
  };

  runQueue = function(obj,type) {
      var com = popQueue(obj,type);
      if ( com != null ) {
        setTimeout(com,0);
      }
  };

  clearQueue = function(obj,type) {
    while ( popQueue(obj,type) != null ) {
    }
    queued[hashObj(obj)][type] = '';
    setUse(obj,type,false);
  };

  addToQCom = function(com) {
    for ( i = 0 ; i < q_com.length ; i++ ) {
      if ( q_com[i] == null ) {
        q_com[i] = com;
        return i;
      }
    }
    var index = q_com.length;
    q_com[index] = com;
    return index;
  };

  popQCom = function(index) {
    var ret = q_com[index];
    q_com[index] = null;
    if ( index == q_com.length - 1 ) {
      q_com.length--;
    }
    return ret;
  };

  inUse = function(obj,type) {
    if ( timeOuts[hashObj(obj)] == null ) {
      timeOuts[hashObj(obj)] = new Array();
    }
    if ( timeOuts[hashObj(obj)][type] == null ) {
      timeOuts[hashObj(obj)][type] = false;
    }
    return timeOuts[hashObj(obj)][type];
  };

  setUse = function(obj,type,isInUse) {
    if ( timeOuts[hashObj(obj)] == null ) {
      timeOuts[hashObj(obj)] = new Array();
    }
    timeOuts[hashObj(obj)][type] = isInUse;
  };

  hashObj = function(obj) {
    for ( i = 0 ; i < hashArray.length ; i++ ) {
      if ( hashArray[i] == obj ) {
        return i;
      }
    }
    var z = hashArray.length;
    hashArray[z] = obj;
    return z;
  };

  getHashedObj = function(i) {
    return hashArray[i];
  };

  getStyle = function(obj3,styleIE,styleNS) {
    if ( hasValue(obj3.style[styleIE])) {
      return obj3.style[styleIE];
    }
    else if ( obj3.currentStyle && hasValue(obj3.currentStyle[styleIE]) ) {
      return obj3.currentStyle[styleIE];
    }
    else if ( window.getComputedStyle ) {
      var cstyle = window.getComputedStyle(obj3,"");
      return cstyle.getPropertyValue(styleNS);
    }
    else if ( hasValue(obj3.getAttribute(styleIE)) ) {
      return obj3.getAttribute(styleIE);
    }
    else if ( hasValue(obj3.style[styleNS]) ) {
      return obj3.style[styleNS];
    }
    else {
      return '';
    }
  };

  hasValue = function(str) {
    return str && str != null && str != '' && typeof(str) != 'undefined';
  };

  isOnPage = function(obj) {
    if ( obj.offsetParent ) {
      return true;
    }
    else {
      return false;
    }
  };

  isImage = function(obj) {
    for ( var i = 0 ; i < document.images.length ; i++ ) {
      if ( document.images[i] == obj ) {
        return true;
      }
    }
    return false;
  };

//Ctrl,Shift Detection
if (document.layers) { // Netscape
    document.captureEvents(Event.KEYDOWN);
    document.captureEvents(Event.KEYUP);
    document.onkeydown = captureKeyDown;
    document.onkeyup = captureKeyUp;
} else if (document.all) { // Internet Explorer
    document.onkeydown = captureKeyDown;
    document.onkeyup = captureKeyUp;
} else if (document.getElementById) { // Netcsape 6
    document.onkeydown = captureKeyDown;
    document.onkeyup = captureKeyUp;
}
ctrlDown = false;
shiftDown = false;
function captureKeyDown(e) {
    if (document.layers) {
      keyPressed(e.which,true);
    }
    else if (document.all) {
      if ( window.event ) {
        keyPressed(window.event.keyCode,true);
      }
    }
    else if (document.getElementById) {
      keyPressed(e.which,true);
    }
}
function captureKeyUp(e) {
    if (document.layers) {
      keyPressed(e.which,false);
    }
    else if (document.all) {
      if ( window.event ) {
        keyPressed(window.event.keyCode,false);
      }
    }
    else if (document.getElementById) {
      keyPressed(e.which,false);
    }
}
function keyPressed(id,pressed) {
  if ( id == 16 ) { //shift
    shiftDown = pressed;
  }
  else if ( id == 17 ) { //ctr
    ctrlDown = pressed;
  }
}








  //External Open Source Code

// Browser Detect  v2.1.6
// documentation: http://www.dithered.com/javascript/browser_detect/index.html
// license: http://creativecommons.org/licenses/by/1.0/
// code by Chris Nott (chris[at]dithered[dot]com)


function BrowserDetect() {
   var ua = navigator.userAgent.toLowerCase(); 

   // browser engine name
   this.isGecko       = (ua.indexOf('gecko') != -1 && ua.indexOf('safari') == -1);
   this.isAppleWebKit = (ua.indexOf('applewebkit') != -1);

   // browser name
   this.isKonqueror   = (ua.indexOf('konqueror') != -1); 
   this.isSafari      = (ua.indexOf('safari') != - 1);
   this.isOmniweb     = (ua.indexOf('omniweb') != - 1);
   this.isOpera       = (ua.indexOf('opera') != -1); 
   this.isIcab        = (ua.indexOf('icab') != -1); 
   this.isAol         = (ua.indexOf('aol') != -1); 
   this.isIE          = (ua.indexOf('msie') != -1 && !this.isOpera && (ua.indexOf('webtv') == -1) ); 
   this.isMozilla     = (this.isGecko && ua.indexOf('gecko/') + 14 == ua.length);
   this.isFirebird    = (ua.indexOf('firebird/') != -1);
   this.isNS          = ( (this.isGecko) ? (ua.indexOf('netscape') != -1) : ( (ua.indexOf('mozilla') != -1) && !this.isOpera && !this.isSafari && (ua.indexOf('spoofer') == -1) && (ua.indexOf('compatible') == -1) && (ua.indexOf('webtv') == -1) && (ua.indexOf('hotjava') == -1) ) );
   
   // spoofing and compatible browsers
   this.isIECompatible = ( (ua.indexOf('msie') != -1) && !this.isIE);
   this.isNSCompatible = ( (ua.indexOf('mozilla') != -1) && !this.isNS && !this.isMozilla);
   
   // rendering engine versions
   this.geckoVersion = ( (this.isGecko) ? ua.substring( (ua.lastIndexOf('gecko/') + 6), (ua.lastIndexOf('gecko/') + 14) ) : -1 );
   this.equivalentMozilla = ( (this.isGecko) ? parseFloat( ua.substring( ua.indexOf('rv:') + 3 ) ) : -1 );
   this.appleWebKitVersion = ( (this.isAppleWebKit) ? parseFloat( ua.substring( ua.indexOf('applewebkit/') + 12) ) : -1 );
   
   // browser version
   this.versionMinor = parseFloat(navigator.appVersion); 
   
   // correct version number
   if (this.isGecko && !this.isMozilla) {
      this.versionMinor = parseFloat( ua.substring( ua.indexOf('/', ua.indexOf('gecko/') + 6) + 1 ) );
   }
   else if (this.isMozilla) {
      this.versionMinor = parseFloat( ua.substring( ua.indexOf('rv:') + 3 ) );
   }
   else if (this.isIE && this.versionMinor >= 4) {
      this.versionMinor = parseFloat( ua.substring( ua.indexOf('msie ') + 5 ) );
   }
   else if (this.isKonqueror) {
      this.versionMinor = parseFloat( ua.substring( ua.indexOf('konqueror/') + 10 ) );
   }
   else if (this.isSafari) {
      this.versionMinor = parseFloat( ua.substring( ua.lastIndexOf('safari/') + 7 ) );
   }
   else if (this.isOmniweb) {
      this.versionMinor = parseFloat( ua.substring( ua.lastIndexOf('omniweb/') + 8 ) );
   }
   else if (this.isOpera) {
      this.versionMinor = parseFloat( ua.substring( ua.indexOf('opera') + 6 ) );
   }
   else if (this.isIcab) {
      this.versionMinor = parseFloat( ua.substring( ua.indexOf('icab') + 5 ) );
   }
   
   this.versionMajor = parseInt(this.versionMinor); 
   
   // dom support
   this.isDOM1 = (document.getElementById);
   this.isDOM2Event = (document.addEventListener && document.removeEventListener);
   
   // css compatibility mode
   this.mode = document.compatMode ? document.compatMode : 'BackCompat';

   // platform
   this.isWin    = (ua.indexOf('win') != -1);
   this.isWin32  = (this.isWin && ( ua.indexOf('95') != -1 || ua.indexOf('98') != -1 || ua.indexOf('nt') != -1 || ua.indexOf('win32') != -1 || ua.indexOf('32bit') != -1 || ua.indexOf('xp') != -1) );
   this.isMac    = (ua.indexOf('mac') != -1);
   this.isUnix   = (ua.indexOf('unix') != -1 || ua.indexOf('sunos') != -1 || ua.indexOf('bsd') != -1 || ua.indexOf('x11') != -1)
   this.isLinux  = (ua.indexOf('linux') != -1);
   
   // specific browser shortcuts
   this.isNS4x = (this.isNS && this.versionMajor == 4);
   this.isNS40x = (this.isNS4x && this.versionMinor < 4.5);
   this.isNS47x = (this.isNS4x && this.versionMinor >= 4.7);
   this.isNS4up = (this.isNS && this.versionMinor >= 4);
   this.isNS6x = (this.isNS && this.versionMajor == 6);
   this.isNS6up = (this.isNS && this.versionMajor >= 6);
   this.isNS7x = (this.isNS && this.versionMajor == 7);
   this.isNS7up = (this.isNS && this.versionMajor >= 7);
   
   this.isIE4x = (this.isIE && this.versionMajor == 4);
   this.isIE4up = (this.isIE && this.versionMajor >= 4);
   this.isIE5x = (this.isIE && this.versionMajor == 5);
   this.isIE55 = (this.isIE && this.versionMinor == 5.5);
   this.isIE5up = (this.isIE && this.versionMajor >= 5);
   this.isIE6x = (this.isIE && this.versionMajor == 6);
   this.isIE6up = (this.isIE && this.versionMajor >= 6);
   
   this.isIE4xMac = (this.isIE4x && this.isMac);
}
var browser = new BrowserDetect();


//http://www.breakingpar.com/bkp/home.nsf/Doc?OpenNavigator&U=87256B14007C5C6A87256B4B0005BFA6
if (document.layers) { // Netscape
    document.captureEvents(Event.MOUSEMOVE);
    document.onmousemove = captureMousePosition;
} else if (document.all) { // Internet Explorer
    document.onmousemove = captureMousePosition;
} else if (document.getElementById) { // Netcsape 6
    document.onmousemove = captureMousePosition;
}
// Global variables
xMousePos = 0; // Horizontal position of the mouse on the screen
yMousePos = 0; // Vertical position of the mouse on the screen
xMousePosMax = 0; // Width of the page
yMousePosMax = 0; // Height of the page

function captureMousePosition(e) {
    if (document.layers) {
        // When the page scrolls in Netscape, the event's mouse position
        // reflects the absolute position on the screen. innerHight/Width
        // is the position from the top/left of the screen that the user is
        // looking at. pageX/YOffset is the amount that the user has
        // scrolled into the page. So the values will be in relation to
        // each other as the total offsets into the page, no matter if
        // the user has scrolled or not.
        xMousePos = e.pageX;
        yMousePos = e.pageY;
        xMousePosMax = window.innerWidth+window.pageXOffset;
        yMousePosMax = window.innerHeight+window.pageYOffset;
    } else if (document.all) {
        // When the page scrolls in IE, the event's mouse position
        // reflects the position from the top/left of the screen the
        // user is looking at. scrollLeft/Top is the amount the user
        // has scrolled into the page. clientWidth/Height is the height/
        // width of the current page the user is looking at. So, to be
        // consistent with Netscape (above), add the scroll offsets to
        // both so we end up with an absolute value on the page, no
        // matter if the user has scrolled or not.
        if ( window.event ) {
          xMousePos = window.event.clientX+document.body.scrollLeft; //altered to use clientX instead of x
          yMousePos = window.event.clientY+document.body.scrollTop;
        }
        xMousePosMax = document.body.clientWidth+document.body.scrollLeft;
        yMousePosMax = document.body.clientHeight+document.body.scrollTop;
    } else if (document.getElementById) {
        // Netscape 6 behaves the same as Netscape 4 in this regard
        xMousePos = e.pageX;
        yMousePos = e.pageY;
        xMousePosMax = window.innerWidth+window.pageXOffset;
        yMousePosMax = window.innerHeight+window.pageYOffset;
    }
}
  













  var pulseArray = new Array();
  var bounceArray = new Array();
  var bounceDir = new Array();
  var bounceHeight = 10;
function startPulse(obj2) {
  if ( !pulseArray[hashObj(obj2)] ) {
    pulseArray[hashObj(obj2)] = true;
    pulser(obj2);
    return true;
  }
  return false;
}
function pulser(obj) {
  if ( pulseArray[hashObj(obj)] == true ) {
    if ( getOpacity(obj) > 0.5 ) {
      queue(obj,'fadeElement',function(){fadeElement(obj,0);});
    }
    else {
      queue(obj,'fadeElement',function(){fadeElement(obj,1);});
    }
    queue(obj,'fadeElement',function(){pulser(obj);});
  }
  if ( !inUse(obj,'fadeElement') ) {
    runQueue(obj,'fadeElement');
  }
}
function stopPulse(obj) {
  pulseArray[hashObj(obj)] = null;
  queue(obj,'fadeElement',function(){ fadeElement(obj,1);});
  if ( !inUse(obj,'fadeElement') ) {
    runQueue(obj,'fadeElement');
  }
}

function startBounce(obj2) {
  if ( !bounceArray[hashObj(obj2)] ) {
    bounceArray[hashObj(obj2)] = true;
    bounceDir[hashObj(obj2)] = -1;
    bouncer(obj2);
    return true;
  }
  return false;
}
function bouncer(obj) {
  if ( bounceArray[hashObj(obj)] == true ) {
    if ( bounceDir[hashObj(obj)] > 0 ) {
      queue(obj,'offsetElement',function(){offsetElement(obj,0,-1*bounceDir[hashObj(obj)]*bounceHeight,'200ms',0);});
      bounceDir[hashObj(obj)] *= -1;
    }
    else {
      queue(obj,'offsetElement',function(){offsetElement(obj,0,-1*bounceDir[hashObj(obj)]*bounceHeight,'200ms',0);});
      bounceDir[hashObj(obj)] *= -1;
    }
    queue(obj,'offsetElement',function(){bouncer(obj);});
  }
  if ( !inUse(obj,'offsetElement') ) {
    runQueue(obj,'offsetElement');
  }
}
function stopBounce(obj) {
  bounceArray[hashObj(obj)] = null;
  if ( bounceDir[hashObj(obj)] > 0 ) {
    queue(obj,'offsetElement',function(){offsetElement(obj,0,bounceHeight,'200ms',0);});
    if ( !inUse(obj,'offsetElement') ) {
      runQueue(obj,'offsetElement');
    }
  }
}
// Richard Chen  rcmailbox2003@netscape.net