// LyFormScript.js
// Copyright (c) 2000-2009, Lyria-W4.
// All rights reserved.
// @version	$Id: LyFormScript.js,v 1.10.4.3 2009/11/16 11:40:49 nha Exp $

var sourceParam = '_source';
var valueParam = '_value';
var typeParam = '_type';
var frameParam = '_frame';
var ajaxParam = '_ajax';
var pageParam = '_page';
var manageTabKey = false;

// This function submits the script form in order to reset the
// value field.
// field if a refence of an HTML element.
function FieldChange(form, field, controllerId, typeParamValue)
{
	// If default form is set, use the first form in page
	if ( form == "default" || (typeof form == "undefined"))
		form=document.forms[0];

	if (typeof field == "string")
		field = form.elements[field];

	if (form.elements[sourceParam] != null)
		form.elements[sourceParam].value = field.name;

	if (form.elements[valueParam] != null)
	{
		var newValue;

		if ( (typeof field.selectedIndex != "undefined") && (typeof field.options != "undefined") )
		{
			// For combo box : on Netscape field.value == "". We must use
			// field.selectedIndex instead (works with IE too).
			if ( (typeof field != "undefined")
				&& (typeof field.options != "undefined" )
				&& (typeof field.selectedIndex != "undefined" )
				&& (typeof field.options[field.selectedIndex] != "undefined" )
				&& (typeof field.options[field.selectedIndex].value != "undefined") )
				newValue = field.options[field.selectedIndex].value;
		}
		else
		{
			if (typeof field.value != "undefined")
				newValue = field.value;
			else //case of boolean choice
				newValue = form.elements[field].value;
		}

		form.elements[valueParam].value = newValue;
	}

	if (form.elements[typeParam] != null)
	{
		if ((typeof typeParamValue != "undefined")
				&& (typeParamValue != null)
				&& (typeParamValue != ""))
			form.elements[typeParam].value = typeParamValue;
		else
			form.elements[typeParam].value = "_checkField";
	}

	if (form.elements[frameParam] != null)
		form.elements[frameParam].value = this.name;

	// If there are different controllers managing the view, update the
	// controller input value
	var oldController = form.elements['_controller'].value;

	if (controllerId != null)
		form.elements['_controller'].value = controllerId;

	form.elements['_hidden'].value = 'true';

	// USE for STRUTS : add the page parameter if defined.
	// It is added to the action URL for backward compatibility
	if (((typeof pageWriterId) != "undefined") && (pageWriterId != null))
	{
		var formAction = form.action;
		if ((formAction != null) && (formAction != ""))
		{
			var pos = formAction.indexOf('?');
			if (pos <= 0)
				formAction += '?';
			formAction += pageParam + '=' + pageWriterId
			form.action = formAction;
		}
	}

	SendAjaxRequest(form);
	form.elements['_controller'].value = oldController;
}

// This function selects an option in a select component
function SelectOption(formName, fieldName, optionValue, select)
{
	var form = findForm(null, formName, fieldName);

	if (form == null)
		return;

	var field = form.elements[fieldName];

	if (typeof field == "undefined")
		return;

	var n = field.options.length;
	var option;

	for (var i = n - 1; i >= 0; i--)
	{
		option = field.options[i];

		if (option.value == optionValue)
		{
			option.selected = select;
			break;
		}
	}
}

// This function sets the value of an HTML field
function SetFieldValue(formName, fieldName, value)
{
	var form = findForm(null, formName, fieldName);

	if (form == null)
		return;

	var field = form.elements[fieldName];

	if (typeof field == "undefined")
		return;

	field.value = value;
}

// This function adds an option to a given select component
function AddSelectOption(formName, fieldName, optionValue, optionName, pos)
{
	var form = findForm(null, formName, fieldName);

	if (form == null)
		return;

	var field = form.elements[fieldName];

	if (typeof field == "undefined")
		return;

	var option = new Option(optionName);

	option.value = optionValue;

	if (pos < 0)
		pos = field.options.length;

	// Move all the options after inserted option
	if (pos < field.options.length)
	{
		for (var i = field.options.length; i > pos; i--)
		{
			var decal_option = new Option(field.options[i - 1].text);

			decal_option.value = field.options[i - 1].value;
			field.options[i] = decal_option;
		}
	}

	field.options[pos] = option;
}

// This function removes an option from a given select component
function RemoveSelectOption(formName, fieldName, optionValue)
{
	var form = findForm(null, formName, fieldName);

	if (form == null)
		return;

	var field = form.elements[fieldName];

	if (typeof field == "undefined")
		return;

	var n = field.options.length;
	var option;

	for (var i = n - 1; i >= 0; i--)
	{
		option = field.options[i];

		if (option.value == optionValue)
		{
			field.options[i] = null;
			break;
		}
	}
}

// This function selects checkbox (or radio) component
function SelectCheckbox(formName, fieldName, optionValue, select)
{
	var form = findForm(null, formName, fieldName);

	if (form == null)
		return;

	var field = form.elements[fieldName];

	if (typeof field == "undefined")
		return;

	var n = field.length;
	var option;

	// May occurs when there is only one radio button
	if (typeof n == "undefined")
	{
		field.checked = select;
		return;
	}

	for (var i = n - 1; i >= 0; i--)
	{
		option = field[i];

		if (option.value == optionValue)
		{
			option.checked = select;
			break;
		}
	}
}

function ClickOnDisabledComponent(message)
{
	alert(message);
}

// This function updates a multiple choice. The built value is send to
// to the servlet.
// default value is the value send when no option is checked. If nothing is specified
// defaultValues is ""
function UpdateMultipleChoice(form, fieldName, optName, sep, needCheck, controllerId, defaultValue)
{
	if (typeof form == "undefined")
		form = this.document.forms[0];

	var field = form.elements[fieldName];
	var opt = form.elements[optName];
	var i, n = opt.length;
	var first = true;

	// FFT00292
	// We are in a multiple choice, but if there is just one checkbox, the length properties
	// is undefined, so we must force n to 1
	if (typeof n == "undefined")
		n = 1;

	// Update the field value with the selected values
	if (defaultValue == null)
		defaultValue = "";

	field.value = defaultValue;
	if (n > 1)
	{
		for (i = 0; i < n; i++)
		{
			if (opt[i].checked == false)
				continue;

			if (!first)
				field.value += sep;

			field.value += opt[i].value;
			first = false;
		}
	}
	else
	{
		// single checkbox case
		if (opt.checked == true)
		{
			field.value = opt.value;
		}
	}

	if ( (typeof needCheck != "undefined") && (needCheck == true) )
	{
		FieldChange(form, field, controllerId);
	}
}

// This function updates a list. The built value is send to the servlet.
function UpdateList(form, fieldName, listName, sep, needCheck, controllerId)
{
	if (typeof form == "undefined")
		form = this.document.forms[0];

	var field = form.elements[fieldName];
	var list = form.elements[listName];
	var i, n = list.length;
	var first = true;

	// Update the field value with the selected values
	field.value = "";
	for (i = 0; i < n; i++)
	{
		if (list[i].selected == false)
			continue;

		if (!first)
			field.value += sep;

		field.value += list[i].value;
		first = false;
	}

	if ( (typeof needCheck != "undefined") && (needCheck == true) )
	{
		FieldChange(form, field, controllerId);
	}
}

// This function changes the state of a boolean field.
function ChangeBooleanState(form, fieldName, shownFieldName, imageName, textTag, optional,
	labelEmpty, labelFalse, labelTrue,
	imgEmpty, imgFalse, imgTrue, not)
{
	if (typeof form == "undefined")
		form = this.document.forms[0];

	var field = form.elements[fieldName];
	var shownField = form.elements[shownFieldName];

	// If shownValue is empty, the next value is always unchecked
	if (shownField.value == "EMPTY")
	{
		shownField.value = "UNCHECKED";
		field.value = (not ? "CHECKED" : "UNCHECKED");
		document.images[imageName].src = imgFalse;
		textTag.innerText = labelFalse;
	}
	// If shown value is unchecked, the next value is always checked
	else if (shownField.value == "UNCHECKED")
	{
		shownField.value = "CHECKED";
		field.value = (not ? "UNCHECKED" : "CHECKED");
		document.images[imageName].src = imgTrue;
		textTag.innerText = labelTrue;
	}
	// if shown value is checked and the field is optional, the next value is empty
	else if ((shownField.value == "CHECKED") && optional)
	{
		shownField.value = "EMPTY";
		field.value = "EMPTY";
		document.images[imageName].src = imgEmpty;
		textTag.innerText = labelEmpty;
	}
	else // if the shown value is checked and the field is not optional, the next value is unchecked
	{
		shownField.value = "UNCHECKED";
		field.value = (not ? "CHECKED" : "UNCHECKED");
		document.images[imageName].src = imgFalse;
		textTag.innerText = labelTrue;
	}
}

// This function changes the image of a boolean field.
function SwapBooleanImage(form, fieldName, imageName, imgEmpty, imgFalse, imgTrue)
{
	if (typeof form == "undefined")
		form = this.document.forms[0];

	var field = form.elements[fieldName];

	if (field.value == "UNCHECKED")
	{
		document.images[imageName].src = imgFalse;
	}
	else if (field.value == "EMPTY")
	{
		document.images[imageName].src = imgEmpty;
	}
	else
	{
		document.images[imageName].src = imgTrue;
	}
}

// This function give a full width to a cell in a table
function ExtendCellToFullWidth(cellId, tableId)
{
	var formCell = this.document.getElementById(cellId);
	var formTable = this.document.getElementById(tableId);

	if ((formCell == null) || (formTable == null))
		return;

	var cellWidth = cmGetWidth(formCell);
	var initialTableWidth = cmGetWidth(formTable);
	var tableWidth = initialTableWidth;
	var offset = 60;
	var maxSteps = 10;

	for (var i = 0; i < maxSteps; i++)
	{
		cellWidth = cellWidth - (-offset);

		formCell.style.width = cellWidth;
		tableWidth = cmGetWidth(formTable);

		if (tableWidth - 10 > initialTableWidth)
		{
			formCell.style.width = cellWidth - offset;
			break;
		}
	}
}

// This function refresh the content of an auto-completion component
function refreshAutoCompletion(formName, completionName, fieldName, values,
	selectColor, maxValues, width, event, controller, displayAllValues, allowUnknownValues)
{
	var key = (!document.all) ? event.which : event.keyCode;
	var form = findForm(null, formName, fieldName);

	if (form == null)
		return;

	var autoCompletionIndex = form.elements["AutoCompletionIndex_" + completionName];
	var autoCompletionIndexValue = autoCompletionIndex.value;
	var divObj = document.getElementById('AutoCompletion_' + completionName)
	var iframeObj = document.getElementById('AutoCompletionFrame_' + completionName);

	// Manage arrow down / up to select an item
    	if ((key == 40) || (key == 38))
    	{
		var previousTrObj = document.getElementById(completionName + autoCompletionIndexValue);
		var diff = (key == 40 ? -1 : 1);
		var trObj = document.getElementById(completionName + (autoCompletionIndexValue - diff));

		if (previousTrObj != null)
			previousTrObj.style.background = "#FFFFFF";

		if (trObj != null)
			trObj.style.background = selectColor;

		if ((previousTrObj != null) || (trObj != null))
			autoCompletionIndex.value = autoCompletionIndex.value - diff;

		if ((trObj != null) && (typeof(divObj.scrollIntoView) != "undefined"))
			trObj.scrollIntoView(false);

    		return;
    	}

	autoCompletionIndex.value = "-1";

	var idField = form.elements[fieldName];
	var field = form.elements[fieldName + "_text"];

	if (typeof field == "undefined")
		field = form.elements[fieldName];

	var startValue = field.value.toLowerCase();
	var html = "<table id=\"" + completionName + "_table\" width='" + width + "' border='0' bgColor='FFFFFF' cellspacing='0' cellpadding='3'>";
	var visibility = "hidden";
	var match = false;
	var nbValues = 0;
	var valueId, valueName, valueDisplayed;
	var rowColor;
	var matchIndex = -1;

	for (var i = 0; i < values.length; i++)
	{
		if ((maxValues > 0) && (nbValues >= maxValues))
			break;

		valueId = values[i][0];
		valueName = values[i][1];
		valueDisplayed = values[i][2];

		// Check if value start with field value (not case sensitive)
		if (valueDisplayed
			&& ((valueName.toLowerCase().indexOf(startValue) == 0) || displayAllValues))
		{
			var jsFieldName = ReplaceString(fieldName, "\\", "\\\\");
			var displayedValue = (valueName == "" ? "&nbsp;" : valueName);
			var javascriptValueId = ReplaceString(valueId, "\\", "\\\\");
			var javascriptValueName = ReplaceString(valueName, "\\", "\\\\");

			displayedValue = ReplaceString(displayedValue, "<", "&lt;");
			displayedValue = ReplaceString(displayedValue, ">", "&gt;");

			javascriptValueId = ReplaceString(javascriptValueId, "'", "\\'");
			javascriptValueId = ReplaceString(javascriptValueId, "\"", "&quot;");
			javascriptValueName = ReplaceString(javascriptValueName, "'", "\\'");
			javascriptValueName = ReplaceString(javascriptValueName, "\"", "&quot;");

			html += "<tr id=\"" + completionName + nbValues + "\"";

			rowColor = '#FFFFFF';

			if (!allowUnknownValues && (valueId == idField.value))
			{
				rowColor = selectColor;
				autoCompletionIndex.value = nbValues;
			}

			html += " bgColor='" + rowColor + "'";
			html += " onMouseOver=\"";
			html += "resetAutoCompletionBackground('" + formName + "','" + completionName + "','" + jsFieldName + "');";
			html += "this.style.background='" + selectColor + "'\"";
			html += " onMouseOut=\"this.style.background='" + rowColor + "'\"";
			html += " onMouseDown=\"setCompletionValue('" + formName + "', '" + completionName + "','" + jsFieldName + "','" +
				javascriptValueId + "','" + javascriptValueName + "','" + controller + "');\"";
			html += " style=\"cursor:default;\">";
			html += "<td valign='top' align='left' nowrap='yes'><font class='label'>" + displayedValue + "</font></td></tr>";
			visibility = "visible";

			if (valueName.toLowerCase().indexOf(startValue) == 0)
				match = true;

			if (!displayAllValues
					&& (valueName.toLowerCase() == startValue))
				matchIndex = i;

			if ((key == 13) && (autoCompletionIndexValue == nbValues))
			{
				setCompletionValue(formName, completionName, fieldName, valueId, valueName, controller);
			}

			nbValues++;
		}
	}

	html += "</table>";

	if (key == 13)
		visibility = "hidden";

	if (!match && !allowUnknownValues)
		setCompletionValue(formName, completionName, fieldName, "", null, null);
	else if ((matchIndex >= 0) && (nbValues == 1))
	{
		if (!allowUnknownValues)
			setCompletionValue(formName, completionName, fieldName, values[matchIndex][0], values[matchIndex][1], controller);

		visibility = "hidden";
	}

	divObj.innerHTML = html;
	divObj.style.visibility = visibility;

	if (visibility == "hidden")
		lastKeyEventTime = -1;
	else
		lastKeyEventTime = new Date().getTime() + 10000000;

	// If div contains a vertical scrollbar, reduce table width to avoid a horizontal
	// scrollbar to appear.
	if (divObj.clientHeight < divObj.scrollHeight)
	{
		var tableObj = document.getElementById(completionName + '_table');

		tableObj.width -= 16;
	}

	if (iframeObj != null)
		iframeObj.style.visibility = visibility;
}

// This function reset the background color of auto-completion div
function resetAutoCompletionBackground(formName, completionName, fieldName)
{
	var form = findForm(null, formName, fieldName);

	if (form == null)
		return;

	var autoCompletionIndex = form.elements["AutoCompletionIndex_" + completionName];
	var autoCompletionIndexValue = autoCompletionIndex.value;
	var trObj = document.getElementById(fieldName + autoCompletionIndexValue);

	autoCompletionIndex.value = "-1";

	if (trObj != null)
		trObj.style.background = "#FFFFFF";
}

// This function updates a text input with an auto-completion value
function setCompletionValue(formName, completionName, fieldName, valueId, valueName, controller)
{
	var form = findForm(null, formName, fieldName);

	if (form == null)
		return;

	var idField = form.elements[fieldName];
	var nameField = form.elements[fieldName + "_text"];

	idField.value = valueId;

	if ((typeof nameField != "undefined") && (valueName != null))
		nameField.value = valueName;

	hideAutoCompletion(formName, completionName, fieldName, controller);
	setTimeout("activateAutoCompletionText('" + formName + "','" + fieldName + "')", 300);
}

// This function gives the focus to a text input with an auto-completion value
function activateAutoCompletionText(formName, fieldName)
{
	var form = findForm(null, formName, fieldName);

	if (form == null)
		return;

	var field = form.elements[fieldName + "_text"];

	if (typeof field == "undefined")
		field = form.elements[fieldName];

	try
	{
		field.focus();
		SetEndCaret(field);
	}
	catch (ex)
	{
	}
}

// This function reset the focus state of an auto-completion component
function resetAutoCompletionFocus(formName, completionName)
{
	setAutoCompletionFocus(formName, "AutoCompletionFocus_" + completionName, 'true');
	setTimeout("setAutoCompletionFocus('" + formName + "', 'AutoCompletionFocus_" + completionName + "', false)", 300);
}

// This function set the focus state of an auto-completion component
function setAutoCompletionFocus(formName, fieldName, value)
{
	var form = findForm(null, formName, fieldName);

	if (form == null)
		return;

	var autoCompletionFocus = form.elements[fieldName];

	if (typeof autoCompletionFocus != "undefined")
		autoCompletionFocus.value = value;
}

// This function switch the visibility of an auto-completion component
function switchAutoCompletion(formName, completionName, fieldName, values,
	selectColor, maxValues, width, event, controller)
{
	var divObj = document.getElementById('AutoCompletion_' + completionName)

	if (divObj.style.visibility == "hidden")
	{
		refreshAutoCompletion(formName, completionName, fieldName, values, selectColor, maxValues, width, event, controller,
			true, false);
	}
	else
		hideAutoCompletion(formName, completionName, fieldName);

	activateAutoCompletionText(formName, fieldName);
}

// This function hides an auto-completion component with a timeout
function hideAutoCompletionTimeout(formName, completionName, fieldName, controller)
{
	setTimeout("hideAutoCompletion('" + formName + "', '" + completionName + "','" + fieldName + "', '" + controller + "')", 150);
}

var changedField = null;

// This function hides an auto-completion component immediatly
function hideAutoCompletion(formName, completionName, fieldName, controller)
{
	var form = findForm(null, formName, fieldName);

	if (form == null)
		return;

	var autoCompletionFocus = form.elements["AutoCompletionFocus_" + completionName];

	if ((typeof autoCompletionFocus != "undefined") && (autoCompletionFocus.value != "true"))
	{
		var divObj = document.getElementById('AutoCompletion_' + completionName)
		var iframeObj = document.getElementById('AutoCompletionFrame_' + completionName);

		divObj.style.visibility = 'hidden';
		lastKeyEventTime = -1;

		if (iframeObj != null)
			iframeObj.style.visibility = 'hidden';

		if ((controller != null) && (controller != "") && (controller != "undefined") && (controller != "null") && (typeof controller != "undefined"))
		{
			var field = form.elements[fieldName];

			// If a FieldChange is being sent, do not authorize modification of this field
			// but reset this value after 3 seconds.
			changedField = fieldName;
			setTimeout("changedField = null", 3000);

			FieldChange(form, field, controller);
		}
	}
}

var lastKeyEventTime = -1;
var keyHandlerTopFrame = null;

// This function captures return key on input fields and prevent return
function keyHandler (evt)
{
	var elem;

	if (!document.all)
		elem = (evt.target) ? evt.target : evt.srcElement;
	else
		elem = (event.target) ? event.target : event.srcElement;

	var key = (!document.all) ? evt.which : event.keyCode;
	var actionId = "";

	// If a FieldChange is being sent, do not authorize modification of this field
	if ((changedField != null)
			&& (elem != null)
			&& (elem.name == changedField)
			&& (key != 9))
		return false;

	// Firefox may send two events at the same time.
	if (new Date().getTime() - lastKeyEventTime < 50)
		return true;

	lastKeyEventTime = new Date().getTime();

    if (key == 13)
    {
		// Redirect return on text fields to the first command button.
		if ((elem.tagName == "INPUT")
			|| (elem.type == "text")
			|| (elem.type == "select-one"))
		{
			FieldChange('default', elem, '', '_validateField');
			return false;
      	}
   	}
   	// Manage tab key
   	else if ((key == 9) && manageTabKey)
   	{
   		var parent = elem;

   		while (parent != null)
   		{
	   		parent = parent.parentNode;

	   		if ((parent != null)
	   			&& (parent.tagName == "DIV")
	   			&& (parent.getAttribute("manageTabKey") != null))
	   		{
				if (!document.all)
					actionId = (evt.shiftKey) ? "_tabPrevious" : "_tabNext";
				else
					actionId = (event.shiftKey) ? "_tabPrevious" : "_tabNext";

		   		break;
			}
	   	}
   	}
   	// Manage alt + arrow up, down, left and right keys and alt + add key
   	else if (((key == 37) || (key == 38) || (key == 39) || (key == 40) || (key == 107) || ((key == 187) && window.event.shiftKey))
   			&& window.event.altKey
   			&& manageTabKey)
   	{
		if (key == 37)
			actionId = "_altLeft";
		else if (key == 38)
			actionId = "_altUp";
		else if (key == 39)
			actionId = "_altRight";
		else if (key == 40)
			actionId = "_altDown";
		else if ((key == 107) || (key == 187))
			actionId = "_altAdd";
	}
   	else if (key == 8)
   	{
   		// Manage Backspace key : disable when key is not pressed in an input field
   		// to avoid returning to previous page.
		var elem;

		if (!document.all)
    			elem = (evt.target) ? evt.target : evt.srcElement;
    		else
    			elem = (event.target) ? event.target : event.srcElement;

   		if (((elem.type == "text") || (elem.type == "textarea") || (elem.type == "password") || (elem.type == "file"))
   				&& !elem.disabled
				&& !elem.readOnly)
	   		return true;
	   	else
	   		return false;
   	}
   	else
   	{
		// Specific process
		if (keyHandlerTopFrame == null)
			keyHandlerTopFrame = getLeonardiTopFrame();

		if (keyHandlerTopFrame.specificKeyHandler)
			return keyHandlerTopFrame.specificKeyHandler((!document.all) ? evt : event);

     		return true;
	}

	if (actionId != "")
	{
   		// Manage tab key for editable tables
		var elem;

		if (!document.all)
    			elem = (evt.target) ? evt.target : evt.srcElement;
    		else
    			elem = (event.target) ? event.target : event.srcElement;

		if ((elem.tagName == "INPUT") || (elem.tagName == "SELECT") || (elem.tagName == "TEXTAREA"))
		{
			// Use a timeout to leave enough time to the valueChanged
			// event to be sent.
			var jsFieldName = ReplaceString(elem.name, "\\", "\\\\");

			setTimeout("FieldChange('default', '" + jsFieldName + "', '', '" + actionId + "')", 300);
		}

		return false;
	}
}
// Activate key capture for keyHandler
if (!document.all)
  document.captureEvents(Event.KEYDOWN);
document.onkeydown = keyHandler;
