if(!window.Richfaces) window.Richfaces = {};

Richfaces.ListShuttle = Class.create();

Richfaces.ListShuttle.Source = Class.create(Richfaces.ListBase);
Richfaces.ListShuttle.Target = Class.create(Richfaces.OrderingList);

Richfaces.ListShuttle.Source.SelectItem = Class.create(Richfaces.SelectItem);
Richfaces.ListShuttle.Source.SelectItem.prototype.CLASSES = {
	ROW : {
		ACTIVE   : "rich-shuttle-source-row-active",
		SELECTED : "rich-shuttle-source-row-selected",
		DISABLED : "rich-shuttle-source-row-disabled",
		NORMAL   : "rich-shuttle-source-row"
	},
	CELL : {
		ACTIVE   : "rich-shuttle-source-cell-active",
		SELECTED : "rich-shuttle-source-cell-selected",
		DISABLED : "rich-shuttle-source-cell-disabled",
		NORMAL   : "rich-shuttle-source-cell",
		BEGIN:	" rich-shuttle-source-cell-first",
		END:	" rich-shuttle-source-cell-last"
	}
}

Richfaces.ListShuttle.Target.SelectItem = Class.create(Richfaces.SelectItem);
Richfaces.ListShuttle.Target.SelectItem.prototype.CLASSES = {
	ROW : {
		ACTIVE   : "rich-shuttle-target-row-active",
		SELECTED : "rich-shuttle-target-row-selected",
		DISABLED : "rich-shuttle-target-row-disabled",
		NORMAL   : "rich-shuttle-target-row"
	},
	CELL : {
		ACTIVE   : "rich-shuttle-target-cell-active",
		SELECTED : "rich-shuttle-target-cell-selected",
		DISABLED : "rich-shuttle-target-cell-disabled",
		NORMAL   : "rich-shuttle-target-cell",
		BEGIN:	" rich-shuttle-target-cell-first",
		END:	" rich-shuttle-target-cell-last"
	}
}

Richfaces.ListShuttle.prototype = {
	initialize: function(targetList, sourceList, clientId, controlIds, switchByClick, onlistchanged) {
		this.containerId = clientId;
		this["rich:destructor"] = "destroy";
		
		this.container = $(this.containerId);
		this.container.component = this;
		
		this.targetList = targetList;
		this.sourceList = sourceList;
		
		this.targetLayoutManager = targetList.layoutManager;
		this.sourceLayoutManager = sourceList.layoutManager;
		
		if (switchByClick == "true") {
			this.targetList.shuttleTable.observe("click", function(e) {this.moveItemByClick(window.event||e, this.targetList, this.sourceList)}.bindAsEventListener(this));
			this.sourceList.shuttleTable.observe("click", function(e) {this.moveItemByClick(window.event||e, this.sourceList, this.targetList)}.bindAsEventListener(this));
			Event.stopObserving(this.sourceList.shuttleTable, "click", this.sourceList.clckHandler);
			Event.stopObserving(this.targetList.shuttleTable, "click", this.targetList.clckHandler);
		} else {
			this.targetList.shuttleTable.observe("dblclick", function(e) {this.moveItemByClick(window.event||e, this.targetList, this.sourceList)}.bindAsEventListener(this));
			this.sourceList.shuttleTable.observe("dblclick", function(e) {this.moveItemByClick(window.event||e, this.sourceList, this.targetList)}.bindAsEventListener(this));
			
			sourceList._onclickHandler = sourceList.onclickHandler;
			sourceList.onclickHandler = function(e) { this.onclickHandler(e, sourceList); }.bindAsEventListener(this);
			targetList._onclickHandler = targetList.onclickHandler;
			targetList.onclickHandler = function(e) { this.onclickHandler(e, targetList); }.bindAsEventListener(this);
		}
		
		sourceList._onkeydownHandler = sourceList.onkeydownHandler;
		sourceList.onkeydownHandler = function(e) { this.onkeydownHandler(e, sourceList); }.bindAsEventListener(this);
		targetList._onkeydownHandler = targetList.onkeydownHandler;
		targetList.onkeydownHandler = function(e) { this.onkeydownHandler(e, targetList); }.bindAsEventListener(this);
			
		this.controlList = new Array();
		this.initControlList(clientId, controlIds);
	
		if (onlistchanged) {
			this.targetList.container.observe("rich:onorderchanged", onlistchanged);
			this.container.observe("rich:onlistchanged", onlistchanged);
		}
	},
	
	destroy: function() {
		this.container.component = null;
		this.targetList.destroy();
		this.sourceList.destroy();
	},
	
	initControlList : function(clientId, ids) {
		for (var i = 0; i < ids.length; i++) {
			var id = ids[i];
			var node = $(clientId + id[0]);
			var disNode = $(clientId + id[1]);
			if (node && disNode) { 
				node.observe("click", Richfaces.ListShuttle.HANDLERS[id[0]].bindAsEventListener(this));	
				this.controlList[i] = new Richfaces.Control(node, disNode, false, false, id[0]);
			}
		}
		//this.controlListManager();
	},
	
	controlListManager : function() {
		//this.controlsProcessing();
		this.controlsProcessing(["copy", "copyAll", "removeAll" ,"remove"], "enable");
		if (this.sourceList.shuttleItems.length < 1) 
			this.controlsProcessing(["copy", "copyAll"], "disable");
		if (this.sourceList.selectedItems.length < 1) 
			this.controlsProcessing(["copy"] , "disable");
		if (this.targetList.shuttleItems.length < 1) 
			this.controlsProcessing(["removeAll" ,"remove"], "disable");
		if (this.targetList.selectedItems.length < 1) {
			this.controlsProcessing(["remove"], "disable");
		} 	
	},
	
	onclickHandler : function(event, component) {
		component._onclickHandler(event);
		this.controlListManager();
		//Event.stop(event);     //bug: RF-2097
	},
	
	onkeydownHandler : function(event, component) {
		component._onkeydownHandler(event);
		this.controlListManager();
	},
	
	controlsProcessing : function(disabledControls , action) {
		for (var i = 0; i < this.controlList.length; i++) {
			control = this.controlList[i];
			if (control != null) {
				if (disabledControls != null && disabledControls.indexOf(control.action) != -1) {
					if (action == "disable") {
						control.doDisable();
					} else {
						control.doEnable();
					}
				}
			}
		}
	},
	
	moveItems : function(sourceComponent, targetComponent, items) {
		if (items.length > 0) {
			var length = items.length;
			for (var i = 0; items.length > 0;) {
				var item = items[i];
				this.moveItem(sourceComponent, targetComponent, item);
			} 
			this.controlListManager();
			if (this.targetList.controlListManager) {
				this.targetList.controlListManager();				
			}
			//this.saveState();
			
			this.targetLayoutManager.widthSynchronization();
			this.sourceLayoutManager.widthSynchronization();
		
			this.container.fire("rich:onlistchanged", {});
		}
	},
	
	moveItem : function(sourceComponent, targetComponent, item) {
		if (!(item instanceof Richfaces.SelectItem)) {
			item = sourceComponent.getSelectItemByNode(item);
		}
		if (!LayoutManager.isIE() && (targetComponent.shuttleTbody.rows.length == 0)) {
			var newItem = null;
			if (item instanceof Richfaces.ListShuttle.Target.SelectItem) {
				newItem = new this.targetList.controlClass(item._label, item._id, item._node.cloneNode(true));
			} else {
				newItem = new this.sourceList.controlClass(item._label, item._id, item._node.cloneNode(true));
			}
			this.tableUpdate(targetComponent);
			this.addItem(targetComponent, newItem);
			
			this.removeItem(sourceComponent, item);
			sourceComponent.shuttleTable.deleteRow(item._node.rowIndex);
		} else {
			this.addItem(targetComponent, item);
			this.removeItem(sourceComponent, item);
		}
	},
	
	removeItem : function(component, item) {
		var items = component.shuttleItems;
		component.selectedItems.remove(item._node);
		items.remove(item);
		if (item == component.activeItem) {
			component.activeItem == null;
		}
	},
	
	addItem : function(component, item) {
		//var newItem = Object.clone(item);
		item.doNormal(Richfaces.getExternalClass(item.rowIndex), component.columnsClasses);
		
		component.shuttleTbody.insertBefore(item._node, null);
		component.shuttleItems.push(item);
	},
	
	tableUpdate : function(component) {
		var table = component.shuttleTable;
		var tbody = table.tBodies[0];
		var newTbody = tbody.cloneNode(false);
		table.removeChild(tbody);
		table.appendChild(newTbody);
		component.shuttleTbody = table.tBodies[0];
	},
	
	/*saveState : function() {
		this.targetList.saveState();
		this.sourceList.saveState();
	},*/
	
	moveItemByClick : function(event, sourceComponent, targetComponent, layoutManager) {
		var item = this.sourceList.getEventTargetRow(event);
		this.moveItem(sourceComponent, targetComponent, item);
		
		this.controlListManager();
		if (this.targetList.controlListManager) {
			this.targetList.controlListManager();
		}
		//this.saveState();
		
		this.targetLayoutManager.widthSynchronization();
		this.sourceLayoutManager.widthSynchronization();
		
		this.container.fire("rich:onlistchanged", {});
	},
	
	copyAll : function() {
		this.moveItems(this.sourceList, this.targetList, this.sourceList.shuttleItems);
	},
	
	copy : function() {
		this.moveItems(this.sourceList, this.targetList, this.sourceList.selectedItems);
	},
	
	removeAll : function() {
		this.moveItems(this.targetList, this.sourceList, this.targetList.shuttleItems);
	},
	
	remove : function() {
		 this.moveItems(this.targetList, this.sourceList, this.targetList.selectedItems);
	}
	
};

Richfaces.ListShuttle.HANDLERS = {
	copy:      function (e) { this.copy(); return false; },
	copyAll:   function (e) { this.copyAll(); return false; },
	remove:    function (e) { this.remove(); return false; },
	removeAll: function (e) { this.removeAll(); return false; }
};