entity = new Array();

function setPropertyById(id, property, value) {
  x = document.getElementById(id);
  x.style[property] = value;
}
function hideById(id) { setPropertyById(id, 'visibility', 'hidden'); }
function showById(id) { setPropertyById(id, 'visibility', 'visible'); }

function getScreenWidth() {
  if(document.all) return document.body.clientWidth;
  else return innerWidth;
}
function getScreenHeight() {
  if(document.all) return document.body.clientHeight;
  else return innerHeight;
}

function setZ(z) { this.entity.style.zIndex = z; }
function nsSetZ(z) { this.style.zIndex = z; }

function getTop() { return parseInt(this.style.top); }
function nsGetTop() { return this.style.top; }
function setTop(v) { this.style.top = v + "px"; }
function nsSetTop(v) { this.style.top = v; }

function getLeft() { return parseInt(this.style.left); }
function nsGetLeft() { return this.style.left; }
function setLeft(v) { this.style.left = v + "px"; }
function nsSetLeft(v) { this.style.left = v; }

function decodeClip() {
  v = this.style.clip.split("rect(")[1].split(")")[0].split("px");
  this.clipWidth = v[1];  
  this.clipHeight = v[2];  
}
function encodeClip() {
  this.style.clip = "rect(0px " + this.clipWidth + "px " + this.clipHeight + "px 0px)";
}

function getWidth() { return this.clipWidth; }
function nsGetWidth() { return this.entity.clip.width; }
function setWidth(v) { this.style.width = this.clipWidth = v; this.encodeClip(); }
function nsSetWidth(v) {
  this.entity.clip.width = v;
  if(document.width < this.getRight()) document.width = this.getRight(); //fixme: only needed for top-level layers
}

function getHeight() { return this.clipHeight; }
function nsGetHeight() { return this.entity.clip.height; }
function setHeight(v) { this.style.height = this.clipHeight = v; this.encodeClip(); }
function nsSetHeight(v) {
  this.entity.clip.height = v;
  if(document.height < this.getBottom()) document.height = this.getBottom()+4; //fixme: only needed for top-level layers
}

function setArea(w, h) { this.style.width = this.clipWidth = w; this.style.height = this.clipHeight = h; this.encodeClip(); }
function nsSetArea(w, h) { this.setWidth(w); this.setHeight(h); }

function getContentWidth() { return parseInt(document.defaultView.getComputedStyle(this.entity, "").getPropertyValue("width")); }
function ieGetContentWidth() { return this.entity.offsetWidth; }
function nsGetContentWidth() { return this.entity.document.width; }
function getContentHeight() { return parseInt(document.defaultView.getComputedStyle(this.entity, "").getPropertyValue("height")); }
function ieGetContentHeight() { return this.entity.offsetHeight; }
function nsGetContentHeight() { return this.entity.document.height; }

function getBottom() { return this.getTop() + this.getHeight(); }
function getRight() { return this.getLeft() + this.getWidth(); }
function setBottom(v) { this.setTop(v - this.getHeight()); }
function setRight(v) { this.setTop(v - this.getWidth()); }

function moveTo(x, y) { this.setLeft(x); this.setTop(y); }

function setBgImage(i) {
  var agent = navigator.userAgent.toLowerCase();
  if(agent.indexOf('mac')==-1) this.style.backgroundImage = "url('"+i+"')";
}
function nsSetBgImage(i) { this.entity.background.src = i; }

//function eSetClass(c) { this.class = c; }
function eShow(c) { this.style.visibility = "inherit"; }
function eHide(c) { this.style.visibility = "hidden"; }
function eDisplayOn(c) { this.style.display = "block"; }
function eDisplayOff(c) { this.style.display = "none"; }
function eMoveBy(x, y) {
  this.style.left = parseInt(this.style.left)+y;
  this.style.top = parseInt(this.style.top)+y;
}

function nsSetEventEntity(e) { nsEventEntity = entity[e.target.name]; }
function nsClearEventEntity() { nsEventEntity = null; }
function nsHandleMouseDown(e) { if(nsEventEntity) nsEventEntity.handleMouseDown(e.screenX, e.screenY); }
function nsHandleMouseUp(e) { if(nsEventEntity) nsEventEntity.handleMouseUp(e.screenX, e.screenY); }
function nsHandleMouseMove(e) { if(nsEventEntity) nsEventEntity.handleMouseMove(e.screenX, e.screenY); }
function onMouseDown(f) {
  this.handleMouseDown = f;
  this.entity.onmousedown = new Function("ev", "e = ev||window.event; entity."+this.entity.id+".handleMouseDown(e.clientX, e.clientY)");
}
function nsOnMouseDown(f) {
  this.handleMouseDown = f;
  this.entity.onmouseover = nsSetEventEntity;
  this.entity.onmouseout = nsClearEventEntity;
  document.onmousedown = nsHandleMouseDown;
  document.captureEvents(Event.MOUSEDOWN);
}
function onMouseUp(f) {
  this.handleMouseUp = f;
  this.entity.onmouseup = new Function("ev", "e = ev||window.event; entity."+this.entity.id+".handleMouseUp(e.clientX, e.clientY)");
}
function nsOnMouseUp(f) {
  this.handleMouseUp = f;
  this.entity.onmouseover = nsSetEventEntity;
  this.entity.onmouseout = nsClearEventEntity;
  document.onmouseup = nsHandleMouseUp;
  document.captureEvents(Event.MOUSEUP);
}
function onMouseMove(f) {
  this.handleMouseMove = f;
  if(f) this.entity.onmousemove = new Function("ev", "e = ev||window.event; entity."+this.entity.id+".handleMouseMove(e.clientX, e.clientY)");
  else this.entity.onmousemove = null;
}
function nsOnMouseMove(f) {
  this.handleMouseMove = f;
  if(f) {
    this.entity.onmouseover = nsSetEventEntity;
    this.entity.onmouseout = nsClearEventEntity;
    this.entity.document.onmousemove = nsHandleMouseMove;
    this.entity.document.captureEvents(Event.MOUSEMOVE);
  }
  else this.entity.document.releaseEvents(Event.MOUSEMOVE);
}
function globalDrag(x, y) {
  globalDragTarget.setLeft(globalDragTarget.getLeft() + x - globalDragX);
  globalDragTarget.setTop(globalDragTarget.getTop() + y - globalDragY);
  globalDragX = x;
  globalDragY = y;
}
function dragStart(x, y) {
  globalDragTarget = this.dragTarget;
  globalDragX = x;
  globalDragY = y;
  globalOnMouseMove(globalDrag);
  globalOnMouseUp(globalDragEnd);
}
function globalDragEnd() {
  globalOnMouseMove(null);
  globalOnMouseUp(null);
}
function enableDrag(target) {
  this.dragTarget = target || this;
  this.dragTarget.findComputedPosition();
  this.onMouseDown(this.dragStart);
}
function globalOnMouseMove(f) {
  globalHandleMouseMove = f;
  if(document.layers) {
    if(f) document.onmousemove = new Function("e", "globalHandleMouseMove(e.screenX, e.screenY)");
    if(f) document.captureEvents(Event.MOUSEMOVE);
    else document.releaseEvents(Event.MOUSEMOVE);
  }
  else {
    if(f) document.onmousemove = new Function("ev", "e = ev||window.event; globalHandleMouseMove(e.clientX, e.clientY)");
    else document.onmousemove = null;
  }
}
function globalOnMouseUp(f) {
  globalHandleMouseUp = f;
  if(document.layers) {
    if(f) document.onmouseup = new Function("e", "globalHandleMouseUp(e.screenX, e.screenY)");
    if(f) document.captureEvents(Event.MOUSEUP);
    else document.releaseEvents(Event.MOUSEUP);
  }
  else {
    if(f) document.onmouseup = new Function("ev", "e = ev||window.event; globalHandleMouseUp(e.clientX, e.clientY)");
    else document.onmouseup = null;
  }
}

function nsFindComputedPosition() {}
function ieFindComputedPosition() {
  this.setLeft(parseInt(this.entity.currentStyle.left));
  this.setTop(parseInt(this.entity.currentStyle.top));
}
function findComputedPosition() {
  v = document.defaultView.getComputedStyle(this.entity, "");
  this.setLeft(parseInt(v.getPropertyValue("left")));
  this.setTop(parseInt(v.getPropertyValue("top")));
}

function baseEntity(obj) {
  this.entity = obj;
  if(document.layers) this.style = obj;
  else this.style = obj.style;
  if(document.layers) {
    this.getTop = nsGetTop;
    this.getLeft = nsGetLeft;
    this.setTop = nsSetTop;
    this.setLeft = nsSetLeft;
    this.getWidth = nsGetWidth;
    this.getHeight = nsGetHeight;
    this.setWidth = nsSetWidth;
    this.setHeight = nsSetHeight;
    this.setArea = nsSetArea;
    this.setBgImage = nsSetBgImage;
    this.setZ = nsSetZ;
    this.onMouseDown = nsOnMouseDown;
    this.onMouseUp = nsOnMouseUp;
    this.onMouseMove = nsOnMouseMove;
  }
  else {
    this.getTop = getTop;
    this.getLeft = getLeft;
    this.setTop = setTop;
    this.setLeft = setLeft;
    this.getWidth = getWidth;
    this.getHeight = getHeight;
    this.setWidth = setWidth;
    this.setHeight = setHeight;
    this.setArea = setArea;
    this.encodeClip = encodeClip;
    this.decodeClip = decodeClip;
    this.setBgImage = setBgImage;
    this.setZ = setZ;
    this.onMouseDown = onMouseDown;
    this.onMouseUp = onMouseUp;
    this.onMouseMove = onMouseMove;
  }
  if(document.layers) {
    this.getContentWidth = nsGetContentWidth;
    this.getContentHeight = nsGetContentHeight;
    this.findComputedPosition = nsFindComputedPosition;
  }
  else if(document.all) {
    this.getContentWidth = ieGetContentWidth;
    this.getContentHeight = ieGetContentHeight;
    this.findComputedPosition = ieFindComputedPosition;
  }
  else {
    this.getContentWidth = getContentWidth;
    this.getContentHeight = getContentHeight;
    this.findComputedPosition = findComputedPosition;
  }

  this.enableDrag = enableDrag;
  this.dragStart = dragStart;

  this.getBottom = getBottom;
  this.getRight = getRight;
  this.setBottom = setBottom;
  this.setRight = setRight;

  this.moveTo = moveTo;

  this.displayOn = eDisplayOn;
  this.displayOff = eDisplayOff;

  this.show = eShow;
  this.hide = eHide;
  this.moveBy = eMoveBy;

  if(document.layers) this.handler = new Array();
  else {
    this.setWidth(this.getContentWidth());
    this.setHeight(this.getContentHeight());
  }
}

function setupEntities() {
  if(document.layers) {
    dAll = new Array();
    for(i=0; i<document.layers.length; i++) dAll[i] = document.layers[i];
    while(dAll.length > 0) {
      temp = dAll.shift();
      entity[temp.name] = new baseEntity(temp);
      for(i=0; i<temp.document.layers.length; i++) dAll.push(temp.document.layers[i]);
    }
  }
  else if(document.getElementsByTagName) {
    dAll = document.getElementsByTagName("div");
    for(i=0; i < dAll.length; i++) entity[dAll[i].id] = new baseEntity(dAll[i]);
  }
  else if(document.all) {
    dAll = document.all.tags("div");
    for(i=0; i < dAll.length; i++) entity[dAll[i].id] = new baseEntity(dAll[i]);
  }
}
