
/*
 * @version Id: wizardEngine.js 08/mar/07
 * @package Parcelle
 * @copyright Copyright (C) 2010 - Tecnobit S.R.L. All rights reserved.
 * @license 
 * Created on 08/mar/07
 */

// some functions here are directly or transitive depending on insertSection() and updateSection()
// in treeEvents.js and listEvents.js

// refer to wizardEvents.js for global vars used in these scripts

/*
 * this function is called by endWizard(endOption) and updates all the attributes in the xml structure:
 *    <controls>
 * 	     <attribute id="attribute 1 id" type="attribute 1 type" value="attribute 1 value" />
 *       ....
 *    </controls>
 * setting the "value" attribute
 */ 
function updateSectionXML() {
	var controlValue = '';
	var doc = createDomParser(lastSectionControlsXML);	
	if (doc == null)
		return;
	var root = doc.getDocumentElement();
	
	var i, xmlChilds = root.getChildNodes();
	for (i = 0; i < xmlChilds.getLength(); i++) {
		var item = xmlChilds.item(i);
		var attributes = item.getAttributes();
		var controlId = '' + attributes.getNamedItem(TAG_CONTROL_ID).getNodeValue();		
		var controlType = '' + attributes.getNamedItem(TAG_CONTROL_TYPE).getNodeValue();				
		
		var control = $(controlId);
		switch (controlType) {
			case TAG_CONTROL_TYPE_SELECT:
				if (control.selectedIndex >= 0 && control.options.length > 0)
					attributes.getNamedItem(TAG_CONTROL_VALUE).setNodeValue(control.options[control.selectedIndex].value);
				else
					attributes.getNamedItem(TAG_CONTROL_VALUE).setNodeValue('');
				break;
			case TAG_CONTROL_TYPE_EDIT:
				controlValue = control.value;
				if (controlValue != null){
					controlValue = controlValue.replace(/'/g, "&#39;");
					// '
					controlValue = controlValue.replace(/"/g, "&#34;");
					// '
				}
				attributes.getNamedItem(TAG_CONTROL_VALUE).setNodeValue(controlValue);
				break;
			case TAG_CONTROL_TYPE_CHECKBOX:
				attributes.getNamedItem(TAG_CONTROL_VALUE).setNodeValue(control.checked ? "Y" : "N");
				break;
			case TAG_CONTROL_TYPE_RADIO:
				attributes.getNamedItem(TAG_CONTROL_VALUE).setNodeValue(control.checked ? "Y" : "N");
				break;
			case TAG_CONTROL_TYPE_HIDE:
				controlValue = control.value;
				if (controlValue != null){
					controlValue = controlValue.replace(/'/g, "&#39;");
					controlValue = controlValue.replace(/"/g, "&#34;");
				}
				attributes.getNamedItem(TAG_CONTROL_VALUE).setNodeValue(controlValue);
				break;				
		}
	}
	lastSectionControlsXML = doc.getXML();
}

// function called when the user clicks on the finish button of the wizard
function endWizard(endOption, isDemo) {
	setCursor("wait");
	demoMode = isDemo;
	//
	updateSectionXML();
	if (endOption == "newSection")
		evaluateNewSection();
	else if (endOption == "modSection")
		evaluateModifiedSection();
	else if (endOption == "adaptSection")
		evaluateAdaptSection();
}

function display(id) {
    
	// if (id == 'div256')
	// alert('display 256');
	
	$(id).style.visibility = 'visible';
	$(id).style.display = 'block';
}

function hide(id) {

	// if (id == 'div256')
	// alert('hide 256');

	$(id).style.visibility = 'hidden';
	$(id).style.display = 'none';
}

function toggleEnable(id) {

	$(id).disabled = !$(id).disabled;
}
function enable(id) {

	$(id).disabled = false;
}
function disable(id) {

	$(id).disabled = true;
}

function check(id) {

	$(id).checked = true;
}
function uncheck(id) {

	$(id).checked = false;
}

function lockEnable(ids) { 
    /*
	 * var status = "lockEnable - back: "; status +=
	 * document.getElementById("back").disabled ? "N" : "Y"; status += "
	 * forward: "; status += document.getElementById("forward").disabled ? "N" :
	 * "Y"; alert(status);
	 */

    // if(ids == null)
    // alert(ids);

    ids = "back-forward";
	var id = ids.split("-");
    
    /*
	 * if(id != "back,forward") { ids = "back-forward"; id = ids.split("-"); }
	 */

	// wizardButtonsState = "";
	var i;
	for (i = 0; i < id.length; i++) {
		var button = $(id[i]);// document.getElementById(id[i]);//
		if (button != null) {
			// wizardButtonsState += button.disabled ? "N" : "Y";
            // alert('buttons ' + wizardButtonsState);
			button.disabled = true;
		}
		else
        {
            // alert("ddd");
			wizardButtonsState = "X";
        }
		// if (i < id.length - 1)
		// wizardButtonsState += "-";
	}
    
    /*
	 * status = "lockEnable FINE - back: "; status +=
	 * document.getElementById("back").disabled ? "N" : "Y"; status += "
	 * forward: "; status += document.getElementById("forward").disabled ? "N" :
	 * "Y"; alert(status);
	 */   
}

function lockDisable(ids) {
    // var status = "lockDisable - back: ";
    // status += document.getElementById("back").disabled ? "N" : "Y";
    // status += " forward: ";
    // status += document.getElementById("forward").disabled ? "N" : "Y";
    // alert(status);

	
    // if(ids == null)
    // alert(ids);
    ids = 'back-forward';
	var id = ids.split("-");
   
    // alert(wizardButtonsState);
    var i;

    if(wizardButtonsState == "")
    {
        for (i = 0; i < id.length; i++)  
        {
            var button = document.getElementById(id[i]);// $(id[i]);
            if (button != null)    
            {
                 wizardButtonsState += button.disabled ? "N" : "Y";                           
            }
             if (i < id.length - 1)
                  wizardButtonsState += "-";             
        }        
    }
    
    var buttonsState = wizardButtonsState.split("-");
    
    // alert(wizardButtonsState);
    
	for (i = 0; i < id.length; i++) {
		var button = document.getElementById(id[i]);// $(id[i]);
		if (button != null)
        {         
			button.disabled = buttonsState[i] == "N" ? true : false;
        }
	}
    
    // status = "lockDisable FINE - back: ";
    // status += document.getElementById("back").disabled ? "N" : "Y";
    // status += " forward: ";
    // status += document.getElementById("forward").disabled ? "N" : "Y";
    // alert(status);
}

// handling of numeric editbox onchange to prevent non-valid chars to be
// inserted and out-of-bounds error
function editboxChange(controlId, isInteger, range, sign, action) {
	
	var control = $(controlId);
	var bound = range.split("-");

	var str = control.value;
	var i, len = str.length;
	var testBound;
	var showEditError;
	//
	if (control != null && control.title == "dontShowRangeError"){
		showEditError = false;
		control.title = "";
	}
	else
		showEditError = true;
		
	// For negative number change the value
	for (i = 0; i < bound.length; i++)  {
		bound[i] = bound[i].replace("N","-");
	}
	
	if (isInteger) {
		for (i = 0; i < len; i++) {
			if (str.charAt(i) < '0' || str.charAt(i) > '9') {
				if (sign != "Y" || str.charAt(i) != "-" || i > 0) {
					if (showEditError)
						alert("formato non valido: sono ammessi solo valori interi");
					control.value = bound[0];
					return;
				}
			}
  		}
	}
	else {
		var comma = 0, point = 0;
		for (i = 0; i < len; i++) {
			
			if ((i == 0 || i == len - 1) && (str.charAt(i) == ',' || str.charAt(i) == '.')) {
				if (sign != "Y" || str.charAt(i) != "-" || i > 0) {
					if (showEditError)
						alert("formato non valido");
					control.value = bound[0];
					return;
				}
			}
			if (str.charAt(i) == ',')
				comma++;
			if (str.charAt(i) == '.')
				point++;
			if (comma > 1 || point > 1 || comma == 1 && point == 1) {
				if (sign != "Y" || str.charAt(i) != "-" || i > 0) {
					if (showEditError)
						alert("formato non valido");
					control.value = bound[0];
					return;
				}
			}
			if (str.charAt(i) != ',' && str.charAt(i) != '.' && (str.charAt(i) < '0' || str.charAt(i) > '9')) {
				if (sign != "Y" || str.charAt(i) != "-" || i > 0) {
					if (showEditError)
						alert("formato non valido");
					control.value = bound[0];
					return;
				}
			}
		}
	}
	var strValue = control.value.replace(",", ".");
	var value = parseFloat(strValue);
	var fLowBound, fUpBound;
	
	fLowBound = bound[0].replace(",", ".");
	fLowBound = fLowBound.replace(",", ".");
	fLowBound = parseFloat(fLowBound);

	fUpBound = bound[1].replace(",", ".");
	fUpBound = fUpBound.replace(",", ".");
	fUpBound = parseFloat(fUpBound);	
	
	// allow negative values
	// if (sign == "Y")
	// value = Math.abs(value);
	if (value < (fLowBound) || value > (fUpBound)) {	
		if (showEditError)
			alert("Inserire un valore compreso tra " + bound[0] + " e " + bound[1]);
		control.value = value < fLowBound ? bound[0] : bound[1];
		return;
	}
	// if is correct value
	if (action != ''){
		updateControls(TAG_CONTROL_TYPE_EDIT, controlId, action);
		
		// doEditBoxAction(action);
		//
		updateForwardButtonPrompt();
	}
}
 
//
// this function get the action for an editbox and do a specific action
//
/* CPERON TO REMOVE */
function doEditBoxAction(action){
	var mutex, to;
	var i, j;	
	// first split into commands
	var actions = action.split(";");
	for (i = 0; i < actions.length; i++) {
		mutex = to = '';
		
		var parts = actions[i].split(" ");
		for (j = 0; j < parts.length; j++) {
		
			var tokens = parts[j].split("=");
			if (tokens.length != 2) {
				alert('wizardEvents.js::doEditBoxAction('+ action +') ERROR: wrong handler format');
				return;
			}

			if (tokens[0] == TAG_CONTROL_MUTEX)
				mutex = tokens[1];
			if (tokens[0] == TAG_CONTROL_TO)
				to = tokens[1];
				
		}
		if (mutex != "" && to != "")
			mutexControl("", "", mutex,to, "");
	}		
}

/*
 * this function fills the option array of a select control with the xml
 * returned by the ajax call param.responseText structure: <select id="id_dest">
 * <option id="id_option">text</option> .... </select>
 */
function setComboboxOptions(param) {
	// alert(param.responseText);
	
	var doc = createDomParser(param.responseText);
	if (doc == null)
		return;
	var root = doc.getDocumentElement();

	dumpString(param.responseText, 1);
	
	var item = root;

	// retireving destination combobox
	var attributes = item.getAttributes();
	var destId = '' + attributes.getNamedItem("id").getNodeValue();

	// alert(item.getXML());
	// ---------------------- access to pending operations XML to update values
	// -------------------------
	// alert(pendingOperations);
	var pendingValue = '';
	var operationsDoc = createDomParser(pendingOperations);
	if (operationsDoc == null) {
		return;
	}
	var operationsRoot = operationsDoc.getDocumentElement();

	var operations = operationsRoot.getChildNodes();
	for (i = 0; i < operations.getLength(); i++) {
	
		attributes = operations.item(i).getAttributes();
		if (attributes.getNamedItem("id").getNodeValue() == destId) {
		
			pendingValue = attributes.getNamedItem("value").getNodeValue();
			operationsRoot.removeChild(operations.item(i));
			// alert(operationsRoot.getXML());
		}
	}
	pendingOperations = operationsRoot.getXML();
	// ----------------------------------------------------------------------------------------------------
		
	// empty combobox
	var control = $(destId);
	control.options.length = 0;
	
	// fill with new values
	var xmlChilds = item.getChildNodes();
	for (i = 0; i < xmlChilds.getLength(); i++) {
		
		var optionId = '' + xmlChilds.item(i).getAttributes().getNamedItem("id").getNodeValue();
		var optionValue = '' + xmlChilds.item(i).getFirstChild().getNodeValue();

		control.options[i] = new Option(optionValue, optionId);
		if (optionId == pendingValue)
			control.selectedIndex = i;
	}
	fireChangeEvent(control);
}



// this function requests the new xml content to refresh the combobox indexed by
// destId
// destId can be a list of controls on the form: x-y-...-z
function refreshCombobox(uses, srcId, destId) {

	// alert("uses="+uses+";src="+srcId+";dest="+destId);
	
	var selection = '';
	if (uses != "") {
		var i, use = uses.split("-");
		for (i = 0; i < use.length; i++) {		
			var control = $(use[i]);
			selection = selection + control.options[control.selectedIndex].value + "-";
		}		
	}

	var src = $(srcId);
	var id;
	// CPERON
	if (src.selectedIndex > -1 && src.selectedIndex < src.length) {
		id = src.options[src.selectedIndex].value;
		selection = selection + id;
		
		var pars = 'action=comboboxChange&itemId=' + lastSectionItem + '&selection=' + selection + '&destId=' + destId;
		// CPERON
		new Ajax.Request("wizardCallback.php", {
			method: 'get',
			parameters: pars,
			onFailure: reportError,
			onComplete: setComboboxOptions
		});
	}
}

// this code handles 'forward' button text, that has to be changed if the last
// active page is set by a select
// control
function updateForwardButtonPrompt() {

	var doc = createDomParser(lastSectionFormsXML);	
	if (doc == null)
		return;
	var root = doc.getDocumentElement();

	if (wizardPage == '') {
		// if it is the first time that user presses a button button, load first
		// page id
		// wizard has at least one page so this is correct
		wizardPage = '' + root.getChildNodes().item(0).getAttributes().getNamedItem("id").getNodeValue();
	}
	//
	$('forward').value = isLast(root, wizardPage) ? "Fine" : "avanti";
}

function updateSelector(srcId, selector){

	// selector: "optId&dstId&rule-optId&dstId&rule-optId&dstId&rule..."
	// alert(srcId + ": " + selector);
	updateForwardButtonPrompt();
	
	var src = $(srcId);
	var id = src.options[src.selectedIndex].value;
	// relations: "optId&dstId&rule"
	var i, relations = selector.split("-");
	for (i = 0; i < relations.length; i++) {
	
		var values = relations[i].split("&");
		// alert(relations[i] + " " + values.length);
		if (id == values[0] && values[1] == TAG_FORM_DYN_RULE_ALLOW || 
			id != values[0] && values[1] == TAG_FORM_DYN_RULE_BLOCK)
			display("div" + values[2]);
		else
			hide("div" + values[2]);
	}
}
/*
 * this function handle a generic mutex event. destId, is the control to mutex.
 * to rapresent a trivial formula used to update value of destination control
 */
function mutexControl(srcId, srcType, destId, to, when) {
	try{					
		var srcControl;	
		var control = $(destId);	
		
		if (srcId != "")
			srcControl = $(srcId);
			
		if (control != null){
			if (control.tagName == "SELECT"){				
				try{					
					var controlToCopy = $(to);
					if (controlToCopy != null){
						// during initWizard prevent mutex action
						if (controlToCopy.title != "notMutex"){
							if (controlToCopy.selectedIndex > -1 && control.selectedIndex != controlToCopy.selectedIndex){
								if (controlToCopy.selectedIndex < control.options.length){
									// copy master value
									control.selectedIndex = controlToCopy.selectedIndex;
									// performe a change event to change slave
									// control
									fireChangeEvent(control);
								}
							}
						}
						else
						{
							// set title to "" otherwise mutex action doesn't
							// perform.
							controlToCopy.title = "";
						}
					}
				}
				catch (e){
					alert("Mutex Control SELECT Error:\tdest:\t" + destId + "\tformula:\t" + to);
				}
			}
			else {					
				switch (srcType) {
					case TAG_CONTROL_TYPE_CHECKBOX:
						try{
                            if (srcControl.checked && when == TAG_FORM_DYN_RULE_CHECK || !srcControl.checked && when == TAG_FORM_DYN_RULE_UNCHECK){
                                if (srcControl.title != "notMutex"){
                                    /* var value = getValueFromFormula(to); */
                                    var value = getCalculatedFunctionValue(to);
                                    if (control.type=="checkbox"){
                                            if (control.checked != value){
                                                    fireCheckboxEvent(control, value);
                                            }
                                            // fireCheckboxEvent(control,
											// value);
                                            // control.checked = value;
                                            // fireClickEvent(control);
                                    }
                                    else{
                                            control.value = value;
                                            fireChangeEvent(control);
                                    }
                                    control.title = "dontShowRangeError";
                                }
                            }
						}
						catch(e){
							alert("Mutex Control Error:" + TAG_CONTROL_TYPE_CHECKBOX + "\n" + e);
						}															
						break;
					case TAG_CONTROL_TYPE_RADIO:
						try{
							if (srcControl.title != "notMutex"){
								var toControl = $(to);
								//
								if (toControl != null){
									if (toControl.checked){
										control.checked = true;
									}
									else{
										control.checked = false;
									}
								}
								else{
									control.checked = getCalculatedFunctionValue(to);
								}
								fireChangeEvent(control);
							}
						}
						catch(e){
							alert("Mutex Control Error:" + TAG_CONTROL_TYPE_RADIO + "\n" + e);
						}						
						break;
				default:
					if (control.type.toUpperCase() == TAG_CONTROL_TYPE_CHECKBOX.toUpperCase()){
						try{
							control.checked = getCalculatedFunctionValue(to);
							fireChangeEvent(control);
						}
						catch(e){
							alert("Mutex Control Error:" + TAG_CONTROL_TYPE_CHECKBOX + "\n" + e);
						}						
					}
					else{
						try{
							// var value = getValueFromFormula(to);
							var value = getCalculatedFunctionValue(to);
							control.value = value;
							control.title = "dontShowRangeError";
							fireChangeEvent(control);
						}
						catch(e){
							alert("Mutex Control Error:\tformula:\t" + to + "\n" + e);
						}
					}					
					break;
				}
			}
		}
	}
	catch(e){
		alert("Error in mutex control\n" + e);
	}
}

function getValueFromFormula(formula){	
	var value = -1;
	if (formula != null){
		if (formula != ""){
			try{
				value = calculateValueFromFormula(formula, '-');
				if (value == -1)
					value = calculateValueFromFormula(formula, '+');
				if (value == -1)
					value = calculateValueFromFormula(formula, '/');
				if (value == -1)
					value = calculateValueFromFormula(formula, '*');
				if (value == -1)
					value = $(formula).value;
			}
			catch(e){
				value = -1;
				alert("getValueFromFormula:\tformula:\t" + formula + "\n" + e);
			}
		}			
	}
	return value;
}

function calculateValueFromFormula(formula, operation){
	var value = -1;
	var array;
	//
	index = formula.indexOf(operation);
	//
	if (index > 0){
		array = formula.split(operation);
		if (array != null)
			if (array.length > 1){
				
				switch(operation) {
					case '-':
						value = $(array[0]).value - $(array[1]).value;
						break;
					case '+':
						value = $(array[0]).value + $(array[1]).value;
						break;
					case '*':
						value = $(array[0]).value * $(array[1]).value;
						break;
					case '/':
						value = $(array[0]).value / $(array[1]).value;
						break;					
					default:
						break;					
				}				
			}
	}
	return value;
}

// this function handles two checkboxes firing events each one to the other,
// preventing loops
// this code uses some tricks to do the job. Don't change it before asking me
function updateMutexCheckbox(srcId, destId, set, when) {

	// alert("src=" + srcId + ";dest=" + destId + ";set=" + set + ";when=" +
	// when + ";state=" + mutexCheckboxState);
	if (mutexCheckboxState == 0) {
	
		src = $(srcId);
		dest = $(destId);
		
		if (when == TAG_FORM_DYN_RULE_CLICK) {
		
			// positive logic
			if (set == TAG_FORM_DYN_RULE_CHECK) {
				if (dest.checked != src.checked) {
					// make equal
					mutexCheckboxState = 1;
					fireCheckboxEvent(dest, src.checked);
				}
	
			}
			// negative logic
			else {
				if (dest.checked == src.checked) {
				
					// make not equal
					mutexCheckboxState = 1;
					fireCheckboxEvent(dest, !src.checked);
				}
			}
		}
		else if (src.checked && when == TAG_FORM_DYN_RULE_CHECK ||
			    !src.checked && when == TAG_FORM_DYN_RULE_UNCHECK) {
			
			if (set == TAG_FORM_DYN_RULE_CHECK && !dest.checked)
			
				fireCheckboxEvent(dest, true);
			
			else if (set == TAG_FORM_DYN_RULE_UNCHECK && dest.checked)
			
				fireCheckboxEvent(dest, false);
		}
	}
	else
		mutexCheckboxState = 0;
}

// this function handles interaction between controls
function updateControlsState(srcType, srcId, matchValue, commands, rule) {

	// alert("type="+srcType+";id="+srcId+";matchValue="+matchValue+";commands="+commands+";rule="+rule);
	var src = $(srcId);
	if (srcType == TAG_CONTROL_TYPE_SELECT) {

		updateForwardButtonPrompt();
				
		// 11001: <attribute id="103" name="Esecuzione dell'opera" type="select"
		// commands="300" rule="block" match="1">
		if (rule == TAG_FORM_DYN_RULE_ALLOW || rule == TAG_FORM_DYN_RULE_BLOCK) {
			var index = src.selectedIndex;
			if (src.options.length > index  && index > -1)
			{			
				var id = src.options[index].value;
				var i, control = commands.split("-");
				var matches = matchValue.split("-");
				if (control != null)
					for (i = 0; i < control.length; i++) {
						for (j = 0; j < matches.length; j++) {
							if (id == matches[j] && rule == TAG_FORM_DYN_RULE_ALLOW || id != matches[j] && rule == TAG_FORM_DYN_RULE_BLOCK)
								display("div" + control[i]);
							else
								hide("div" + control[i]);
						}
					}
			}
		}
		else if (rule == TAG_FORM_DYN_RULE_CHECK || rule == TAG_FORM_DYN_RULE_UNCHECK) {
			var id = src.options[src.selectedIndex].value;
			var i, control = commands.split("-");
				
			for (i = 0; i < control.length; i++) {
				if (atLeastOneMatch(id, matchValue)){					
					if (rule == TAG_FORM_DYN_RULE_CHECK){
						// if not checked than check
						if (!$(control[i]).checked){
							fireCheckboxEvent($(control[i]), true);
						}
					}
					else{
						// if checked than uncheck
						if ($(control[i]).checked){
							fireCheckboxEvent($(control[i]), false);
						}
					}
				}
				// in case of wizard initiated, if not values are matched, fire
				// an uncheck event.
				// Only uncheck action is performed.
				// There are some commands that check some checkboxes if a value
				// match. In case of value doesn't match an uncheck is
				// performed.
				// This is normal flow in parcelle online.
				// Command example:
				// commands=200-201-202-203-204-205-206-207-208-209 rule=check
				// match=1
				if (initWizardDone){
					if (!atLeastOneMatch(id, matchValue)){
						if (rule == TAG_FORM_DYN_RULE_CHECK){
							if ($(control[i]).checked){
								fireCheckboxEvent($(control[i]), false);
							}		
						}
					}
				}		
			}			
			/*
			 * var id = src.options[src.selectedIndex].value; var i, control =
			 * commands.split("-"); for (i = 0; i < control.length; i++) {
			 * 
			 * if (!$(control[i]).checked && (id == matchValue))
			 * fireCheckboxEvent($(control[i]), true);
			 * 
			 * if (initWizardDone) if ($(control[i]).checked && (id !=
			 * matchValue)) fireCheckboxEvent($(control[i]), false);
			 * 
			 * //if ($(control[i]).checked != (id == matchValue)) //
			 * fireCheckboxEvent($(control[i]), id == matchValue); }
			 */
		}
		else if (rule == TAG_FORM_DYN_RULE_SHOW || rule == TAG_FORM_DYN_RULE_HIDE) {
                    var i, control = commands.split("-");
                    if (isAFunctionString(matchValue)){
                        var isMatch = getCalculatedFunctionValue(matchValue);
                        if (control != null){
                            for (i = 0; i < control.length; i++) {
                                if (isMatch){
                                    if (rule == TAG_FORM_DYN_RULE_SHOW)
                                        display("div" + control[i]);
                                    else if (rule == TAG_FORM_DYN_RULE_HIDE)
                                        hide("div" + control[i]);
                                }
                            }
                        }
                    }
                    else{
                        var index = src.selectedIndex;
                        if (src.options.length > index  && index > -1)
                        {
                            var id = src.options[index].value;                            
                            var matches = matchValue.split("-");
                            if (control != null){
                                for (i = 0; i < control.length; i++) {
                                    for (j = 0; j < matches.length; j++) {
                                        if (id == matches[j]){
                                            if (rule == TAG_FORM_DYN_RULE_SHOW)
                                                display("div" + control[i]);
                                            else if (rule == TAG_FORM_DYN_RULE_HIDE)
                                                hide("div" + control[i]);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
		else if (rule == TAG_FORM_DYN_RULE_ENABLE || rule == TAG_FORM_DYN_RULE_DISABLE){
			var index = src.selectedIndex;
			if (src.options.length > index  && index > -1){
				var id = src.options[index].value;
				var i, control = commands.split("-");				
				if (id == matchValue && rule == TAG_FORM_DYN_RULE_ENABLE || id != matchValue && rule == TAG_FORM_DYN_RULE_DISABLE)
					for (i = 0; i < control.length; i++)
						enable(control[i]);
				else
					for (i = 0; i < control.length; i++)
						disable(control[i]);
			}			
		}
	}	
	else if (srcType == TAG_CONTROL_TYPE_CHECKBOX){
	
		updateForwardButtonPrompt();

		var state = src.checked ? "Y" : "N";
		var control = commands.split("-");
		var i;
		
		// 11001: <attribute id="400" name="Aggiornamento prezzi"
		// type="checkbox" default="N" commands="401-402-403" rule="hide"
		// match="N" />
		if (rule == TAG_FORM_DYN_RULE_SHOW || rule == TAG_FORM_DYN_RULE_HIDE) {
			/*
			 * if (state == matchValue && rule == TAG_FORM_DYN_RULE_SHOW ||
			 * state != matchValue && rule == TAG_FORM_DYN_RULE_HIDE)
			 */
			if (state == matchValue && rule == TAG_FORM_DYN_RULE_SHOW || 
				state != matchValue && rule == TAG_FORM_DYN_RULE_HIDE)
				for (i = 0; i < control.length; i++)
					display("div" + control[i]);
			else
				for (i = 0; i < control.length; i++)
					hide("div" + control[i]);
		}
		// 11001: <attribute id="206" name="Direzione lavori" type="checkbox"
		// commands="210" set="uncheck" when="check"/>
		else if (rule == TAG_FORM_DYN_RULE_CHECK || rule == TAG_FORM_DYN_RULE_UNCHECK) {
			// this code uses some tricks to do the job. Don't change it before
			// asking me
			if (matchValue == TAG_FORM_DYN_RULE_CLICK) {
				//
				if (rule == TAG_FORM_DYN_RULE_CHECK) {
					for (i = 0; i < control.length; i++) {
						if ($(control[i]).checked != src.checked)
							fireCheckboxEvent($(control[i]), src.checked);
					}
				}
				if (rule == TAG_FORM_DYN_RULE_UNCHECK) {
					for (i = 0; i < control.length; i++) {
						if ($(control[i]).checked == src.checked)
							fireCheckboxEvent($(control[i]), !src.checked);
					}
				}
			}
			else if (src.checked && matchValue == TAG_FORM_DYN_RULE_CHECK ||
			        !src.checked && matchValue == TAG_FORM_DYN_RULE_UNCHECK) {
				
				if (rule == TAG_FORM_DYN_RULE_CHECK) {				
					for (i = 0; i < control.length; i++) {
				 		// if (!$(control[i]).checked || ($(control[i]).checked
						// && $(control[i]).type == "radio"))
				 		if (!$(control[i]).checked)
							fireCheckboxEvent($(control[i]), true);
					}
				}
				else if (rule == TAG_FORM_DYN_RULE_UNCHECK) {				
					for (i = 0; i < control.length; i++) {
				 		if ($(control[i]).checked)
							fireCheckboxEvent($(control[i]), false);
					}
				}
			}		
		}
		// 11001: <attribute id="202" name="Progetto esecutivo" type="checkbox"
		// commands="200-201" rule="enable" match="Y"/>
		else if (rule == TAG_FORM_DYN_RULE_ENABLE || rule == TAG_FORM_DYN_RULE_DISABLE) {
			
			if (state == matchValue && rule == TAG_FORM_DYN_RULE_ENABLE || 
				state != matchValue && rule == TAG_FORM_DYN_RULE_DISABLE)
				for (i = 0; i < control.length; i++)
					enable(control[i]);
			else
				for (i = 0; i < control.length; i++)
					disable(control[i]);
		}
	}
	else if (srcType == TAG_CONTROL_TYPE_RADIO){
		// 11002: <attribute id="201" type="radio" group="radiogroup2"
		// default="Y" commands="202-204" name="Collaudo nominato all'inizio
		// dell'appalto con obbligo di visite periodiche (art. 19-d)" />
		
		// updateForwardButtonPrompt();
		
		var state = src.checked ? "Y" : "N";
		var control = commands.split("-");
		var i;
		for (i = 0; i < control.length; i++) {
			if (rule == TAG_FORM_DYN_RULE_ENABLE || rule == TAG_FORM_DYN_RULE_DISABLE) {
				// the first control is set to a state and the others to the
				// opposite state
				if (i == 0 && rule == TAG_FORM_DYN_RULE_ENABLE || i > 0 && rule == TAG_FORM_DYN_RULE_DISABLE)
					enable(control[i]);
				else
					disable(control[i]);
			}
			else 
			{
				if (rule == TAG_FORM_DYN_RULE_SHOW || rule == TAG_FORM_DYN_RULE_HIDE) {
					/*
					 * if (state == matchValue && rule == TAG_FORM_DYN_RULE_SHOW ||
					 * state != matchValue && rule == TAG_FORM_DYN_RULE_HIDE)
					 */
					
					if (state == matchValue && rule == TAG_FORM_DYN_RULE_SHOW ){
						for (i = 0; i < control.length; i++)
							display("div" + control[i]);
					}
					
					if (state == matchValue && rule == TAG_FORM_DYN_RULE_HIDE ){
						for (i = 0; i < control.length; i++)
							hide("div" + control[i]);
					}

					if (state != matchValue && rule == TAG_FORM_DYN_RULE_SHOW){
						for (i = 0; i < control.length; i++)
							hide("div" + control[i]);						
					}

					if (state != matchValue && rule == TAG_FORM_DYN_RULE_HIDE ){
						for (i = 0; i < control.length; i++)
							display("div" + control[i]);
					}
				}
			}			
		}
	}
	else if (srcType == TAG_CONTROL_TYPE_EDIT || srcType == TAG_CONTROL_TYPE_HIDE){
		if (rule == TAG_FORM_DYN_RULE_SHOW || rule == TAG_FORM_DYN_RULE_HIDE) {
            var i, control = commands.split("-");
            if (isAFunctionString(matchValue)){
                var isMatch = getCalculatedFunctionValue(matchValue);
                if (control != null){
                    for (i = 0; i < control.length; i++) {
                        if (isMatch){
                            if (rule == TAG_FORM_DYN_RULE_SHOW)
                                display("div" + control[i]);
                            else if (rule == TAG_FORM_DYN_RULE_HIDE)
                                hide("div" + control[i]);
                        }
                    }
                }
            }
            else{
                var id = src.value;                            
                var matches = matchValue.split("-");
                if (control != null){
                    for (i = 0; i < control.length; i++){
                    	if (dojo.some(matches, function(item){
                    		return item == id
                    		}, id)){
                            if (rule == TAG_FORM_DYN_RULE_SHOW)
                                display("div" + control[i]);
                            else if (rule == TAG_FORM_DYN_RULE_HIDE)
                                hide("div" + control[i]);                    		
                    	}
                    	else{
                            if (rule == TAG_FORM_DYN_RULE_SHOW)
                                hide("div" + control[i]);
                            else if (rule == TAG_FORM_DYN_RULE_HIDE)
                                display("div" + control[i]);                    		
                    	}
                    }
                }
            }
        }
	}
	
	// alert(srcId + "[" + id + "=" + matchValue + "] commands " + commands + "
	// with rule " + rule);
}

// action is a string like this : "commands=200-201 rule=enable
// match=Y;commands=252 rule=hide match=N;commands..."
function updateControls(srcType, srcId, action) {
	var change, mutex, commands, rule, match, set, when, uses, to;
	var i, j, k;
	
	// first split into commands
	var actions = action.split(";");
	for (i = 0; i < actions.length; i++) {
	
		// retrieve commands parts
		// commands='200-201'
		// rule='enable'
		// match='Y'
		change = mutex = commands = rule = match = set = when = uses = to = '';
		
		var parts = actions[i].split(" ");
		for (j = 0; j < parts.length; j++) {		
			var tokens = parts[j].split("=");
			if (tokens.length != 2) {
				alert('wizardEvents.js::updateControls(' + srcType + ', ' + srcId + ', ' + action + ') ERROR: wrong handler format');
				return;
			}

			if (tokens[0] == TAG_CONTROL_CHANGE)
				change = tokens[1];
			if (tokens[0] == TAG_CONTROL_COMMANDS)
				commands = tokens[1];
			if (tokens[0] == TAG_CONTROL_RULE)
				rule = tokens[1];
			if (tokens[0] == TAG_CONTROL_MATCH)
				match = tokens[1];
			if (tokens[0] == TAG_CONTROL_MUTEX)
				mutex = tokens[1];
			if (tokens[0] == TAG_CONTROL_SET)
				set = tokens[1];
			if (tokens[0] == TAG_CONTROL_WHEN)
				when = tokens[1];
			if (tokens[0] == TAG_CONTROL_USES)
				uses = tokens[1];
			if (tokens[0] == TAG_CONTROL_TO)
				to = tokens[1];				
		}
		if (change != "") {		
			refreshCombobox(uses, srcId, change);
		}
		if (rule != "" && match != "") {
			updateControlsState(srcType, srcId, match, commands, rule);
		}
		else if (set != "" && when != "") {
			if (mutex != "")
				updateMutexCheckbox(srcId, mutex, set, when);
			else
				updateControlsState(srcType, srcId, when, commands, set);
		}
		//		
		if (mutex != "" && to != ""){
			mutexControl(srcId, srcType, mutex,to, when);			
		}			
	}
}

// FUNCTIONS FOR WIZARD NAVIGATION
 
// checks if the condition exists
function hasGuardCondition(attrs){	
    // alert(attrs.getNamedItem(TAG_FORM_DYN_SRCID) + " " +
	// attrs.getNamedItem(TAG_FORM_DYN_RULE));
    if ((attrs.getNamedItem(TAG_FORM_DYN_SRCID) != null || attrs.getNamedItem(TAG_FORM_DYN_CONDITION))
            && attrs.getNamedItem(TAG_FORM_DYN_RULE) != null)
            return true;
    return false;
}

// returns true if condition matches
function checkCondition(attributes){
    var attribute;
    var srcControlId;
    var srcControlRule;
    var pageCondition;
    //
    attribute = attributes.getNamedItem(TAG_FORM_DYN_SRCID);
    if (attribute != null){
        srcControlId = '' + attribute.getNodeValue();
    }
    //
    attribute = attributes.getNamedItem(TAG_FORM_DYN_RULE);
    if (attribute != null){
        srcControlRule = '' + attribute.getNodeValue();
    }

    attribute = attributes.getNamedItem(TAG_FORM_DYN_CONDITION);
    if (attribute != null){
        pageCondition = '' + attribute.getNodeValue();
    }
    //
    var control = $(srcControlId);
    //
    if (control == null && pageCondition == null)
        return true;
    // if the page is allowed, return false, else continue iteration

    // page commanded by a select input
    if (attributes.getNamedItem(TAG_FORM_DYN_SRCVALUE) != null){
            var ctrlValue;
            var srcControlValue = '' + attributes.getNamedItem(TAG_FORM_DYN_SRCVALUE).getNodeValue();
            //
            if (control.tagName == null || control.tagName.toUpperCase() == TAG_CONTROL_TYPE_SELECT.toUpperCase()){
                ctrlValue = control.options[control.selectedIndex].value;
            }
            else{
                var ctrlType = control.type.toUpperCase();
                switch (ctrlType){
                    case TAG_CONTROL_TYPE_RADIO.toUpperCase():
                        if (control.checked){
                            ctrlValue = "true";
                        }
                        else{
                            ctrlValue = "false";
                        }
                        break;
                    case TAG_CONTROL_TYPE_TEXT.toUpperCase():
                        ctrlValue = control.value;
                        break;
                    default:
                        ctrlValue = control.checked;
                        break;
                }
            }
            //
            if (srcControlValue == ctrlValue && srcControlRule == TAG_FORM_DYN_RULE_ALLOW ||
                    srcControlValue != ctrlValue && srcControlRule == TAG_FORM_DYN_RULE_BLOCK)
                    return true;
    }
    else if (pageCondition != null){
        var conditionValue = getCalculatedFunctionValue(pageCondition);
        if (conditionValue == true && srcControlRule == TAG_FORM_DYN_RULE_ALLOW ||
            conditionValue == false && srcControlRule == TAG_FORM_DYN_RULE_BLOCK)
                return true;
    }
    else {
        // page commanded by a checkbox input
        if (control.checked && srcControlRule == TAG_FORM_DYN_RULE_CHECK ||
           !control.checked && srcControlRule == TAG_FORM_DYN_RULE_UNCHECK)
           return true;
    }
    return false;
}

// a page is the first page if it is the first in the XML or if it is the first
// page allowed by the conditions
function isFirst(root, page) {

	var i, pages = root.getChildNodes();
	for (i = 0; i < pages.getLength(); i++) {
		// if the current page is the last of the list, return always true
		var pageId = '' + pages.item(i).getAttributes().getNamedItem(TAG_FORM_ID).getNodeValue();
		if (pageId == page)
			return true;
					
		// the page is not the last: check if the last is allowed or not
		var attrs = pages.item(i).getAttributes();
		// if the ith page hasn't a guard condition return false
		if (!hasGuardCondition(attrs))
			return false;

		// the ith page has a guard condition
		if (checkCondition(attrs))
			return false;
	}
	// this statement should never be reached
	alert('wizardEvents.js::isFirst(' + page + ') ERROR: page not recognized');
	return false;
}

// a page is the last page if it is the last in the XML or if it is the last
// page allowed by the conditions
function isLast(root, page){

	var i, pages = root.getChildNodes();
	for (i = pages.getLength() - 1; i >= 0; i--) {
		// if the current page is the last of the list, return always true
		var pageId = '' + pages.item(i).getAttributes().getNamedItem(TAG_FORM_ID).getNodeValue();
		if (pageId == page)
			return true;
					
		// the page is not the last: check if the last is allowed or not
		var attrs = pages.item(i).getAttributes();
		// if the ith page hasn't a guard condition return false
		if (!hasGuardCondition(attrs))
			return false;

		// the ith page has a guard condition
		if (checkCondition(attrs))
			return false;
	}
	// this statement should never be reached
	alert('wizardEvents.js::isLast(' + page + ') ERROR: page not recognized');
	return false;
}

// this function returns the previous valid page or false if there no exists one
function prevPage(root, page){
	var i, pages = root.getChildNodes();
	// set i to current page
	for (i = 0; i < pages.getLength(); i++) {
		
		var pageId = '' + pages.item(i).getAttributes().getNamedItem(TAG_FORM_ID).getNodeValue();
		if (pageId == page)
			break;
	}
		
	if (i == 0) {
		// alert('wizardEvents.js::prevPage(' + page + ') ERROR: page not
		// recognized');
		return false;
	}
	// find first acceptable page
	while (true) {
		// i points to the current page so it is possible to query the successor
		// pages if i = n - 1
		if (i > 0) {
		
			var attrs = pages.item(i - 1).getAttributes();
			// if form is free, take that to be the next page
			if (!hasGuardCondition(attrs))
				return '' + pages.item(i - 1).getAttributes().getNamedItem(TAG_FORM_ID).getNodeValue();
			
			// form is not free
			if (checkCondition(attrs)) {
			
				return '' + pages.item(i - 1).getAttributes().getNamedItem(TAG_FORM_ID).getNodeValue();
			}
			else {
				i--;
				continue;
			}
		}
		// there are no pages left
		else {
			alert('wizardEvents.js::prevPage(' + page + ') ERROR: no free pages left');
			return false;
		}
	}
}

// this function returns the next valid page or false if there no exists one
function nextPage(root, page) {

	var i, pages = root.getChildNodes();
	// set i to current page
	for (i = 0; i < pages.getLength(); i++){		
		var pageId = '' + pages.item(i).getAttributes().getNamedItem(TAG_FORM_ID).getNodeValue();
		if (pageId == page)
			break;
	}
		
	if (i == pages.getLength()) {
		// alert('wizardEvents.js::nextPage(' + page + ') ERROR: page not
		// recognized');
		return false;
	}
	// find first acceptable page
	while (true){
		// i points to the current page so it is possible to query the successor
		// pages if i = n - 1
		if (i < pages.getLength() - 1) {
		
			var attrs = pages.item(i + 1).getAttributes();
			// if form is free, take that to be the next page
			if (!hasGuardCondition(attrs))
				return '' + pages.item(i + 1).getAttributes().getNamedItem(TAG_FORM_ID).getNodeValue();
			
			// form is not free
			if (checkCondition(attrs)) {			
				return '' + pages.item(i + 1).getAttributes().getNamedItem(TAG_FORM_ID).getNodeValue();
			}
			else {
				i++;
				continue;
			}
		}
		// there are no pages left
		else {
			alert('wizardEvents.js::nextPage(' + page + ') ERROR: no free pages left');
			return false;
		}
	}
}

/*
 * This function allows 'back' and 'forward' navigation of the wizard Note:
 * wizardPage is declared in wizardEvents.js The XML structure for the forms is:
 * <forms> <form id="form 1 id" srcid="source 1 id" srcvalue="source 1 value"
 * [rule="rule"] /> .... </forms>
 */
function navigate(direction, endOption, demo){
	var doc = createDomParser(lastSectionFormsXML);	
	if (doc == null)
		return;
	var root = doc.getDocumentElement();

	// if it is the first time that user presses a button button, load first
	// page id
	if (wizardPage == '') {
		// wizard has at least one page so this is correct
		wizardPage = '' + root.getChildNodes().item(0).getAttributes().getNamedItem("id").getNodeValue();
        wizardButtonsState = (($('back') == null || $('back').disabled) ? "N" : "Y") + '-' + ($('forward').disabled ? "N" : "Y");    
	}
	if (direction == 'back') {

		var prev = prevPage(root, wizardPage);
		if (prev == false)
			return;
			
		display(prev);
		hide(wizardPage);
		
		// update buttons state
		if (isFirst(root, prev)){
                    $('back').disabled = true;
		}
		if (isLast(root, wizardPage)) {
                    $('forward').value = "avanti";
		}        
        wizardButtonsState = (($('back') == null || $('back').disabled) ? "N" : "Y") + '-' + ($('forward').disabled ? "N" : "Y");                 
        // alert(wizardButtonsState);
        wizardPage = prev;                
	}
	else {  // forward
		if (isLast(root, wizardPage)) {	
                    setCursor("wait");
                    // empty wizard content
                    hide(wizardPage);
                    display('WAIT_DIV');
                    wizardPage = '';
                    // end the wizard
                    endWizard(endOption, demo);
                    return;
		}
		// get next page
                
		var next = nextPage(root, wizardPage);
		if (next == false)
                    return;

		display(next);
		hide(wizardPage);
        
		// update buttons state
		if (isLast(root, next)) {
			$('forward').value = "Fine";	
                    // wizardButtonsState = 'Y-N';
		}
		/*
		 * else { $('forward').value = "avanti"; }
		 */
		if (isFirst(root, wizardPage)) {
			$('back').disabled = false;
            // wizardButtonsState = 'Y-Y';
		}
                wizardButtonsState = (($('back') == null || $('back').disabled) ? "N" : "Y") + '-' + ($('forward').disabled ? "N" : "Y");
		wizardPage = next;               
	}
}

// 
function manageVersionForm(action) {
	switch(action)
	{
		case "cancel":		
				setCursor("wait");				
				hide('page1');
				display('WAIT_DIV');			
				if(useOldStyleWizard)
			        wizard.hide();
			    else
			        wizard.close();
				setCursor("auto");
			break;
		case "proceed":
				setCursor("wait");
				var pars = 'action=listDblClick&sectionId=' + selectedSection + '&proceed=Y';			
				new Ajax.Request(PHP_RESPONSE_FILE, {method: 'get', parameters: pars, onFailure: reportError, onComplete: listCallback});
			break;
	}
	return;
}
// check if the attributes contains mutex clauses.
function checkMutexToAttribute(control){	
	if (control != null){
		for (i = 0; i < control.attributes.length; i++) {
			try{
				if (control.attributes[i].value.search("mutex") != -1){
					if (control.attributes[i].value.search("to=") != -1){
						return true;
					}
				}
			}
			catch(ex){
				alert('checkMutexToAttribute' + ex);
			}
		}
	}
	return false;
}
//
//
function openEnhancedDialog(srcId, action){
	var i;
	
	// first split into commands
	var actions = action.split(";");
	for (i = 0; i < actions.length; i++) {
		populateEnhancedDialog(srcId, actions[i]);
	}		
}


