var Drag=new Class({Implements:[Events,Options],options:{snap:6,unit:"px",grid:false,style:true,limit:false,handle:false,invert:false,preventDefault:false,stopPropagation:false,modifiers:{x:"left",y:"top"}},initialize:function(){var params=Array.link(arguments,{options:Type.isObject,element:function(obj){return obj!=null}});this.element=document.id(params.element);this.document=this.element.getDocument();this.setOptions(params.options||{});var htype=typeOf(this.options.handle);this.handles=((htype=="array"||htype=="collection")?$$(this.options.handle):document.id(this.options.handle))||this.element;this.mouse={now:{},pos:{}};this.value={start:{},now:{}};this.selection=(Browser.ie)?"selectstart":"mousedown";if(Browser.ie&&!Drag.ondragstartFixed){document.ondragstart=Function.from(false);Drag.ondragstartFixed=true}this.bound={start:this.start.bind(this),check:this.check.bind(this),drag:this.drag.bind(this),stop:this.stop.bind(this),cancel:this.cancel.bind(this),eventStop:Function.from(false)};this.attach()},attach:function(){this.handles.addEvent("mousedown",this.bound.start);return this},detach:function(){this.handles.removeEvent("mousedown",this.bound.start);return this},start:function(event){var options=this.options;if(event.rightClick){return}if(options.preventDefault){event.preventDefault()}if(options.stopPropagation){event.stopPropagation()}this.mouse.start=event.page;this.fireEvent("beforeStart",this.element);var limit=options.limit;this.limit={x:[],y:[]};var z,coordinates;for(z in options.modifiers){if(!options.modifiers[z]){continue}var style=this.element.getStyle(options.modifiers[z]);if(style&&!style.match(/px$/)){if(!coordinates){coordinates=this.element.getCoordinates(this.element.getOffsetParent())}style=coordinates[options.modifiers[z]]}if(options.style){this.value.now[z]=(style||0).toInt()}else{this.value.now[z]=this.element[options.modifiers[z]]}if(options.invert){this.value.now[z]*=-1}this.mouse.pos[z]=event.page[z]-this.value.now[z];if(limit&&limit[z]){var i=2;while(i--){var limitZI=limit[z][i];if(limitZI||limitZI===0){this.limit[z][i]=(typeof limitZI=="function")?limitZI():limitZI}}}}if(typeOf(this.options.grid)=="number"){this.options.grid={x:this.options.grid,y:this.options.grid}}var events={mousemove:this.bound.check,mouseup:this.bound.cancel};events[this.selection]=this.bound.eventStop;this.document.addEvents(events)},check:function(event){if(this.options.preventDefault){event.preventDefault()}var distance=Math.round(Math.sqrt(Math.pow(event.page.x-this.mouse.start.x,2)+Math.pow(event.page.y-this.mouse.start.y,2)));if(distance>this.options.snap){this.cancel();this.document.addEvents({mousemove:this.bound.drag,mouseup:this.bound.stop});this.fireEvent("start",[this.element,event]).fireEvent("snap",this.element)}},drag:function(event){var options=this.options;if(options.preventDefault){event.preventDefault()}this.mouse.now=event.page;for(var z in options.modifiers){if(!options.modifiers[z]){continue}this.value.now[z]=this.mouse.now[z]-this.mouse.pos[z];if(options.invert){this.value.now[z]*=-1}if(options.limit&&this.limit[z]){if((this.limit[z][1]||this.limit[z][1]===0)&&(this.value.now[z]>this.limit[z][1])){this.value.now[z]=this.limit[z][1]}else{if((this.limit[z][0]||this.limit[z][0]===0)&&(this.value.now[z]<this.limit[z][0])){this.value.now[z]=this.limit[z][0]}}}if(options.grid[z]){this.value.now[z]-=((this.value.now[z]-(this.limit[z][0]||0))%options.grid[z])}if(options.style){this.element.setStyle(options.modifiers[z],this.value.now[z]+options.unit)}else{this.element[options.modifiers[z]]=this.value.now[z]}}this.fireEvent("drag",[this.element,event])},cancel:function(event){this.document.removeEvents({mousemove:this.bound.check,mouseup:this.bound.cancel});if(event){this.document.removeEvent(this.selection,this.bound.eventStop);this.fireEvent("cancel",this.element)}},stop:function(event){var events={mousemove:this.bound.drag,mouseup:this.bound.stop};events[this.selection]=this.bound.eventStop;this.document.removeEvents(events);if(event){this.fireEvent("complete",[this.element,event])}}});Element.implement({makeResizable:function(options){var drag=new Drag(this,Object.merge({modifiers:{x:"width",y:"height"}},options));this.store("resizer",drag);return drag.addEvent("drag",function(){this.fireEvent("resize",drag)}.bind(this))}});