// Global variables
var dBox_Debug=false;

var dBox_BusyMessage='fetching map...';
var dBox_NotBusyMessage='';

//
// Object constructor
//
function dBox(name) {
  if(dBox_Debug) alert("Constructing dBox named '"+ name +"'.");

  this.name = name; 
  
  // some reasonable defaults  
  this.color = 'red';
  this.thickness = 2;

  this.width = 0;
  this.height = 0;

  this.box = true;
  this.verbose = false;

  this.canvas = null; // DHTML elements
  this.anchor = null;  
  this.left = this.right = this.top = this.bottom = null;

  this.cursor= 'crosshair';
  this.jitter = 10;

  this.x1 = this.y1 = this.x2 = this.y2 = -1;
  this.offsetx = this.offsety = 0;
  this.drag = false;

  this.waiting = false; // are we waiting for a new image?
}

//
// Object prototypes
//

function dBox_initialize() {
  // anchor *must* exist as a IMG in the document
  this.anchor = window.xGetElementById(this.name);
  this.anchor.parentObject = this;
  this.anchor.onload = dBox_onload;

  this.width = xWidth(this.anchor);
  this.height = xHeight(this.anchor);
 
  // create the canvas for the box sides
  this.canvas = document.createElement('div');

  // set some properties
  this.canvas.style.position = 'absolute';  
  this.canvas.id = this.name + "_canvas";
  this.canvas.parentObject = this;    
  // xBackground(this.canvas, 'red');
  document.body.appendChild(this.canvas);

  xResizeTo(this.canvas, this.width, this.height);
  xMoveTo(this.canvas, xPageX(this.anchor), xPageY(this.anchor));
  xShow(this.canvas);

  this.offsetx = xLeft(this.canvas);
  this.offsety = xTop(this.canvas);

  this.left = document.createElement('div');
  this.left.style.position = 'absolute';
  this.left.id = this.name + "_left";
  this.left.parentObject = this;
  xBackground(this.left, this.color);
  this.canvas.appendChild(this.left);

  this.right = document.createElement('div');
  this.right.style.position = 'absolute';
  this.right.id = this.name + "_right";
  this.right.parentObject = this;
  xBackground(this.right, this.color);
  this.canvas.appendChild(this.right);

  this.top = document.createElement('div');
  this.top.style.position = 'absolute';
  this.top.id = this.name + "_top";
  this.top.parentObject = this;
  xBackground(this.top, this.color);
  this.canvas.appendChild(this.top);

  this.bottom = document.createElement('div');
  this.bottom.style.position = 'absolute';
  this.bottom.id = this.name + "_bottom";
  this.bottom.parentObject = this;
  xBackground(this.bottom, this.color);
  this.canvas.appendChild(this.bottom);
 
  if(xIE4Up && !xMac) {
    xAddEventListener(this.anchor, 'mousedown', dBox_mousedown, true);
    xAddEventListener(this.anchor, 'mousemove', dBox_mousemove, true);
    xAddEventListener(this.anchor, 'mouseup', dBox_mouseup, true);
    xAddEventListener(this.anchor, 'mouseover', dBox_mouseenter, true);
    xAddEventListener(this.anchor, 'mouseout', dBox_mouseexit, true);
    xEnableDrag(this.anchor, dBox_drag, dBox_drag, dBox_drag);
  } else {
    xAddEventListener(this.canvas, 'mousedown', dBox_mousedown, true);
    xAddEventListener(this.canvas, 'mousemove', dBox_mousemove, true);
    xAddEventListener(this.canvas, 'mouseup', dBox_mouseup, true);
    xAddEventListener(this.canvas, 'mouseover', dBox_mouseenter, true);
    xAddEventListener(this.canvas, 'mouseout', dBox_mouseexit, true);
    xEnableDrag(this.canvas, dBox_drag, dBox_drag, dBox_drag);
  }

}

function dBox_sync() {
  xMoveTo(this.canvas, xPageX(this.anchor), xPageY(this.anchor));
  this.offsetx = xLeft(this.canvas);
  this.offsety = xTop(this.canvas);
}

function dBox_boxon() {
  this.box = true;
}

function dBox_boxoff() {
  this.box = false;
  this.x1 = this.x2; 
  this.y1 = this.y2;
  this.paint();

  // user SHOULD provide this handler
  if(window.reset_handler) reset_handler(this.name, Math.min(this.x1, this.x2)-this.offsetx, Math.min(this.y1, this.y2)-this.offsety, Math.max(this.x1, this.x2)-this.offsetx, Math.max(this.y1, this.y2)-this.offsety);
}

function dBox_lineoff() {
  return; // not implemented yet
}

function dBox_lineon() {
  return; // not implemented yet
}

function dBox_reset() {
  window.status = dBox_NotBusyMessage;

  this.x1 = this.x2 = (this.width - 1)/2 + this.offsetx; // center of image
  this.y1 = this.y2 = (this.height - 1)/2 + this.offsety;

  // user SHOULD provide this handler
  if(window.reset_handler) reset_handler(this.name, this.x1, this.y1, this.x1, this.y1);

  this.sync();
  this.paint();
  this.waiting = false;
}

function dBox_setimage(url) {
  this.waiting = true;
  window.status = dBox_BusyMessage;

  this.anchor.src = url;

  // netscape 6 doesn't invoke the onload method each time (dammit) so we call it manually here
  // if(is.nav6) this.onload();
}

function dBox_paint() {    
  var x, y, w, h;

  if(this.x1==this.x2 && this.y1==this.y2) {    
    xHide(this.left); // defer to the browser cursor
    xHide(this.top);
    xHide(this.right);
    xHide(this.bottom);    
  } else {
    w = Math.abs(this.x1-this.x2) + this.thickness;
    h = Math.abs(this.y1-this.y2) + this.thickness;
    x = Math.min(this.x1, this.x2) - this.offsetx; // UL corner of box
    y = Math.min(this.y1, this.y2) - this.offsety;

    if(dBox_Debug) window.status = "h:" + h + " w:" + w + " x:" + x + " y:" + y;

    // resize
    xResizeTo(this.left,this.thickness,h);
    xResizeTo(this.right,this.thickness,h+this.thickness);
    xResizeTo(this.top,w,this.thickness);
    xResizeTo(this.bottom,w+this.thickness,this.thickness);
   
    // move
    xMoveTo(this.left, x, y);  
    xMoveTo(this.right, x+w, y);  
    xMoveTo(this.top, x, y);  
    xMoveTo(this.bottom, x, y+h);  

    // clip
    xClip(this.left, 0, this.thickness, h, 0);
    xClip(this.right, 0, this.thickness, h+this.thickness, 0);
    xClip(this.top, 0, w, this.thickness, 0);
    xClip(this.bottom, 0, w+this.thickness, this.thickness, 0);

    // show
    xShow(this.left);  
    xShow(this.right);
    xShow(this.top);  
    xShow(this.bottom);
  }
}

dBox.prototype.initialize = dBox_initialize;
dBox.prototype.sync = dBox_sync;
dBox.prototype.boxoff = dBox_boxoff;
dBox.prototype.boxon = dBox_boxon;
dBox.prototype.lineoff = dBox_lineoff;
dBox.prototype.lineon = dBox_lineon;
dBox.prototype.reset = dBox_reset;
dBox.prototype.setimage = dBox_setimage;
dBox.prototype.paint = dBox_paint;

//
// Event helper functions
//

function dBox_onload() {
  this.parentObject.reset();
}

function dBox_mousedown(event) {
  var e = new xEvent(event);  
  var t = e.target.parentObject;

  t.drag = true;
  t.x1 = t.x2 = e.pageX;
  t.y1 = t.y2 = e.pageY;
}

function dBox_mousemove(event) {
  var e = new xEvent(event);  
  var t = e.target.parentObject;

  t.anchor.style.cursor = t.canvas.style.cursor = t.cursor;

  var x = e.pageX;
  var y = e.pageY;  

  if(t.drag) {
    t.x2 = x;
    t.y2 = y;
    if(!t.box) {      
      t.x1 = t.x2;
      t.y1 = t.y2;
    }
    t.paint();
  }

  if(!t.waiting && t.verbose && window.mousemove_handler) mousemove_handler(t.name,x-t.offsetx,y-t.offsety);
}

function dBox_mouseup(event) {
  var e = new xEvent(event);
  var t = e.target.parentObject;
 
  t.drag = false;

  if(t.box) {
    t.x2 = e.pageX;
    t.y2 = e.pageY;
  
    if((Math.abs(t.x1-t.x2) <= t.jitter) || (Math.abs(t.y1-t.y2) <= t.jitter)) {
      t.x2 = t.x1;
      t.y2 = t.y1;
    }
  } else {
    t.x2 = t.x1;
    t.y2 = t.y1;
  }
  t.paint();

  // user MUST provide this handler
  if(window.setbox_handler) setbox_handler(t.name, Math.min(t.x1, t.x2)-t.offsetx, Math.min(t.y1, t.y2)-t.offsety, Math.max(t.x1, t.x2)-t.offsetx, Math.max(t.y1, t.y2)-t.offsety);
}

function dBox_mouseenter(event) {
  var e = new xEvent(event);
  var t = e.target.parentObject;

  t.anchor.style.cursor = t.canvas.style.cursor = t.cursor;

  if(t.verbose && window.mouseenter_handler) window.mouseenter_handler(t.name);
}

function dBox_mouseexit(event) {
  var e = new xEvent(event);
  var t = e.target.parentObject;

  t.anchor.style.cursor = t.canvas.style.cursor = "default";

  if(t.verbose && window.mouseexit_handler) window.mouseexit_handler(e.target.parentObject.name);
}

function dBox_drag(event) { 
  // do nothing
}

