/* ******************************************************************
 * Author		:	11.09.2006, Marco Feuchter (Activest Investmentgesellschaft mbH)
 * Description	:	Implements the selection mechanism between two html <select>s
 * ******************************************************************/

var SELECT_ACTIVE     = 0;
var SELECT_INACTIVE   = 1;
var DESELECT_ACTIVE   = 2;
var DESELECT_INACTIVE = 3;

var imagePath = "/de_DE/media/forms/";

var selectionArrows = new Array();
selectionArrows[SELECT_ACTIVE]         = new Image();
selectionArrows[SELECT_ACTIVE].src     = imagePath + "btn_select_active.gif";
selectionArrows[SELECT_INACTIVE]       = new Image();
selectionArrows[SELECT_INACTIVE].src   = imagePath + "btn_select_inactive.gif";
selectionArrows[DESELECT_ACTIVE]       = new Image();
selectionArrows[DESELECT_ACTIVE].src   = imagePath + "btn_deselect_active.gif";
selectionArrows[DESELECT_INACTIVE]     = new Image();
selectionArrows[DESELECT_INACTIVE].src = imagePath + "btn_deselect_inactive.gif";

function toggleStatus(element, status) {
	if (element != null && (status >= 0 && status < selectionArrows.length)) {
		element.src = selectionArrows[status].src;
	}
}


/* ******************************************************************
 * The class Selection
 *
 * Public Methods:
 *   init()
 *   select(all)
 *   deselect(all)
 *   isSelectFromSelected()
 *   isSelectToSelected()
 * ******************************************************************/

/* ******************************************************************
 * Class constructor Selection(HTMLSelectElement, HTMLSelectElement, HTMLInputElement)
 *
 * Parameters:
 *    selectFrom - Reference to the available items <select>
 *      selectTo - Reference to the selected  items <select>
 *   hiddenInput - Reference to the hidden form <input>. The hidden
 *                 input keeps the actual selection which is going
 *                 to be transmitted to the server.
 * ******************************************************************/
function Selection (selectFrom, selectTo, hiddenInput) {
	
	this.selectFrom	 = (typeof(selectFrom)  != 'undefined' ? selectFrom  : null);
	this.selectTo	 = (typeof(selectTo)    != 'undefined' ? selectTo    : null);
	this.hiddenInput = (typeof(hiddenInput) != 'undefined' ? hiddenInput : null);
	this.array       = new Array();
}

/* ******************************************************************
 * Public Method init()
 *
 * Must be called once on pageload to synchronize the internal fields
 * with the incoming bean values.
 * ******************************************************************/
Selection.prototype.init = function () {

	// initially populate the array
	if (this.array.length == 0 && this.selectTo != null) {
		for (i = 0; i < this.selectTo.options.length; i++) {
			var currentOption = this.selectTo.options[i];
			this.array.push(new Array(currentOption.value, currentOption.text));
        }							
	}
   	this.array.sort(arraySort); // asc
   	this._synchronizeSelect();  // synchronize array - select - hidden
}

/* ******************************************************************
 * Public Method select(boolean)
 *
 * Add the selected items to the selection.
 *
 * Parameter:
 *   all - true, all items are going to be added to the selection
 * ******************************************************************/
Selection.prototype.select = function (all) {
	if (this.selectFrom != null && this.selectTo != null) {
		if (all)
			this.array = new Array();
			
		var checkDouble = (this.array.length == 0 ? false : true);
		var i;
		for (i = 0; i < this.selectFrom.options.length; i++) {
			var currentOption = this.selectFrom.options[i];
        	if ((currentOption.selected == true || all) && !currentOption.disabled)
	        	this._addOptionToArray(currentOption.value, currentOption.text, checkDouble);
        }

        if (!all)
        	this.array.sort(arraySort);	// asc
        this._synchronizeSelect();		// synchronize array - select - hidden
        this._clearSelect();
	}	
}

/* ******************************************************************
 * Public Method deselect(boolean)
 *
 * Remove the selected items from the selection.
 *
 * Parameter:
 *   all - true, all items are going to be removed from the selection
 * ******************************************************************/
Selection.prototype.deselect = function (all) {
	if (this.selectTo != null) {
		this.array = new Array();
		if (all == true) {
			this.selectTo.length = 0;
		}
			
		var i;
		for (i = 0; i < this.selectTo.options.length; i++) {
			var currentOption = this.selectTo.options[i];
        	if (currentOption.selected == false)
	        	this._addOptionToArray(currentOption.value, currentOption.text, false);
        }

        this._synchronizeSelect();
        this._clearDeselect();
        this._clearSelect();
	}
}

/* ******************************************************************
 * Public Method boolean isSelectFromSelected()
 *
 * Returns true, if at least one item in the list of available items
 * is selected, otherwise false.
 * ******************************************************************/
Selection.prototype.isSelectFromSelected = function () {
	return this._isSelected(this.selectFrom);
}

/* ******************************************************************
 * Public Method boolean isSelectToSelected()
 *
 * Returns true, if at least one item in the list of selected items
 * is selected, otherwise false.
 * ******************************************************************/
Selection.prototype.isSelectToSelected = function () {
	return this._isSelected(this.selectTo);
}

/* ******************************************************************
 * Private Method boolean _isSelected(HTMLSelectElement)
 *
 * Returns true, if at least one item in the list is selected,
 * otherwise false.
 *
 * Parameter:
 *   selectElement - reference to the list
 * ******************************************************************/
Selection.prototype._isSelected = function (selectElement) {
	if (selectElement != null) {
		var l;
		for (l = 0; l < selectElement.options.length; l++) {
        	if (selectElement.options[l].selected == true && !selectElement.options[l].disabled)
	        	return true;
        }			
	}
	return false;
}

/* ******************************************************************
 * Private Method boolean _addOptionToArray(String, String, boolean)
 *
 * Add an option (value/text pair) to the internal selection array.
 * Returns true if the element has been added, otherwise false.
 *
 * Parameters:
 *   value - value of the HTML option element
 *    text - text of the HTML option element
 *   check - performs a doubletcheck, if set to true
 * ******************************************************************/
Selection.prototype._addOptionToArray = function (value, text, check) {
    if (this.array != null) {
		var j;
		for (j = 0; check && j < this.array.length; j++) {
        	if (this.array[j][0] == value)
	        	return false;
        }
        this.array.push(new Array(value, text));

        return true;
    }
    return false;
}

/* ******************************************************************
 * Private Method void _synchronizeSelect()
 *
 * Synchronize the internal selection array with the HTMLSelectElement
 * that holds the visible selection and the hidden HTMLInputElement.
 * ******************************************************************/
Selection.prototype._synchronizeSelect = function () {
	if (this.selectTo != null && this.array != null) {
		var valueList = "";
		
		this.selectTo.length = 0
		var k;
		for (k = 0; k < this.array.length; k++) {
	        var newOption = new Option(this.array[k][1], this.array[k][0], false, false);
	        this.selectTo.options[k] = newOption;
	        if (k == 0)
	        	valueList += this.array[k][0];
	        else
	        	valueList += "," + this.array[k][0];
		}
		
		this.hiddenInput.value = valueList;
	}
}

/* ******************************************************************
 * Private Method void _clearSelect()
 *
 * Clear the selection from the HTMLSelectElement that holds the
 * available items.
 * ******************************************************************/
Selection.prototype._clearSelect = function () {
	this._clear(this.selectFrom);
}

/* ******************************************************************
 * Private Method void _clearDeselect()
 *
 * Clear the selection from the HTMLSelectElement that holds the
 * selected items.
 * ******************************************************************/
Selection.prototype._clearDeselect = function () {
	this._clear(this.selectTo);
}

/* ******************************************************************
 * Private Method void _clear(HTMLSelectElement)
 *
 * Clear the selection from the given HTMLSelectElement.
 *
 * Parameter:
 *   selectElement - reference to the HTMLSelectElement
 * ******************************************************************/
Selection.prototype._clear = function (selectElement) {
	if (selectElement != null) {
		var l;
		for (l = 0; l < selectElement.options.length; l++) {
        	if (selectElement.options[l].selected == true)
	        	selectElement.options[l].selected = false;
        }			
	}
}
		
/* ******************************************************************
 * Helper functions
 * ******************************************************************/
// implements an ascending array sort
function arraySort(a, b) {
	if(a[1] > b[1])
		return 1
	if(a[1] < b[1])
		return -1
	return 0
}
// implements a descending array sort
function arraySortReverse(a, b) {
	if(a[1] > b[1])
		return -1
	if(a[1] < b[1])
		return 1
	return 0
}
