/*
 * ============================================================================
 *                   The ProQuality Inc.
 *         Rapid Efficent Low cost And Xtreme (RELAX)
 *	           Advanced Solutions Framework (ASF)
 *                  Cristian Teodorescu
 *                      Version 6.0
 * ============================================================================
 * 
 *    Copyright (C) 1999 The ProQuality Inc. Foundation. All rights reserved.
 * 
 * The use of this software in any form is strictly prohibited unless you have 
 * purchased a licence from ProQuality Inc. or you have a software agreement with 
 * ProQuality Inc.
 * 
 * Redistributions of source code must retain copyright statements
 * and notices. Redistributions must also contain a copy of this
 * document.
 *
  THIS SOFTWARE IS PROVIDED BY PROQUALITY AND CONTRIBUTORS ``AS IS'' AND
  ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL PROQUALITY OR ITS
  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  DAMAGE.
    
 *
 */

var ListBoxHandler = {
	registerArray	: 	{},
	all				: 	{},
	activeListBox		:	null,
	register		: 	function (inputElement, optionsArray, multiple, divElement, disabled, onselect, flyover) 
						{
							if(ListBoxHandler.registerArray[inputElement] == null)
							{
								ListBoxHandler.registerArray[inputElement]= new ListBoxRegistrationObject(inputElement, optionsArray, multiple, divElement, disabled, onselect, flyover);
							}
						}
}


function ListBoxRegistrationObject(inputElement, optionsArray, multiple, divElement, disabled, onselect, flyover)
{
	this.inputElement = inputElement;
	this.optionsArray = optionsArray;
	this.multiple = multiple;
	this.divElement = divElement;
	this.disabled = disabled;
	this.onselect = onselect;
	this.flyover = flyover;
}

function listboxInit ()
{
	for(var inputElement in ListBoxHandler.registerArray)
	{
		var c = ListBoxHandler.registerArray[inputElement];
		var elem = document.getElementById(inputElement);
		var divElem = document.getElementById(c.divElement);
		if(elem != null)
		{
			new ListBox(elem, c.optionsArray, c.multiple, divElem, c.disabled, c.onselect, c.flyover);
		}
	}
}

function ListBox()
{
	
    if(arguments.length==0)
	{
	    self.status="ListBox invalid - no name arg"
	}

 	this.arguments = arguments;
 	
 	this.inputElement = arguments[0];
 	this.options  = arguments[1]||new Array();
 	this.multiple = arguments[2];
 	this.divElement = arguments[3];
 	this.disabled = arguments[4];
 	//this.onselect = arguments[5];
 	var onselect = arguments[5];
 	if(onselect != null)
 	{
 		this.onselect = new Function("", onselect);
 	}
 	this.flyover = arguments[6];
 	
    this.name 	= this.inputElement.id;
    this.parent   = this.inputElement.parentNode;
	
    this.nextTabElement = ListBox.getNextTabElement(this.inputElement);
	this.previousTabElement = ListBox.getPreviousTabElement(this.inputElement);
		
	this.numItemsSelected = 0;
    this.currentRow = -1;
    this.handlerCall = "ListBoxHandler.all[\"" + this.name + "\"]";
    this.cancelBlur = false;
    this.opslistBlurEnabled = false;
    this.itemSelected = false;
    this.isActive = false;

    this.activate	= ListBox_activate;
    this.deactivate	= ListBox_deactivate;
    this.make		= ListBox_make;
	this.add		= ListBox_add;
    this.remove		= ListBox_remove;
    this.hilite		= ListBox_hilite;
    this.position   = ListBox_position;
	
    this.make()
	
    ListBoxHandler.all[this.name] = this;
}

function ListBox_make()
{
    var str;
		
    this.opsTable = document.createElement("TABLE");
    this.opsTable.id = this.name + "_table";
    this.opsTable.width = "100%";
    this.opsTable.cellPadding = 0;
    this.opsTable.cellSpacing = 0;
	
    str = '<tbody>';
    for(var i=0; i < this.options.length; i++)
	{
	    var row = this.opsTable.insertRow(i);
		var cell = row.insertCell(0);
		cell.className = "listbox-item";
		cell.id = "cell" + i;
		cell.setAttribute("listboxName", this.name);
		cell.setAttribute("rowNumber", i);
		if(this.flyover)
		{
			cell.title = this.options[i].text;
		}
		
		if(i == 0)
		{
			var tmp = document.createElement("A");
			tmp.id = this.name + "_focus";
			tmp.href = "#";
			
			if (document.addEventListener)
			{
				tmp.addEventListener("focus", ListBox_handleFocus, false );
			}
			else if(document.attachEvent)
			{
				tmp.attachEvent("onfocus", ListBox_handleFocus);
			}
			tmp.onblur = new Function ("", this.handlerCall + ".deactivate()");
			
			this.focusElement = tmp;
			cell.appendChild(tmp);
	   	}
		
		var textNode = document.createTextNode(' '+this.options[i].text+' ');
		if(!this.disabled)
		{
			if (document.addEventListener) //for Netscape only
			{
				textNode.addEventListener("mousedown", ListBox_mouseDown, false );
			}
		}
		
		cell.appendChild(textNode);
		
		if(!this.disabled)
		{
			if (document.addEventListener)
			{
				cell.addEventListener("mousedown", ListBox_mouseDown, false );
			}
			else if(document.attachEvent)
			{
				cell.attachEvent("onmousedown", ListBox_mouseDown);
			}
		}
	}
	
    this.divElement.appendChild(this.opsTable);
    
	var rowsString = this.inputElement.value;
	if(rowsString != null && rowsString != "")
	{
		var selectedRows = rowsString.split(",");
		for(var i = 0; i < selectedRows.length; i++)
		{
			var row = parseInt(selectedRows[i]);
			this.options[row].selected = true;
			this.opsTable.rows[row].cells[0].className = "listbox-hilite";
			if(this.currentRow == -1)
			{
				this.currentRow = row;
			}
		}
	}
	
}

function ListBox_position()
{
	var cell = this.opsTable.rows[this.currentRow].cells[0];
	if(((cell.offsetTop + cell.offsetHeight) - this.divElement.scrollTop) > (this.divElement.offsetHeight - 3))
	{
		this.divElement.scrollTop = (cell.offsetTop + cell.offsetHeight) - (this.divElement.offsetHeight - 3);
	}
	else if((cell.offsetTop - this.divElement.scrollTop) < 0)
	{
		this.divElement.scrollTop =  cell.offsetTop;
	}
}

function ListBox_handleKeyDown(evt)
{
	var listbox = ListBoxHandler.activeListBox;
	var table;
	var preventPropagation = false;
	
	evt = (evt) ? evt : ((event) ? event : null);

	if (evt)
	{
		var key = evt.keyCode;
		
		if(key == 40) //down key
		{
			if(listbox.currentRow >= 0 && listbox.currentRow < listbox.opsTable.rows.length -1)
			{
				if(evt.shiftKey && listbox.multiple)
				{
					if(listbox.options[listbox.currentRow + 1].selected == false)
					{
						listbox.opsTable.rows[listbox.currentRow].cells[0].className = "listbox-hilite";
						listbox.currentRow = listbox.currentRow + 1;
						ListBox.select(listbox, listbox.currentRow);
						listbox.opsTable.rows[listbox.currentRow].cells[0].className = "listbox-hilite-selected";
					}
					else
					{
						ListBox.unselect(listbox, listbox.currentRow);
						listbox.opsTable.rows[listbox.currentRow].cells[0].className = "listbox-item";
						listbox.currentRow = listbox.currentRow + 1;
						listbox.opsTable.rows[listbox.currentRow].cells[0].className = "listbox-hilite-selected";
					}
				}
				else
				{
					if(listbox.numItemsSelected > 1)
					{
						ListBox.reset(listbox);
					}
					else if(listbox.numItemsSelected >= 0)
					{
						ListBox.unselect(listbox, listbox.currentRow);
						listbox.opsTable.rows[listbox.currentRow].cells[0].className = "listbox-item";
					}
					listbox.currentRow = listbox.currentRow + 1;
					ListBox.select(listbox, listbox.currentRow);
					listbox.opsTable.rows[listbox.currentRow].cells[0].className = "listbox-hilite-selected";
				}
				
				listbox.position();
			}
						
			preventPropagation = true;
		}

		if(key == 38) //up key
		{
			if(listbox.currentRow > 0)
			{
				if(evt.shiftKey && listbox.multiple)
				{
					if(listbox.options[listbox.currentRow - 1].selected == false)
					{
						listbox.opsTable.rows[listbox.currentRow].cells[0].className = "listbox-hilite";
						listbox.currentRow = listbox.currentRow - 1;
						ListBox.select(listbox, listbox.currentRow);
						listbox.opsTable.rows[listbox.currentRow].cells[0].className = "listbox-hilite-selected";
					}
					else
					{
						ListBox.unselect(listbox, listbox.currentRow);
						listbox.opsTable.rows[listbox.currentRow].cells[0].className = "listbox-item";
						listbox.currentRow = listbox.currentRow - 1;
						listbox.opsTable.rows[listbox.currentRow].cells[0].className = "listbox-hilite-selected";					
					}
				}
				else
				{
					if(listbox.numItemsSelected > 1)
					{
						ListBox.reset(listbox);
					}
					else if(listbox.numItemsSelected >= 0)
					{
						ListBox.unselect(listbox, listbox.currentRow);
						listbox.opsTable.rows[listbox.currentRow].cells[0].className = "listbox-item";
					}
					listbox.currentRow = listbox.currentRow - 1;
					ListBox.select(listbox, listbox.currentRow);
					listbox.opsTable.rows[listbox.currentRow].cells[0].className = "listbox-hilite-selected";
				}

				listbox.position();
			}
			
			preventPropagation = true;
		}
		
		if(key == 9) //tab key
		{
			listbox.deactivate();
			if(evt.shiftKey)
			{
				if(listbox.previousTabElement)
				{
					listbox.previousTabElement.focus();
					preventPropagation = true;
				}
			}
			else
			{
				if(listbox.nextTabElement)
				{
					listbox.nextTabElement.focus();
					preventPropagation = true;
				}
			}
		}
		
		if(preventPropagation)
		{
			return ListBox.stopEvent(evt);
		}
		else
		{
			return true;
		}
	}
}

function ListBox_mouseDown(evt)
{
    //dbg("ListBox_mouseDown event");
	evt = (evt) ? evt : ((event) ? event : null);
	if (evt)
	{
		var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
		if (node)
		{
			//dbg("nodeName: " + node.nodeName);
		    if(node.nodeName.toLowerCase() == "td")
			{
				ListBox.mouseSelect(node);
			}
			else if(node.parentNode.nodeName.toLowerCase() == "td") //for Netscape
			{
				ListBox.mouseSelect(node.parentNode);
			}
			
		    return ListBox.stopEvent(evt);
		}
	}
}

function ListBox_mouseOver(evt)
{
	//dbg("ListBox_mouseOver event");
	
	/*
    var listbox = ListBoxHandler.activeListBox;
    if(listbox != null)
	{
   		evt = (evt) ? evt : ((event) ? event : null);
		if (evt)
		{
			var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
			if (node)
			{
				//dbg("id: " + node.id);
			    listbox.cancelBlur = true;
			}
		}
	}
	*/
}

function ListBox_mouseOut(evt)
{
	//dbg("ListBox_mouseOut event");
	
	evt = (evt) ? evt : ((event) ? event : null);
	if (evt)
	{
		var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
		if (node)
		{
		    //dbg("id: " + node.id);
		    if(evt.relatedTarget)
			{
				//dbg("relatedTarget: " + evt.relatedTarget.nodeName);
			}
		    else if (evt.toElement)
			{
				//dbg("toElement: " + evt.toElement.nodeName);
			}
		}
	}
}

function ListBox_handleBlur(evt)
{
	//dbg("ListBox_handleBlur event");
	
	var listbox = ListBoxHandler.activeListBox;
	
	listbox.deactivate();
	return ListBox.stopEvent(evt);
}

function ListBox_handleFocus(evt)
{
	//dbg("ListBox_handleFocus event");
	
	evt = (evt) ? evt : ((event) ? event : null);
	{
		var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
		if (node)
		{
			if(node.id.indexOf("_focus") != -1)
			{
				var strArray = node.id.split("_");
				var listbox = ListBoxHandler.all[strArray[0]];
				if(listbox != null)
				{
					listbox.activate();
				}
			}
		}
		
		return ListBox.stopEvent(evt);
	}
}

function ListBox_remove(index)
{
    this.options.remove(index)
}

function ListBox_activate()
{
	if(!this.disabled)
	{
	    if(!this.isActive)
		{
			ListBoxHandler.activeListBox = this;
			if (document.addEventListener)
			{
				document.addEventListener("keydown", ListBox_handleKeyDown, false );
			}
			else if(document.attachEvent)
			{
				document.attachEvent("onkeydown", ListBox_handleKeyDown);
			}
			
			this.isActive = true;
		}
		
		if(this.currentRow < 0)
		{
			this.opsTable.rows[0].cells[0].className = "listbox-item-selected";
			this.currentRow = 0;
		}
		else
		{
			if(this.opsTable.rows[this.currentRow].cells[0].className == "listbox-hilite")
			{
				this.opsTable.rows[this.currentRow].cells[0].className = "listbox-hilite-selected";
			}
			else
			{
				this.opsTable.rows[this.currentRow].cells[0].className = "listbox-item-selected";
			}
		}
	}
}

function ListBox_deactivate()
{
    //dbg("Deactivating the ListBox: " + this.name);
	
    if(this.isActive)
    {
	    ListBoxHandler.activeListBox = null;
	    if (document.removeEventListener)
		{
			document.removeEventListener("keydown", ListBox_handleKeyDown, false );
		}
		else if(document.detachEvent)
		{
			document.detachEvent("onkeydown", ListBox_handleKeyDown);
		}
		
		if(this.opsTable.rows[this.currentRow].cells[0].className == "listbox-hilite-selected")
		{
			this.opsTable.rows[this.currentRow].cells[0].className = "listbox-hilite";
		}
		else
		{
			this.opsTable.rows[this.currentRow].cells[0].className = "listbox-item";
		}
		
		this.isActive = false;
	}
}

function ListBox_add()
{
    var i,arglen;
    arglen=arguments.length
    for(i=0;i<arglen;i++)
	{
	    this.options[this.options.length]=arguments[i]
	}
}

function ListBox_hilite(rowNumber)
{
    this.opsTable.rows[this.currentRow].cells[0].className='listbox-item';
	this.opsTable.rows[rowNumber].cells[0].className='listbox-hilite';
	this.currentRow = rowNumber;
}

ListBox.mouseSelect = function(row)
{
	var listbox = ListBoxHandler.all[row.getAttribute("listboxName")];
	var rowNumber = parseInt(row.getAttribute("rowNumber"));
	var lastRowNum = listbox.currentRow;
	
	if(!listbox.multiple)
	{
		if(listbox.currentRow != rowNumber)
		{
			ListBox.select(listbox, rowNumber);
			listbox.opsTable.rows[rowNumber].cells[0].className = "listbox-hilite-selected";
			if(listbox.currentRow >= 0)
			{
				ListBox.unselect(listbox, listbox.currentRow);
				listbox.opsTable.rows[listbox.currentRow].cells[0].className = "listbox-item";
			}
			listbox.currentRow = rowNumber;
			if(listbox.onselect)
		    {
		    	listbox.onselect();
		    }
		}
	}
	else if(listbox.options[rowNumber].selected == false)
	{
		ListBox.select(listbox, rowNumber);
		if(lastRowNum >= 0 && lastRowNum != rowNumber)
		{
			var lastRow = listbox.opsTable.rows[lastRowNum].cells[0];
			if(lastRow.className == "listbox-hilite-selected" || lastRow.className == "listbox-hilite")
			{
				lastRow.className = "listbox-hilite";
			}
			else
			{
				lastRow.className = "listbox-item"
			}
		}
		listbox.opsTable.rows[rowNumber].cells[0].className = "listbox-hilite-selected";
		listbox.currentRow = rowNumber;
	}
	else
	{
		ListBox.unselect(listbox, rowNumber);
		if((lastRowNum != rowNumber) && (lastRowNum != -1))
		{
			var lastRow = listbox.opsTable.rows[lastRowNum].cells[0];
			if(lastRow.className == "listbox-hilite-selected" || lastRow.className == "listbox-hilite")
			{
				lastRow.className = "listbox-hilite";
			}
			else
			{
				lastRow.className = "listbox-item"
			}
		}
		listbox.opsTable.rows[rowNumber].cells[0].className = "listbox-item-selected";
		listbox.currentRow = rowNumber;
	}
}

ListBox.select = function(listbox, rowNumber)
{
	//dbg("ListBox.select");
	
	listbox.options[rowNumber].selected = true;
	listbox.numItemsSelected++;
	ListBox.rebuildInputValue(listbox);
}

ListBox.unselect = function(listbox, rowNumber)
{
	//dbg("ListBox.unselect");
	
	listbox.options[rowNumber].selected = false;
	listbox.numItemsSelected--;
	ListBox.rebuildInputValue(listbox);
}

ListBox.rebuildInputValue = function(listbox)
{
	var selectedRows = new Array();
	for(var i = 0; i < listbox.options.length; i++)
	{
		if(listbox.options[i].selected == true)
		{
			selectedRows[selectedRows.length] = i;
		}
	}
	listbox.inputElement.value = selectedRows.join();
}

ListBox.reset = function(listbox)
{
	//dbg("ListBox.reset");
	
	for(var i = 0; i < listbox.options.length; i++)
	{
		listbox.options[i].selected = false;
		listbox.opsTable.rows[i].cells[0].className = "listbox-item";
	}
	listbox.numItemsSelected = 0;
	listbox.inputElement.value = "";
}

ListBox.stopEvent = function(ev) {
	if (ListBox.isIE) {
		window.event.cancelBubble = true;
		window.event.returnValue = false;
	} else {
		ev.preventDefault();
		ev.stopPropagation();
	}
	return false;
}

ListBox.getNextTabElement = function(field)
{
	var fieldFound = false;
	var form = field.form;
	
	if(form == null)
	{
		return null;
	}
		
	if(form.length <= 1)
	{
		return null;
	}
	
	var nextElement = null;
	var fieldIndex = -1;
	for (var e = 0; (e < form.elements.length) && !fieldFound; e++) 
	{
		if (field == form.elements[e])
		{
			fieldFound = true;
			fieldIndex = e;
		}
	}
	
	var counter = 0;
	do
	{
		counter++;
		if(fieldIndex < (form.elements.length - 1))
		{
			nextElement = form.elements[++fieldIndex];
		}
		else
		{
			fieldIndex = 0;
			nextElement = form.elements[fieldIndex];
		}
	}
	while(nextElement.type == 'hidden' && counter < form.length)
	
	if(nextElement.type == 'hidden')
	{
		return null;
	}
	
	return nextElement;
}

ListBox.getPreviousTabElement = function(field)
{
	var fieldFound = false;
	var form = field.form;
	
	if(form == null)
	{
		return null;
	}
	
	if(form.length <= 1)
	{
		return null;
	}
	
	var nextElement = null;
	var fieldIndex = -1;
	for (var e = 0; (e < form.elements.length) && !fieldFound; e++) 
	{
		if (field == form.elements[e])
		{
			fieldFound = true;
			fieldIndex = e;
		}
	}
	
	var counter = 0;
	do
	{
		counter++;
		if(fieldIndex > 0)
		{
			nextElement = form.elements[--fieldIndex];
		}
		else
		{
			fieldIndex = form.elements.length - 1;
			nextElement = form.elements[fieldIndex];
		}
	}
	while(nextElement.type == 'hidden' && counter < form.length)
	
	if(nextElement.type == 'hidden')
	{
		return null;
	}
	
	return nextElement;
}

ListBox.getAbsolutePos = function(el)
{
	var r = { x: el.offsetLeft, y: el.offsetTop };
	if (el.offsetParent) {
		var tmp = ListBox.getAbsolutePos(el.offsetParent);
		r.x += tmp.x;
		r.y += tmp.y;
	}
	return r;
}

ListBox.isCharacterKey = function (keyCode)
{
	if(keyCode >= 65 && keyCode <=90) // A to Z
	{
		return true;
	}
	
	if(keyCode >= 48 && keyCode <= 57) // 0 to 9
	{
		return true;
	}	
	
	if(keyCode >= 96 && keyCode <= 107) // Numpad 0-9, *, +
	{
		return true;
	}
	
	if(keyCode >= 109 && keyCode <= 111) // Numpad -./
	{
		return true;
	}
	
	if(keyCode >= 186 && keyCode <= 192) // ;=,-./`
	{
		return true;
	}
	
	if(keyCode >= 219 && keyCode <= 222) // [\]'
	{
		return true;
	}
	
	return false;
}

ListBox.isIE = (document.attachEvent ? true : false);

ListBox.isNN = (document.addEventListener ? true : false);

function returnFalse()
{
	return false
}

function ListBoxItem(text,value)
{
    this.text  = text;
    this.value = value;
    this.selected = false;
}