var Sortables=new Class({Implements:[Events,Options],options:{opacity:1,clone:false,revert:false,handle:false,dragOptions:{},snap:4,constrain:false,preventDefault:false},initialize:function(lists,options){this.setOptions(options);this.elements=[];this.lists=[];this.idle=true;this.addLists($$(document.id(lists)||lists));if(!this.options.clone){this.options.revert=false}if(this.options.revert){this.effect=new Fx.Morph(null,Object.merge({duration:250,link:"cancel"},this.options.revert))}},attach:function(){this.addLists(this.lists);return this},detach:function(){this.lists=this.removeLists(this.lists);return this},addItems:function(){Array.flatten(arguments).each(function(element){this.elements.push(element);var start=element.retrieve("sortables:start",function(event){this.start.call(this,event,element)}.bind(this));(this.options.handle?element.getElement(this.options.handle)||element:element).addEvent("mousedown",start)},this);return this},addLists:function(){Array.flatten(arguments).each(function(list){this.lists.include(list);this.addItems(list.getChildren())},this);return this},removeItems:function(){return $$(Array.flatten(arguments).map(function(element){this.elements.erase(element);var start=element.retrieve("sortables:start");(this.options.handle?element.getElement(this.options.handle)||element:element).removeEvent("mousedown",start);return element},this))},removeLists:function(){return $$(Array.flatten(arguments).map(function(list){this.lists.erase(list);this.removeItems(list.getChildren());return list},this))},getClone:function(event,element){if(!this.options.clone){return new Element(element.tagName).inject(document.body)}if(typeOf(this.options.clone)=="function"){return this.options.clone.call(this,event,element,this.list)}var clone=element.clone(true).setStyles({margin:0,position:"absolute",visibility:"hidden",width:element.getStyle("width")}).addEvent("mousedown",function(event){element.fireEvent("mousedown",event)});if(clone.get("html").test("radio")){clone.getElements("input[type=radio]").each(function(input,i){input.set("name","clone_"+i);if(input.get("checked")){element.getElements("input[type=radio]")[i].set("checked",true)}})}return clone.inject(this.list).setPosition(element.getPosition(element.getOffsetParent()))},getDroppables:function(){var droppables=this.list.getChildren().erase(this.clone).erase(this.element);if(!this.options.constrain){droppables.append(this.lists).erase(this.list)}return droppables},insert:function(dragging,element){var where="inside";if(this.lists.contains(element)){this.list=element;this.drag.droppables=this.getDroppables()}else{where=this.element.getAllPrevious().contains(element)?"before":"after"}this.element.inject(element,where);this.fireEvent("sort",[this.element,this.clone])},start:function(event,element){if(!this.idle||event.rightClick||["button","input","a","textarea"].contains(event.target.get("tag"))){return}this.idle=false;this.element=element;this.opacity=element.getStyle("opacity");this.list=element.getParent();this.clone=this.getClone(event,element);this.drag=new Drag.Move(this.clone,Object.merge({preventDefault:this.options.preventDefault,snap:this.options.snap,container:this.options.constrain&&this.element.getParent(),droppables:this.getDroppables()},this.options.dragOptions)).addEvents({onSnap:function(){event.stop();this.clone.setStyle("visibility","visible");this.element.setStyle("opacity",this.options.opacity||0);this.fireEvent("start",[this.element,this.clone])}.bind(this),onEnter:this.insert.bind(this),onCancel:this.end.bind(this),onComplete:this.end.bind(this)});this.clone.inject(this.element,"before");this.drag.start(event)},end:function(){this.drag.detach();this.element.setStyle("opacity",this.opacity);if(this.effect){var dim=this.element.getStyles("width","height"),clone=this.clone,pos=clone.computePosition(this.element.getPosition(this.clone.getOffsetParent()));var destroy=function(){this.removeEvent("cancel",destroy);clone.destroy()};this.effect.element=clone;this.effect.start({top:pos.top,left:pos.left,width:dim.width,height:dim.height,opacity:0.25}).addEvent("cancel",destroy).chain(destroy)}else{this.clone.destroy()}this.reset()},reset:function(){this.idle=true;this.fireEvent("complete",this.element)},serialize:function(){var params=Array.link(arguments,{modifier:Type.isFunction,index:function(obj){return obj!=null}});var serial=this.lists.map(function(list){return list.getChildren().map(params.modifier||function(element){return element.get("id")},this)},this);var index=params.index;if(this.lists.length==1){index=0}return(index||index===0)&&index>=0&&index<this.lists.length?serial[index]:serial}});