/***********************************************************************************
 * Class: CFormList
 * Description:
 *   List class for forms
 ***********************************************************************************/

	// Contructor
	function CFormList() {};
	
/***********************************************************************************
 * List functions
 ***********************************************************************************/
	// Get index
	CFormList.getIndex = function(index, list) {
		if(index == null)
			index = 0;
		if(index <= 0 && list != null && list.options)
			index += list.options.length - 1;
		return index;
	};
	
	// Apply a function call to all items in a list starting with the last
	// Passes the argmuments list and index to the supplied function
	// First index and last index specifies range
	// If last index is negative, the last valid index will be list length + last index - 1
	CFormList.applyToAllSelected = function(list, func, firstIndex, lastIndex, bottomUp) {
		if(typeof(func) != 'function' || !list)
			return;
			
		// Set first and last index
		firstIndex = CFormList.getIndex(firstIndex);
		lastIndex = CFormList.getIndex(lastIndex, list);		
				
		if(bottomUp) {
			for(i = lastIndex; i >= firstIndex; i--)
				(func)(list, i, list.options[i]);
		}
		else {
			for(i = firstIndex; i <= lastIndex; i++)
				(func)(list, i, list.options[i]);
		}
	};
	
	// Add item to a list
	CFormList.addItem = function(list, text, value, index, unique, sorting, sortOnText) {
		if(unique || sorting) {
			// Make sure item is unique
			for(var i = 0; i < list.options.length; i++) {
				var itemValue = list.options[i].value;
				if(unique && itemValue == value)
					return;

				if(sorting) {
					var sortCurrent = (sortOnText ? list.options[i].text : itemValue);
					var sortValue = (sortOnText ? text : value);
				
					if((sorting == "asc" && sortCurrent >= sortValue) ||
						(sorting == "desc" && sortCurrent < sortValue)) {
						index = i;
						sorting = null;
					}
				}
			}
		}
		// Add item
		var item = document.createElement("option");
		item.text = text;
		item.value = value;
		if(index != null && index >= 0) {
			list.options.add(item, index);
			return index;
		}
		else {
			list.options[list.options.length] = item;
			return list.options.length - 1;
		}
	};
		
	// Remove list item
	CFormList.removeItem = function(list, index) { 
		var end = list.options.length;
		for(var i = index + 1; i < end; i++) {
			list.options[i - 1].text = list.options[i].text;
			list.options[i - 1].value = list.options[i].value;
		}
		list.options.length--;
	};
	
	// Remove list item
	CFormList.removeItems = function(list, firstIndex, lastIndex)	{
		// Remove all selected items, bottom up
		CFormList.applyToAllSelected(list, new Function("list,index,item", "if(item.selected) CFormList.removeItem(list, index);"), firstIndex, lastIndex, true);
	};

	// Move list item up
	CFormList.moveItemUp = function(list, index, firstIndex, lastIndex) {
		// Set first and last index
		firstIndex = CFormList.getIndex(firstIndex);
		lastIndex = CFormList.getIndex(lastIndex, list);		
	
		if(index == null || index < 0)
			index = list.selectedIndex;

		if(index > firstIndex && index <= lastIndex) {
			var text = list.options[index].text;
			var value = list.options[index].value;
			
			list.options[index].text = list.options[index - 1].text;
			list.options[index].value = list.options[index - 1].value;
			list.options[index - 1].text = text;
			list.options[index - 1].value = value;
			
			//list.selectedIndex = index - 1;
			list.options[index].selected = false;
			list.options[index - 1].selected = true;
		}
	};
	
	// Move list item down
	CFormList.moveItemDown = function(list, index, firstIndex, lastIndex) {
		// Set first and last index
		firstIndex = CFormList.getIndex(firstIndex);
		lastIndex = CFormList.getIndex(lastIndex, list);		
	
		if(index == null || index < 0)
			index = list.selectedIndex;

		if(index >= firstIndex && index < lastIndex) {
			var text = list.options[index].text;
			var value = list.options[index].value;
			
			list.options[index].text = list.options[index + 1].text;
			list.options[index].value = list.options[index + 1].value;
			list.options[index + 1].text = text;
			list.options[index + 1].value = value;
			
			//list.selectedIndex = index + 1;
			list.options[index].selected = false;
			list.options[index + 1].selected = true;
		}
	};

	// Move items up
	CFormList.moveItemsUp = function(list, firstIndex, lastIndex)	{
		// Set first + 1 since first index cant move up
		firstIndex = CFormList.getIndex(firstIndex) + 1;
		
		// Remove all selected items, bottom up
		CFormList.applyToAllSelected(list, new Function("list,index,item", "if(item.selected && !list.options[index - 1].selected) CFormList.moveItemUp(list, index);"), firstIndex, lastIndex, false);
	};

	// Move items down
	CFormList.moveItemsDown = function(list, firstIndex, lastIndex)	{
		// Set last index - 1 since last item can't move down
		lastIndex = CFormList.getIndex(lastIndex, list) - 1;
		
		// Remove all selected items, bottom up
		CFormList.applyToAllSelected(list, new Function("list,index,item", "if(item.selected && !list.options[index + 1].selected) CFormList.moveItemDown(list, index);"), firstIndex, lastIndex, true);
	};

	// Select all items in a list	
	CFormList.selectAllItems = function(list, selected, firstIndex, lastIndex) {
		if(!list.options)
			list = list[1].options;
		selected = (selected == null || selected ? "true" : "false");
		
		// Unselect all items up to first index
		CFormList.applyToAllSelected(list, new Function("list,index,item", "if(item.selected) item.selected = false;"), lastIndex, 0);
		// Unselect all items after last index
		CFormList.applyToAllSelected(list, new Function("list,index,item", "if(item.selected) item.selected = false;"), 0, firstIndex);
		// Select/Unselect all items in range	
		CFormList.applyToAllSelected(list, new Function("list,index,item", "if(item.selected != " + selected + ") item.selected = " + selected + ";"), firstIndex, lastIndex);
	};
	
	// Copy selected items from one list to another
	CFormList.copyItems = function(destList, sourceList, firstIndex, lastIndex, unique) {
		// Set first and last index
		firstIndex = CFormList.getIndex(firstIndex);
		lastIndex = CFormList.getIndex(lastIndex, sourceList);		
		// Copy all selected items to destination list
		CFormList.copyItemsDestList = destList;
		unique = (unique ? "true" : "false");
		CFormList.applyToAllSelected(sourceList, new Function("list,index,item", "if(item.selected) CFormList.addItem(CFormList.copyItemsDestList, item.text, item.value, null, " + unique + ");"), firstIndex, lastIndex, true);
	};

	// Move selected items from one list to another
	CFormList.listMoveItems = function(destList, sourceList, firstIndex, lastIndex, sorting) {
		// Set first and last index
		firstIndex = CFormList.getIndex(firstIndex);
		lastIndex = CFormList.getIndex(lastIndex, sourceList);		
		// Copy all selected items to destination list
		CFormList.copyItemsDestList = destList;
		sorting = (sorting ? "'" + sorting + "'" : "null");
		CFormList.applyToAllSelected(sourceList, new Function("list,index,item", "if(item.selected) { CFormList.addItem(CFormList.copyItemsDestList, item.text, item.value, null, null, " + sorting + "); CFormList.listRemoveItem(list, index); }"), firstIndex, lastIndex, true);
	};
	
	// Append items from an array to a list. Array format (text1, value1, text2, value2, ..., textn, valuen)
	CFormList.fillList = function(list, sourceArray, selectId, selectFirstIfSingleRecord) {
		for(var i = 1; i < sourceArray.length; i += 2) {
			index = CFormList.addItem(list, sourceArray[i - 1], sourceArray[i]);
			// Select list item?
			if((selectId != null && parseInt(selectId) == parseInt(sourceArray[i])) || (selectFirstIfSingleRecord && sourceArray.length == 2))
				list.options.selectedIndex = index;
		}
	};

	// Get next selected index of an item
	CFormList.getNextSelectedIndex = function(list, firstIndex, lastIndex) {
		if(lastIndex == null)
			lastIndex = list.length;
		for(var i = (firstIndex != null ? firstIndex : 0); i < lastIndex; i++) {
			if(list.options[i].selected)
				return i;
		}
		return -1;
	};
	
	// Get next selected item
	CFormList.getNextSelectedItem = function(list, firstIndex, lastIndex) {
		var index = CFormList.getNextSelectedIndex(list, firstIndex, lastIndex);
		return (index >= 0) ? list.options[index] : null;
	};

	// Find item by value and return index
	CFormList.getItemIndexByValue = function(list, value, firstIndex, lastIndex) {
		if(lastIndex == null)
			lastIndex = list.length;
		for(var i = (firstIndex != null ? firstIndex : 0); i < lastIndex; i++) {
			if(list.options[i].value == value)
				return i;
		}
		return -1;
	};
	
	// Find and select item by value
	CFormList.selectItemByValue = function(list, value, firstIndex, lastIndex) {
		var index = CFormList.getItemIndexByValue(list, value, firstIndex, lastIndex);
		if(index >= 0) {
			list.options[index].selected = true;
			list.selectedIndex = index;
			return true;
		}
		return false;
	};

