var Region = Class.create();
Region.prototype = {
  initialize: function() {
    this.reset();
  },

  reset: function () {
    this.x1 = this.x2 = this.y1 = this.y2 = 0;
  },

  height: function() {
    return Math.abs(this.y2-this.y1);
  },

  width: function() {
    return Math.abs(this.x2-this.x1);
  },

  left: function() {    
    return Math.min(this.x1, this.x2);
  },

  right: function() {
    return Math.max(this.x1, this.x2);
  },

  top: function() {
    return Math.min(this.y1, this.y2);
  },

  bottom: function() {
    return Math.max(this.y1, this.y2);
  },

  toString: function() {
    return '[' + this.left() + ',' + this.right() + ']';
  }

}

var SelectRegion = Class.create();
SelectRegion.prototype = {
  initialize: function(element) {
    this.region = new Region;
    this.drawing = false;

    this.container = $(element);

    this.eventMouseDown = this.start.bindAsEventListener(this);
    this.eventMouseUp   = this.stop.bindAsEventListener(this);
    this.eventMouseMove = this.drag.bindAsEventListener(this);

    var options = Object.extend({
      selectionClass: 'selected_region',
      resolution: '5',
      onDrag: function() {},
      onComplete: function() {alert('provide "onComplete" for this to do something');}
    }, arguments[1] || {});

    Object.extend(this, options);

    this.selection = Builder.node('div', {id:'selection',
                                          style: 'position:absolute; overflow:none; left:15px; top:15px; width: 95%; height: 100%; clip: rect(0 0 0 0); visibility:visiblefilter:alpha(opacity=50); -moz-opacity:0.5; -khtml-opacity:0.5; opacity:0.5; background-color: gray'
                                         });

    this.selectionSensitiveZone = Builder.node('div', {id:'selectionSensitiveZone',
                                                      style: 'position:absolute; overflow:none; left:15px; top:15px; width: 95%; height: 100%; visibility:visible; cursor:crosshair; background:blue; filter:alpha(opacity=0); -moz-opacity:0; -khtml-opacity:0; opacity:0'
                                                      });
  },

  enable_zoom:function(enable) {
    if(enable) {
      this.container.appendChild(this.selection);
      this.container.appendChild(this.selectionSensitiveZone);
      Event.observe(this.container, 'mousedown', this.eventMouseDown);
    } else {
      this.container.removeChild(this.selection)
      this.container.removeChild(this.selectionSensitiveZone)
      Event.stopObserving(this.container, 'mousedown', this.eventMouseDown);
    }
  },

  start: function(event) {
    var offset = Position.cumulativeOffset(this.container);
    //NOTE: offset Y matches the top offset above, the left offset evens out b/c of the margin in #dna_strand
    this.offset = [offset[0], offset[1]+15];
    Event.observe(this.container, 'mousemove', this.eventMouseMove);
    Event.observe(this.container, 'mouseup',   this.eventMouseUp);
    this.drawing = true;
    this.region.reset();
    this.region.x1 = Event.pointerX(event);
    this.region.y1 = Event.pointerY(event);
  },

  drag: function(event) {    
    if(!this.drawing) return;
    if(this.region.x2 && Math.abs(Event.pointerX(event) - this.region.x2) < this.resolution) return;
    this.region.x2 = Event.pointerX(event);
    this.region.y2 = Event.pointerY(event);
    this._lastX = this.region.x2;
    this.draw();
  },
  
  stop: function(event) {
    Event.stopObserving(this.container, 'mousemove', this.eventMouseMove);
    Event.stopObserving(this.container, 'mouseup',   this.eventMouseUp);
    //NOTE: no drag means x2 and y2 won't be set correctly
    this.region.x2 = Event.pointerX(event);
    this.region.y2 = Event.pointerY(event);
    this.drawing = false;
    this.selection.style.clip ="rect(0 0 0 0)";

    //NOTE: make sure it just wasn't a wayword click -- maybe check that it is in the region too
    if((this.region.height()) > 15)
    {
      this.onComplete(this.region);
    }        
    this.region.reset();
  },

  draw: function()
  {
    if(!this.drawing) return;
    var top = this.region.top()-this.offset[1] + 'px'
    var right =  (this.region.left()-this.offset[0]) + (this.region.width()) + 'px'
    var bottom = (this.region.top()-this.offset[1]) + (this.region.height()) + 'px'
    var left =  this.region.left()-this.offset[0] + 'px';
    this.selection.style.clip ="rect(" + top + " " + right + " " + bottom + " " + left + ")";
  }
}
