// dynamic display object manager
// only use inside the <body> of a document
// copyright iBlocks 2002
// Julian George

//* OBJ DFN:ddObject * the core dynamic data object def with supporting fns 
//* [requires deployment inside a ddObjectArray]

function ddObject(window_in, id, mode) 
{ 
  this.iwindow=window_in?window_in:window;
  this.d=this.iwindow.document;
  this.id=id; 
  this.mode = mode?mode:'normal';

  // style entry for object (not silent)
  if (this.mode == 'normal') 
    this.d.writeln("#" + this.id + " {position:absolute;visibility:hidden;}"); // width:300;height:300;clip:rect(0,300,300,0);background-color:red; layer-background-color:red
}

ddObject.prototype.inst = function(){

  // create the generic properties for the ddObject element
  if (this.mode == 'normal'){  // not silent  
    this.d.writeln('<div id="' + this.id + '"></div>'); 
  }
  
/*  
  if (browser.dom) {
    alert(this.id + "=" +this.d.getElementById(this.id, this.iwindow.document)) ;
  }
*/  
  
  this.d_element = browser.dom?this.d.getElementById(this.id, this.iwindow.document):browser.ie4?this.d.all[this.id]:browser.ns4?eval("this.d.layers."+this.id):0;  
  this.css     = (browser.dom||broswer.ie4)?this.d_element.style:this.d_element; 
  this.ref     = browser.dom||browser.ie4?this.d:this.css.document;

  this.x=parseInt(this.css.left)||this.css.pixelLeft||this.d_element.offsetLeft||0;  
  this.y=parseInt(this.css.top)||this.css.pixelTop||this.d_element.offsetTop||0;  
  this.w=this.d_element.offsetWidth||this.ref.width||this.css.pixelWidth||0; 
  this.h=this.d_element.offsetHeight||this.ref.height||this.css.pixelHeight||0;
  eval(this.obj+"=this");    
}

// Update Methods 
ddObject.prototype.moveTo           = function(x,y) { this.x=x;this.y=y; this.css.left=x;this.css.top=y }
ddObject.prototype.moveBy           = function(x,y) { this.css.left=this.x+=x; this.css.top=this.y+=y }
ddObject.prototype.zIndex           = function(z)   { this.z=z; this.css.zIndex=z; }
ddObject.prototype.show             = function() { this.css.visibility="visible" } 
ddObject.prototype.hide             = function() { this.css.visibility="hidden" }
ddObject.prototype.getVisibility    = function() { return this.css.visibility; }
ddObject.prototype.setColor         = function(color) { if(browser.dom || browser.ie4) this.css.color=color; else if(brower.ns4) this.css.color=color; }
ddObject.prototype.setBgColor       = function(color) { if (browser.opera) this.css.background=color; else if(browser.dom || browser.ie4) this.css.backgroundColor=color; else if(brower.ns4) this.css.bgColor=color; }
ddObject.prototype.getBgColor       = function() { if (browser.opera) return this.css.background; else if(browser.dom || browser.ie4) return this.css.backgroundColor; else if(brower.ns4) return this.css.bgColor; }
ddObject.prototype.setBody          = function(str){ 
  if (this.d_element) {       
      //alert("Setting body: " + str);      
      this.d_element.innerHTML=str; 
  } 
}
ddObject.prototype.getBody          = function(str){ 
  if (this.d_element && this.d_element.innerHTML) { 
    return this.d_element.innerHTML; 
  } else { 
    return ""; 
  } 
}
ddObject.prototype.getDElement      = function(str){ if(browser.ns4){ return 0; } else return this.d_element; }
ddObject.prototype.slide            = function(endx,endy,inc,speed,fn){ if(!this.slideactive){ distx = endx - this.x; disty = endy - this.y; num=Math.sqrt(Math.pow(distx,2)+Math.pow(disty,2))/inc;dx = distx/num; dy = disty/num;this.slideactive = 1; if(!fn) fn=0; this.slideFn(dx,dy,endx,endy,speed,fn);}}
ddObject.prototype.slideFn          = function(dx,dy,endx,endy,speed,fn) { if(this.slideactive&&(Math.floor(Math.abs(dx))<Math.floor(Math.abs(endx-this.x))||Math.floor(Math.abs(dy))<Math.floor(Math.abs(endy-this.y)))){ this.moveBy(dx,dy); this.obj = this.id + "Object"; eval(this.obj + "=this"); setTimeout(this.obj+".slideFn("+dx+","+dy+","+endx+","+endy+","+speed+",'"+fn+"')",speed) }else{ this.slideactive = 0; this.moveTo(endx,endy); if(fn) eval(fn);}}
ddObject.prototype.getHeight        = function() { return this.d_element.offsetHeight||this.ref.height||this.css.pixelHeight||0 ;}
ddObject.prototype.getWidth         = function() { return this.d_element.offsetWidth||this.ref.width||this.css.pixelWidth||0; }


//Drag drop functions start *******************
dd_is_active=0; dd_obj=0; dd_mobj=0


ddObject.prototype.dragdrop = function(obj){

  this.p_onmousemove=this.d.onmousemove;
  this.p_onmousedown=this.d.onmousedown;
  this.p_onmouseup=this.d.onmouseup;
  
  this.addEventHandler("onmousedown", 
   function(d,t,ex,ey)
   {
     if(dd_mobj){ 
     dd_obj=dd_mobj;
     dd_obj.clX=ex-dd_obj.x;
     dd_obj.clY=ey-dd_obj.y;
   }
   }
  );
  this.addEventHandler("onmousemove", 
   function(d,t,ex,ey)
   {   
     dd_mobj=d;
   if(dd_obj){
     nx=ex-dd_obj.clX; 
     ny=ey-dd_obj.clY; 
     
     if(dd_obj.ddobj) 
       dd_obj.ddobj.moveTo(nx,ny); 
     else      
       dd_obj.moveTo(nx,ny); 
   } 
   if(!browser.ns4) return false;
   }
  );
  this.addEventHandler("onmouseout",  function(d){dd_mobj=0;});  
  this.addEventHandler("onmouseover", function(d){dd_mobj=d;d.d.onmousemove=d.d_element.onmousemove;d.d.onmousedown=d.d_element.onmousedown;d.d.onmouseup=d.d_element.onmouseup; });   
  this.addEventHandler("onmouseup",   function(d){dd_obj=0;d.d.onmousemove=d.p_onmousemove;d.d.onmousedown=d.p_onmousedown;d.d.onmouseup=d.p_onmouseup;});

}
ddObject.prototype.nodragdrop = function(){

  this.addEventHandler("onmousemove", function(d,t,ex,ey){dd_obj=0;dd_mobj=0});
  this.addEventHandler("onmousedown", function(d){return 0});
  this.addEventHandler("onmouseover", function(d){return 0});
  this.addEventHandler("onmouseout",  function(d){return 0});
  this.addEventHandler("onmouseup",   function(d){return 0});
  
  dd_obj=0; dd_mobj=0
}
//Drag drop functions end *************

   
// event handlers
if (browser.ns4) { // ******* NN4+ ******

  ddObject.prototype.addEventHandler = function(eventname, handler) {
    var ddObject = this;
    this.d_element.captureEvents(ddObject._eventmasks[eventname]);      
    this.d_element[eventname] = function(event) { 
      return handler(ddObject, event.type, event.x, event.y, event.which, event.which,
                     ((event.modifiers & Event.SHIFT_MASK) != 0),
                     ((event.modifiers & Event.CTRL_MASK) != 0),
                     ((event.modifiers & Event.ALT_MASK) != 0));
    }
  }

  ddObject.prototype.removeEventHandler = function(eventname) {
     this.d_element.releaseEvents(ddObject._eventmasks[eventname]);
     delete this.d_element[eventname];
  }

  ddObject._eventmasks = {
        onabort:Event.ABORT, onblur:Event.BLUR, onchange:Event.CHANGE, onclick:Event.CLICK, ondblclick:Event.DBLCLICK, 
        ondragdrop:Event.DRAGDROP, onerror:Event.ERROR, onfocus:Event.FOCUS, onkeydown:Event.KEYDOWN, onkeypress:Event.KEYPRESS,
        onkeyup:Event.KEYUP, onload:Event.LOAD,onmousedown:Event.MOUSEDOWN, onmousemove:Event.MOUSEMOVE, onmouseout:Event.MOUSEOUT,
        onmouseover:Event.MOUSEOVER, onmouseup:Event.MOUSEUP, onmove:Event.MOVE, onreset:Event.RESET, onresize:Event.RESIZE, 
        onselect:Event.SELECT, onsubmit:Event.SUBMIT, onunload:Event.UNLOAD };    

  // now for drag-drop
  this.d.captureEvents(Event.MOUSEMOVE|Event.MOUSEDOWN|Event.MOUSEUP);
  
}  else if (browser.ns6) { // ******* NN6+ ********

    ddObject.prototype.addEventHandler = function(eventname, handler) {       
      var thisEvent = eventname.replace(/on/, '');  
    var ddObject = this;      
      this.d_element.addEventListener(thisEvent, this.d_element[eventname], false);           
    this.d_element[eventname] = function(e) {               
      e.cancelBubble = true;      
      return handler(ddObject, e.type, e.pageX, e.pageY, e.button, e.keyCode, e.shiftKey, e.ctrlKey, e.altKey);
    } 
  }

  ddObject.prototype.removeEventHandler = function(eventname) {
     var thisEvent = eventname.replace(/on/, '');
       this.d_element.removeEventListener(thisEvent, this.d_element[eventname], false);           
       delete this.d_element[eventname];
  }
} else { // ******* IE4+ ********

  ddObject.prototype.addEventHandler = function(eventname, handler) { 
    var ddObject = this;        
    this.d_element[eventname] = function() { 
       var e = ddObject.iwindow.event;
       e.cancelBubble = true;   
       return handler(ddObject, e.type, e.x, e.y, e.button, e.keyCode, e.shiftKey, e.ctrlKey, e.altKey); 
    }
  }

  ddObject.prototype.removeEventHandler = function(eventname) {         
     delete this.d_element[eventname];
  } 
     
}

//* END OBJ DFN: ddObject


//* OBJ DFN:ddObjectArray * array object to hold dynamic a group of dd objects



function ddObjectArray(array_size,window_in)
{
  this.WARNING = 'Error!\n\nObject limit exceeded.\n\nIf this problem occurs often, please report\nit to your technical support team.';
  this.SUPPORT = 'Error!\n\nSorry, your browser is not supported. Please use Netscape6, Opera3+ or Internet Explorer4+';
  if(!browser.sp) alert(this.SUPPORT);  

  this.iwindow = window_in?window_in:window;
  this.ddObjects_store = new FIFOStack(array_size, this.WARNING); 
    
 
  // output the style declairation and create the objects
  this.iwindow.document.writeln('<style type="text/css">');
  for(var i=0;i<array_size;i++) {       
    this.ddObjects_store.push('d' + i, new ddObject(this.iwindow, 'd' + i));      
  }
  this.iwindow.document.writeln('</style>');  

  for(var i=0;i<array_size;i++) {       
    this.ddObjects_store.peak(i).inst();      
  }
  

  //this,iwindow.onerror = this.report_error;

}


ddObjectArray.prototype.report_error = function()
{
 alert('error within get_ddObject - sorry!'); 
 return true;
}

ddObjectArray.prototype.get_ddObject = function()
{  
  return this.ddObjects_store.pop();  ;
}

ddObjectArray.prototype.return_ddObject = function(ddObj_in)
{    
  if (!this.ddObjects_store.search(ddObj_in.id)) {
    ddObj_in.setBody('');ddObj_in.hide();ddObj_in.moveTo(0,0); 
    this.ddObjects_store.push(ddObj_in.id, ddObj_in);
    return null;  
  } else {
    alert("Error: tried to return an object that already exists in the object store");
  }
}

// * END OBJ DFN:ddObjectArray
