var CACHE_MESSAGE = "Please clear the cache of your browser, reload the page and ";
var CACHE_CONTACT = "\nIf the problem persists, please contact the GAINS Development Team under: gains.dev@iiasa.ac.at";

/**
 * submits the variable with the given name and value
 * via the function of the submitter iFrame
 */
var fgTriggers = new Array();
var running = false;
function TriggerFGroup(name, newValue) {
	/*
	 * check whether some other thread is inside the function
	 */
	while (this.parent.running) {
		/*
		 * do nothing, wait ...
		 */
		 alert("waiting ...");
	}

	this.parent.running = true;

	try {
		/*
		 * trigger the visibility
		 */
		if (fgTriggers[name] == undefined) {
			fgTriggers[name] = newValue;
		} else {
			if (fgTriggers[name] == "hidden") {
				fgTriggers[name] = "visible";
			} else {
				fgTriggers[name] = "hidden";
			}	
		}
		 
		/*
		 * change the visibility of the container
		 */
		if (fgTriggers[name] == "hidden") {
			display = "none";
		} else {
			display = "block";
		}
		document.getElementById(name).style.display = display;
		
		/*
		 * change the span, which triggers the visibility
		 */
		spanElement = document.getElementById("span_" +  name);
		spanElement.className = fgTriggers[name];
		
		/*
		 * call the corresponding function in the submitter iFrame
		 * found in /js/submitter.js
		 */
		window.frames.submitter.SubmitParameter(name, fgTriggers[name]);
	} catch (e) {
		alert("error occured");
		this.parent.running = false;
	} finally {
		this.parent.running = false;
	}
}

function wait(millis) {
	date = new Date();
	var curDate = null;
	do {
		var curDate = new Date();
	} while(curDate-date < millis);
}

/**
 * returns the window parameters based on the given width and height of the window
 */
function getWindowParams(width, height) {
	params  = "width=" + width;
	params += ",height=" + height;
	params += ",menubar=yes,toolbar=no,dependent=no,resizable=yes,scrollbars=yes";
	
	return params;
}

/**
 * opens a new window (for the text editor) with the given URL
 */
function OpenEditor(url, windowName) {
	editor = window.open(url, getWindowName(windowName), getWindowParams(1000, 700));
    editor.focus();
}

/**
 * refreshes the window which opened the calling window and closes the calling window
 */
function RefreshOpenerAndClose() {
	opener.location.href = opener.location.href;
	self.close();
}

/**
 * sets the URL of the opener window to the given URL
 */
function LoadURLIntoOpener(url) {
	// alert("opener location was: " + opener.location.href + "\nnew location is now: " + url);
	opener.location.href = url;
}

/**
 * returns a span with a color preview based on the given color fractions
 */
function getColorPreview(red, green, blue) {
	/*
	 * sum the color component together
	 */
	var n = 0;
	n = n * 256 + Math.floor(red);
	n = n * 256 + Math.floor(green);
	n = n * 256 + Math.floor(blue);
	
	var color = n.toString(16);
	while (color.length < 6) {
		color = "0" + color;
	}
	
	var code = '<div class="color_preview" style="background-color:#' + color + '">&nbsp;</div>';
	return code;
}

/**
 * checks whether the length of the value of the given field exceeds the maximum length
 */
function CheckTextLength(form, textFieldName, textFieldLabel, maxLength) {
	// alert("checking length of content of field: " + textFieldName);
	var textarea = document.getElementById(textFieldName);
	if (textarea.disabled) {
		// alert("text area is disabled.");
		return true;
	} else {
		var currentValue = textarea.value.replace("\\r\\n", "\\\n");
		// alert("length of field: " + currentValue.length + " (max: " + maxLength + ")");
		if (currentValue.length > maxLength) {
			alert("Length of field '" + textFieldLabel + "' exceeded maximum length " +
				  "\n of " + maxLength + " characters by " + (currentValue.length-maxLength) + " character(s)." +
				  "\n\n Please correct the input and submit the form again.");
			return false;
		} else {
			return true;
		}
	}
}

/**
 * checks the length of the given field and submits the form if the length is ok
 */
function SubmitText(form, textFieldName, textFieldLabel, maxLength) {
	if (CheckTextLength(form, textFieldName, textFieldLabel, maxLength)) {
		form.submit();
	}
}

/**
 * executes form onsubmit actions and if no errors occured, submits the form
 */
function SubmitForm(form) {
	/*
	 * check whether a submit function exists and execute it
	 */
	var submitFunction = (form.onsubmit) ? form.onsubmit: function () {
		return true;
	};
	var success = submitFunction();

	/*
	 * check what came back
	 */
	//alert("returned: " + success);
	if (success) {
		//alert("all checks ok, submitting ...");
		form.submit();
	} else {
		//alert("could not submit errors occured.");
	}
}

/*
 * returns a valid window name out of the given name
 */
function getWindowName(name) {
	if (name == undefined) {
		return "_blank";
	} else {
		/*
		 * replace all "(", ")" and all kinds of spaces since the IE does not accept them in the name
		 */
		var regExp = /\W/gi;
		// alert("window name was:\n" + name +
		// 	     "\nwindow name is:\n" + name.replace(regExp, ""));
		return name.replace(regExp, "");
	}
}

/**
 * opens a new window with the cost remarks
 */
function OpenCostRules() {
	var remarkWindow = window.open("../rules_for_costs.html", "costRules", getWindowParams(500, 200));
	remarkWindow.focus();
}

/**
 * opens a new popup window where the resulting of the right side are sent
 */
function OpenPopUp(servlet, url, form, newWindow) {
	// alert ("opening popup for servlet '" + servlet + "', url: " + url);
	try {
		/*
		 * check which servlet requested the popup
		 */
		windowName = new Date().getTime();
		if (servlet != null && servlet != undefined) {
			if (servlet == "export" || servlet == "scenario") {
				/*
				 * open all export requests in the same window
				 */
				windowName = servlet;
			} else if (servlet == "table" || servlet == "table_single") {
				if (form != null && form != undefined) {
					/*
					 * check whether a request for a new window can be found
					 */
					// alert("createNewWindow: " + form.elements["createNewWindow"].checked);
					if (form.elements["createNewWindow"] != undefined
						&& ! form.elements["createNewWindow"].checked) {
						/*
						 * open in the same window
						 */
						windowName = "table";
					}
				}
			}
		}
		
		// alert("window name is: " + windowName);
		
		if (newWindow == true || form == null) {
			/*
			 * create a new popup window
			 */
			windowURL = url;
			if (form != null) {
				windowURL = ""
			}
			popUpWindow = window.open(windowURL, windowName, getWindowParams(1000, 700));
			popUpWindow.focus();
			
			/*
			 * set the name of the popup window
			 */
			popUpWindow.opener.name = "mainWindow";
		}
		
		if (form != null) {	
			/*
			 * store the attributes of the form before overwriting them
			 */
			oldTarget = form.target;
			oldAction = form.action;
			
			/*
			 * set the action and the target of the main window and submit the form
			 */
			form.action = url;
			if (newWindow == true) {
				form.target = windowName;
			} else {
				form.target = "_self";
			}
			form.submit();
			
			/*
			 * restore the attributes attributes
			 */
			form.target = oldTarget;
			form.action = oldAction;
		}
	} catch (ex) {
		alert(CACHE_CLEAR + "try to open the new window again." + CACHE_CONTACT);
	}
}

/*
 * opens a window with the given url (editor for old version)
 */
function OpenOldEditor(url) {
	/*
	 * create a new popup window
	 */
	MeinFenster = window.open(url, getWindowName(url), getWindowParams(800, 700));
  	MeinFenster.focus();
}

/*
 * hides the info div and shows the loading div
 */
function doBridgeSubmit(infoDivName, loadingDivName, formName, dotsID, secondsID) {
	/*
	 * hide/show the given divs
	 */
	//alert("submitting over bridge ... '" + infoDivName + "'-div -> hide, '" + loadingDivName + "'-div -> show");
	infoDiv    = document.getElementById(infoDivName);
	loadingDiv = document.getElementById(loadingDivName);
	
	if (infoDiv != undefined && loadingDiv != undefined) {
		infoDiv.style.display    = "none";
		//alert("info div is now displayed as: " + infoDiv.style.display);
		loadingDiv.style.display = "block";
		//alert("loading div is now displayed as: " + loadingDiv.style.display);
	}
	
	/*
	 * submit the form
	 */
	form = document.getElementById(formName);
	doLoading(dotsID, secondsID);
	if (form != undefined) {
		form.submit();
	}
}

/*
 * shows the time it already took to load data by submitting the form
 */
function doLoading(dotsID, secondsID, secAmount) {
	// alert("set loading for: " + loaderName);
	dots    = document.getElementById(dotsID);
	seconds = document.getElementById(secondsID);
	
	if (dots != undefined || seconds != undefined) {	
		if (secAmount == undefined) {
			secAmount = 0;
		}
		secAmount++;
	
		dotsOut = "";
		for (d = 0; d < secAmount%4; d++) {
			dotsOut += ".";
		}
		
		for (s = d; s < 4; s++) {
			dotsOut += "&nbsp;";
		}
		
		if (dots != undefined) {
			dots.innerHTML    = dotsOut;
		}
		
		if (seconds != undefined) {
			seconds.innerHTML = secAmount;
		}
		
		functionCall = "doLoading('" + dotsID + "', '" + secondsID + "', '" + secAmount + "');";
		window.setTimeout(functionCall, 1000);
	}
}

/*
 * sets the given value of the button and sends the given form
 */
function SetSendAction(buttonID, action, form) {
	document.getElementById(buttonID).value = action;
	
	/*
	alert("target is: " + form.target +
		  "\naction is: " + form.action +
		  "\nbutton value is: " + document.getElementById(buttonID).value +
		  "\nelement value is: " + form.elements[action].value);
	*/
	form.submit();
}

/**
 * moves the selected options of the source select to the destination select
 */
function MoveValues(source, destination) {
    var sOptions = document.getElementById(source).options;
    var dOptions = document.getElementById(destination).options;

	var lastMoved = -1;
    for (s = 0; s < sOptions.length; s++) {
        // alert("s: "+s);
        if (sOptions[s].selected == true) {
			lastMoved = s;
			
            /*
             * set all options of the destination options to not selected
             */
            var moved = false;
            for (d = 0; d < dOptions.length; d++) {
                // alert("d: "+d);
                dOptions[d].selected = false;
                if (! moved && dOptions[d].text.toLowerCase() > sOptions[s].text.toLowerCase()) {
                    // alert("in here 2");
                    moved = true;
                    var insertAt = d;

                    var nOption = new Option("new", "new", false, false);
                    dOptions[dOptions.length] = nOption;

                    for (m = dOptions.length-1; m > insertAt; m--) {
                        dOptions[m].text  = dOptions[m-1].text;
                        dOptions[m].value = dOptions[m-1].value;
                    }
                }
            }
            
            if (! moved) {
                var insertAt = dOptions.length;
                var nOption = new Option("new", "new", false, false);
                dOptions[insertAt] = nOption;
            }
            
            /*
             * copy the item from the source to the destination
             */
            // alert("new option");
            dOptions[insertAt] = new Option(sOptions[s].text, sOptions[s].value, false, false);
            
            for (r = s; r < sOptions.length-1; r++) {
                sOptions[r].text     = sOptions[r+1].text;
                sOptions[r].value    = sOptions[r+1].value;
                sOptions[r].selected = sOptions[r+1].selected;
            }
			 
            sOptions.length--;
            s--;
        }
    }
	
	/*
	 * check whether an item should / can be activated 
	 */
	if (lastMoved > -1) {
		if (sOptions.length == 0) {
			/*
			 * activate the item in the destination select
			 */
			for (d = 0; d < dOptions.length; d++) {
				if (d == insertAt) {
					dOptions[d].selected = true;
				} else {
					dOptions[d].selected = false;
				}
			}
		} else {
			activate = lastMoved;
			if (activate > sOptions.length-1) {
				activate = sOptions.length-1;
			}
			
			/*
			 * activate the item in the source select
			 */
			for (d = 0; d < sOptions.length; d++) {
				if (d == activate) {
					sOptions[d].selected = true;
				} else {
					sOptions[d].selected = false;
				}
			}
		}
	}
}

/**
 * adds a method to the Array object that check whether the array contains the given element
 */
Array.prototype.contains = function (element) {
	for (var i = 0; i < this.length; i++) {
		if (this[i] == element) {
			return true;
		}
	}
	return false;
};

/*
 * move items of select up or down
 */
function MoveSelectedItems(selectID, direction) {
	if (typeof direction == "boolean") {
		/*
		 * check in which direction the items shell be moved
		 */
		var add = 1;
		if (! direction) {
			add = -1;
		}
		
		var options      = document.getElementById(selectID).options;
		var movedOptions = new Array();
		for (var o = 0; o < options.length; o++) {
			/*
			 * check whether the current item was selected and was not already moved
			 */
			// alert("movedOptions: " + movedOptions.join(", "));
			if (options[o].selected && ! movedOptions.contains(options[o].value)) {
				/*
				 * check whether the offset is out of the boundary
				 */
				var changeIndex = o + add;
				if (changeIndex < 0) { changeIndex = (options.length - 1); }
				if (changeIndex >= options.length) { changeIndex = 0;}
				
				// alert("changing: " + o + " <-> " + changeIndex + " (length: " + options.length + ")");
				
				/*
				 * get the element at the change index and swap the two items
				 */
				var tempItem         = cloneOption(options[changeIndex]);
				options[changeIndex] = cloneOption(options[o]);
				options[o]           = cloneOption(tempItem);
				
				/*
				 * add the option to the moved options
				 */
				movedOptions.push(options[changeIndex].value);
				// alert("options[" + changeIndex + "].value = " + options[changeIndex].value);
			}
		}
	}
}

/**
 * creates a new option from the given option
 */
function cloneOption(option) {
	return new Option(option.text,
					  option.value,
					  option.defaultSelected,
					  option.selected);
}

function swapOptions(obj,i,j){
	var o = obj.options;
	var i_selected = o[i].selected;
	var j_selected = o[j].selected;
	var temp  = new Option(o[i].text, o[i].value, o[i].defaultSelected, o[i].selected);
	var temp2 = new Option(o[j].text, o[j].value, o[j].defaultSelected, o[j].selected);
	o[i] = temp2;
	o[j] = temp;
	o[i].selected = j_selected;
	o[j].selected = i_selected;
}

/*
 * selects all items from the multiple select with the given id
 */
function SelectAllItems(selectID) {
	/*
	 * activate the multiple selection
	 */
	var sel      = document.getElementById(selectID);
	sel.multiple = true;
	
	/*
	 * step through all options and mark them
	 */
	var options = sel.options;
    for (o = 0; o < options.length; o++) {
        options[o].selected = true;
    }
}

/**
 * submits the items from the given fields and submits the form
 */
function SubmitItems(form, selectID, selectedID, actionID, actionValue) {
	/*
	 * select all items of both select fields
	 */
	SelectAllItems(selectID);
	SelectAllItems(selectedID);
	
	/*
	 * set the variable with the given action name to the given value
	 */
	document.getElementById(actionID).value = actionValue;
	
	/*
	 * submit the form
	 */
	form.submit(); 
}

/*
 * changes the css class of the given object
 */
var rowClass;
function ChangeHighLight(obj) {
    var highlighted = "highlight";
    if (obj.className == highlighted) {
        obj.className = rowClass;
    } else {
        rowClass      = obj.className;
        obj.className = highlighted;
    }
}

/*
 * searches for an anchor with the given name
 */
var foundRow;
var foundStyle;
function searchAbbreviation(anchorName) {
	anchorName   = anchorName.toUpperCase();
	foundAnchor = document.getElementsByName(anchorName)[0];
	
	/*
	 * remove the highlight from the last search result
	 */
	if (foundRow != undefined) {
		document.getElementsByName("row_" + foundRow)[0].className = foundStyle;
	}
	
	if (foundAnchor == undefined) {
		foundRow = undefined;
		alert("Abbrevation not found.");
	} else {
		/*
		 * set the style of the found row
		 */
		foundRow     = anchorName;
		foundElement = document.getElementsByName("row_" + foundRow)[0];
		foundStyle   = foundElement.className;
		foundElement.className = "found";
	    return location.href = "#" + anchorName;
	}
}

/*
 * toggles the visibility of the element with the given ID
 */
function ToggleVisibility(elementID) {
	field = document.getElementById(elementID);
	if (field != undefined && field != null) {
		display = field.style.display;
		if (display == "none" || display == undefined || display == "") {
			field.style.display = "block";
		} else {
			field.style.display = "none";
		}
	}
}

/*
 * sets all checkboxes of the given form with the given name to the check status of the check with the given set name
 */
function CheckAllBoxes(form, searchName, setName, changeDisabled) {
	if (form != undefined) {
		var statusBox = form[setName];
		if (statusBox != undefined) {
			var newStatus = statusBox.checked;
			for (var e = 0; e < form.elements.length; e++) {
				var element = form.elements[e];
				if ((! element.disabled || changeDisabled)
					 && element.name == searchName) {
					element.checked = newStatus;
				}
			}
		}
	}
}