var ImageResize = Class.create({//{{{
  initialize:function(imgobj,dest) {//{{{
    this.imgObj = $(imgobj);
    this.destObj = $(dest);
    this.imgRect = null;

    this.scale = 1;
    this.aspect = 1;
  },//}}}
  show:function() {//{{{
    var size = this.imgObj.getDimensions();
    while(size.width>640 || size.height>640) {
      size.width = Math.ceil(size.width / 2);
      size.height = Math.ceil(size.height / 2);
      this.scale = this.scale * 2;
    }
    this.imgObj.style.width = size.width + "px";
    this.imgObj.style.height = size.height + "px";

    var rect = new Rectangle();
    rect.x = this.imgObj.cumulativeOffset().left;
    rect.y = this.imgObj.cumulativeOffset().top;
    rect.w = this.imgObj.getDimensions().width;
    rect.h = this.imgObj.getDimensions().height;
    this.imgRect = new ImageRect(rect,this.aspect,this.move.bind(this));
  },//}}}
  move:function(rect) {//{{{
    rect.multiply(this.scale);
    rect.round();
    this.destObj.value = rect.x+","+rect.y+","+rect.w+","+rect.h;
  }//}}}
});//}}}
var ImageRect = Class.create({//{{{
  initialize:function(bounds,aspect,callback) {//{{{
    this.bounds = bounds;
    this.aspect = aspect;
    this.callback = callback;

    this.currObj = null;
    this.rect = new Rectangle();
    this.rect.x = bounds.x + 0.1 * bounds.w;
    this.rect.y = bounds.y + 0.1 * bounds.h;
    this.rect.w = 0.8 * bounds.w;
    this.rect.h = 0.8 * bounds.h;

    this.rootObj = new Element('div');
    this.rootObj.style.zIndex = 5;
    this.rootObj.style.background = '#0000aa';
    this.rootObj.setOpacity(0.3);
    this.rootObj.style.position = 'absolute';
    document.body.appendChild(this.rootObj);

    this.aspectObj = new Element('div');
    this.aspectObj.style.zIndex = 6;
    this.aspectObj.style.background = '#0000aa';
    this.aspectObj.setOpacity(0.3);
    this.aspectObj.style.position = 'absolute';
    document.body.appendChild(this.aspectObj);

    this.topleft = this.createAnchor();
    this.top = this.createAnchor();
    this.topright = this.createAnchor();
    this.left = this.createAnchor();
    this.right = this.createAnchor();
    this.bottomleft = this.createAnchor();
    this.bottom = this.createAnchor();
    this.bottomright = this.createAnchor();

    document.body.appendChild(this.topleft);
    document.body.appendChild(this.top);
    document.body.appendChild(this.topright);
    document.body.appendChild(this.left);
    document.body.appendChild(this.right);
    document.body.appendChild(this.bottomleft);
    document.body.appendChild(this.bottom);
    document.body.appendChild(this.bottomright);

    this.topleft.observe('mousedown',this.down.bind(this));
    this.top.observe('mousedown',this.down.bind(this));
    this.topright.observe('mousedown',this.down.bind(this));
    this.left.observe('mousedown',this.down.bind(this));
    this.right.observe('mousedown',this.down.bind(this));
    this.bottomleft.observe('mousedown',this.down.bind(this));
    this.bottom.observe('mousedown',this.down.bind(this));
    this.bottomright.observe('mousedown',this.down.bind(this));

    this.moveRect();
  },//}}}
  createAnchor:function(x,y) {//{{{
    var anchor = new Element('div');
    anchor.style.zIndex = 7;
    anchor.style.background = '#ffffff';
    anchor.style.border = '1px solid #0000aa';
    anchor.style.position = 'absolute';
    anchor.style.width = '8px';
    anchor.style.height = '8px';
    return anchor;
  },//}}}
  down:function(e) {//{{{
    this.currObj = e.findElement('div');
    Event.observe(document.body,'mousemove',this.move.bind(this));
    Event.observe(document.body,'mouseup',function(){Event.stopObserving(document.body);});
  },//}}}
  move:function(e) {//{{{
    switch(this.currObj) {
      case this.topleft://{{{
	this.rect.setLeft(e.pointerX());
	this.rect.setTop(e.pointerY());
	break;//}}}
      case this.top://{{{
	this.rect.setTop(e.pointerY());
	break;//}}}
      case this.topright://{{{
	this.rect.setRight(e.pointerX());
	this.rect.setTop(e.pointerY());
	break;//}}}
      case this.left://{{{
	this.rect.setLeft(e.pointerX());
	break;//}}}
      case this.right://{{{
	this.rect.setRight(e.pointerX());
	break;//}}}
      case this.bottomleft://{{{
	this.rect.setLeft(e.pointerX());
	this.rect.setBottom(e.pointerY());
	break;//}}}
      case this.bottom://{{{
	this.rect.setBottom(e.pointerY());
	break;//}}}
      case this.bottomright://{{{
	this.rect.setRight(e.pointerX());
	this.rect.setBottom(e.pointerY());
	break;//}}}
      default://{{{
	break;//}}}
    }
    this.moveRect();
  },//}}}
  moveRect:function() {//{{{
    this.rect.inBounds(this.bounds);
    // Move main rectangle//{{{
    this.rootObj.style.width = this.rect.w + 'px';
    this.rootObj.style.height = this.rect.h + 'px';
    this.rootObj.style.left = this.rect.x + 'px';
    this.rootObj.style.top = this.rect.y + 'px';
//}}}
    // Move cutout rect//{{{
    var cutRect = new Rectangle();
    cutRect.x = this.rect.x;
    cutRect.y = this.rect.y;
    cutRect.w = this.rect.w;
    cutRect.h = this.rect.w / this.aspect;
    if(cutRect.h > this.rect.h) {
      cutRect.h = this.rect.h;
      cutRect.w = this.rect.h * this.aspect;
    }
    cutRect.x = cutRect.x + (this.rect.w-cutRect.w)/2;
    cutRect.y = cutRect.y + (this.rect.h-cutRect.h)/2;
    this.aspectObj.style.width = cutRect.w + 'px';
    this.aspectObj.style.height = cutRect.h + 'px';
    this.aspectObj.style.left = cutRect.x + 'px';
    this.aspectObj.style.top = cutRect.y + 'px';
//}}}
    // Move anchors//{{{
    this.moveAnchor(this.topleft,this.rect.x,this.rect.y);
    this.moveAnchor(this.top,this.rect.getXMid(),this.rect.y);
    this.moveAnchor(this.topright,this.rect.getXFar(),this.rect.y);
    this.moveAnchor(this.left,this.rect.x,this.rect.getYMid());
    this.moveAnchor(this.right,this.rect.getXFar(),this.rect.getYMid());
    this.moveAnchor(this.bottomleft,this.rect.x,this.rect.getYFar());
    this.moveAnchor(this.bottom,this.rect.getXMid(),this.rect.getYFar());
    this.moveAnchor(this.bottomright,this.rect.getXFar(),this.rect.getYFar());
//}}}
    // Strip offsets from cutRect, callback//{{{
    cutRect.x = cutRect.x - this.bounds.x;
    cutRect.y = cutRect.y - this.bounds.y;
    this.callback(cutRect);//}}}
  },//}}}
  moveAnchor:function(obj,x,y) {//{{{
    obj.style.left = (x-4)+'px';
    obj.style.top = (y-4)+'px';
  }//}}}
});//}}}

