/**
 * Drag'n'Drop module for RightJS
 *
 * See http://rightjs.org/goods/drag-n-drop
 *
 * Copyright (C) 2009-2010 Nikolay V. Nemshilov
 */
if (!RightJS) throw "Gimme RightJS";
var Draggable=new Class(Observer,{extend:{EVENTS:$w('before start drag stop drop'),Options:{handle:null,snap:0,axis:null,range:null,dragClass:'dragging',clone:false,revert:false,revertDuration:'normal',scroll:true,scrollSensitivity:32,zIndex:10000000,moveOut:false,relName:'draggable'},current:null,rescan:function(s){var k=this.Options.relName;($(s)||document).select('*[rel^="'+k+'"]').each(function(e){if(!e._draggable){var d=e.get('data-'+k+'-options');new this(e,eval('('+d+')')||{})}},this)}},initialize:function(e,o){this.element=$(e);this.$super(o);this.element._draggable=this.init()},destroy:function(){this.handle.stopObserving('mousedown',this._dragStart);delete(this.element._draggable);return this},setOptions:function(o){this.$super(o);this.handle=this.options.handle?$(this.options.handle):this.element;if(isArray(this.options.snap)){this.snapX=this.options.snap[0];this.snapY=this.options.snap[1]}else this.snapX=this.snapY=this.options.snap;return this},revert:function(){var p=this.clone.position();var e={top:(p.y+this.ryDiff)+'px',left:(p.x+this.rxDiff)+'px'};if(this.options.revertDuration&&this.element.morph)this.element.morph(e,{duration:this.options.revertDuration,onFinish:this.swapBack.bind(this)});else{this.element.setStyle(e);this.swapBack()}return this},init:function(){this._dragStart=this.dragStart.bind(this);this.handle.onMousedown(this._dragStart);return this},dragStart:function(e){this.fire('before',this,e.stop());var p=p=this.element.position();this.xDiff=e.pageX-p.x;this.yDiff=e.pageY-p.y;var r={y:this.element.getStyle('top').toFloat(),x:this.element.getStyle('left').toFloat()};this.rxDiff=isNaN(r.x)?0:(r.x-p.x);this.ryDiff=isNaN(r.y)?0:(r.y-p.y);var s={x:this.element.getStyle('width'),y:this.element.getStyle('height')};if(s.x=='auto')s.x=this.element.offsetWidth+'px';if(s.y=='auto')s.y=this.element.offsetHeight+'px';if(this.options.clone||this.options.revert)this.clone=$(this.element.cloneNode(true)).setStyle({visibility:this.options.clone?'visible':'hidden'}).insertTo(this.element,'before');this.element.setStyle({position:'absolute',zIndex:Draggable.Options.zIndex++,top:(p.y+this.ryDiff)+'px',left:(p.x+this.rxDiff)+'px',width:s.x,height:s.y}).addClass(this.options.dragClass);if(this.options.moveOut)this.element.insertTo(document.body);this.winScrolls=window.scrolls();this.winSizes=window.sizes();Draggable.current=this.calcConstraints().fire('start',this,e)},dragProcess:function(e){var p=e.pageX,a=e.pageY,x=p-this.xDiff,y=a-this.yDiff;if(this.ranged){if(this.minX>x)x=this.minX;if(this.maxX<x)x=this.maxX;if(this.minY>y)y=this.minY;if(this.maxY<y)y=this.maxY}if(this.options.scroll){var s={x:this.winScrolls.x,y:this.winScrolls.y},b=this.options.scrollSensitivity;if((a-s.y)<b)s.y=a-b;else if((s.y+this.winSizes.y-a)<b)s.y=a-this.winSizes.y+b;if((p-s.x)<b)s.x=p-b;else if((s.x+this.winSizes.x-p)<b)s.x=p-this.winSizes.x+b;if(s.y<0)s.y=0;if(s.x<0)s.x=0;if(s.y<this.winScrolls.y||s.y>this.winScrolls.y||s.x<this.winScrolls.x||s.x>this.winScrolls.x)window.scrollTo(this.winScrolls=s)}if(this.snapX)x=x-x % this.snapX;if(this.snapY)y=y-y % this.snapY;if(!this.axisY)this.element.style.left=(x+this.rxDiff)+'px';if(!this.axisX)this.element.style.top=(y+this.ryDiff)+'px';this.fire('drag',this,e)},dragStop:function(e){this.element.removeClass(this.options.dragClass);Droppable.checkDrop(e,this);if(this.options.revert)this.revert();Draggable.current=null;this.fire('stop',this,e)},swapBack:function(){if(this.clone)this.clone.insert(this.element.setStyle({width:this.clone.getStyle('width'),height:this.clone.getStyle('height'),position:this.clone.getStyle('position'),zIndex:this.clone.getStyle('zIndex')||''}),'before').remove()},calcConstraints:function(){var a=this.options.axis;this.axisX=['x','horizontal'].include(a);this.axisY=['y','vertical'].include(a);this.ranged=false;var r=this.options.range;if(r){this.ranged=true;var e=$(r);if(isElement(e)){var d=e.dimensions();r={x:[d.left,d.left+d.width],y:[d.top,d.top+d.height]}}if(isHash(r)){var s=this.element.sizes();if(r.x){this.minX=r.x[0];this.maxX=r.x[1]-s.x}if(r.y){this.minY=r.y[0];this.maxY=r.y[1]-s.y}}}return this}});var Droppable=new Class(Observer,{extend:{EVENTS:$w('drop hover leave'),Options:{accept:'*',containment:null,overlap:null,overlapSize:0.5,allowClass:'droppable-allow',denyClass:'droppable-deny',relName:'droppable'},rescan:eval('({f:'+Draggable.rescan.toString().replace(/\._draggable/g,'._droppable')+'})').f,checkHover:function(e,d){for(var i=0,l=this.active.length;i<l;i++)this.active[i].checkHover(e,d)},checkDrop:function(e,d){for(var i=0,l=this.active.length;i<l;i++)this.active[i].checkDrop(e,d)},active:[]},initialize:function(e,o){this.element=$(e);this.$super(o);Droppable.active.push(this.element._droppable=this)},destroy:function(){Droppable.active=Droppable.active.without(this);delete(this.element._droppable);return this},checkHover:function(e,d){if(this.hoveredBy(e,d)){if(!this._hovered){this._hovered=true;this.element.addClass(this.options[this.allows(d)?'allowClass':'denyClass']);this.fire('hover',d,this,e)}}else if(this._hovered){this._hovered=false;this.reset().fire('leave',d,this,e)}},checkDrop:function(e,d){this.reset();if(this.hoveredBy(e,d)&&this.allows(d)){d.fire('drop',this,d,e);this.fire('drop',d,this,e)}},reset:function(){this.element.removeClass(this.options.allowClass).removeClass(this.options.denyClass);return this},hoveredBy:function(e,c){var d=this.element.dimensions(),k=d.top,i=d.left,j=d.left+d.width,t=d.top+d.height,f=e.pageX,g=e.pageY;if(this.options.overlap){var a=c.element.dimensions(),h=this.options.overlapSize,m=a.top,l=a.left,r=a.left+a.width,b=a.top+a.height;switch(this.options.overlap){case 'x':case 'horizontal':return((m>k&&m<t)||(b>k&&b<t))&&((l>i&&l<(j-d.width*h))||(r<j&&r>(i+d.width*h)));case 'y':case 'vertical':return((l>i&&l<j)||(r>i&&r<j))&&((m>k&&m<(t-d.height*h))||(b<t&&b>(k+d.height*h)));default:return((l>i&&l<(j-d.width*h))||(r<j&&r>(i+d.width*h)))&&((m>k&&m<(t-d.height*h))||(b<t&&b>(k+d.height*h)))}}else return f>i&&f<j&&g>k&&g<t},allows:function(d){if(this.options.containment&&!this._scanned){this.options.containment.walk($);this._scanned=true}var w=this.options.containment?this.options.containment.includes(d.element):true;return w&&(this.options.accept=='*'?true:d.element.match(this.options.accept))}});document.on({ready:function(){Draggable.rescan();Droppable.rescan()},mousemove:function(e){if(Draggable.current){Draggable.current.dragProcess(e);Droppable.checkHover(e,Draggable.current)}},mouseup:function(e){if(Draggable.current)Draggable.current.dragStop(e)}});Element.include({makeDraggable:function(o){new Draggable(this,o);return this},undoDraggable:function(){if(this._draggable)this._draggable.destroy();return this},makeDroppable:function(o){new Droppable(this,o);return this},undoDroppable:function(){if(this._droppable)this._droppable.destroy();return this}});