﻿////////////////////////////////////////////////////////////////////////////////
//
// utils.js - various utilites and helper functions
//
////////////////////////////////////////////////////////////////////////////////

/// <reference path="yui/dom-event-cookie-dragdrop-container-animation--min.js" />

function isUserAgentOpera() {

	try {
		return navigator.userAgent.indexOf("Opera") != -1;
	} catch (exception) {
		ERROR_REPORT.processException("isUserAgentOpera", exception);
	}
}

function isUserAgentSafari() {

	try {
		return navigator.userAgent.indexOf("Safari") != -1;
	} catch (exception) {
		ERROR_REPORT.processException("isUserAgentSafari", exception);
	}
}

function isUserAgentGeckoLinuxBased() {

	try {
		return navigator.userAgent.indexOf("Linux", 0) > 0 && navigator.userAgent.indexOf("Gecko/20", 0) > 0;
	} catch (exception) {
		ERROR_REPORT.processException("isUserAgentGeckoLinuxBased", exception);
	}
}

function isUserAgentIphone() {
	try {
		return navigator.userAgent.indexOf("iPhone") != -1;
	} catch (exception) {
		ERROR_REPORT.processException("isUserAgentSafari", exception);
	}
}

function go_to_hash(hash) {

	if (isUserAgentSafari()) {
		location.hash = "hash_helper";
	}
	location.hash = hash;
}

////////////////////////////////////////////////////////////////////////////////
// The method used to encode given string into base64 representation
////////////////////////////////////////////////////////////////////////////////
function base64_encode(input) {

	try {

		var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
		output = "",
		chr1, chr2, chr3,
		enc1, enc2, enc3, enc4,
		i = 0;

		do {
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);

			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;

			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}

			output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
		} while (i < input.length);

		return output;

	} catch (exception) {
		ERROR_REPORT.processException("base64_encode", exception);
	}
}


////////////////////////////////////////////////////////////////////////////////
// The method used to decode given base64 sequence
////////////////////////////////////////////////////////////////////////////////
function base64_decode(input) {

	try {

		var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
		output = "",
		chr1, chr2, chr3,
		enc1, enc2, enc3, enc4,
		i = 0;

		// remove all characters that are not A-Z, a-z, 0-9, +, /, or =
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

		do {
			enc1 = keyStr.indexOf(input.charAt(i++));
			enc2 = keyStr.indexOf(input.charAt(i++));
			enc3 = keyStr.indexOf(input.charAt(i++));
			enc4 = keyStr.indexOf(input.charAt(i++));

			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;

			output = output + String.fromCharCode(chr1);

			if (enc3 != 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output + String.fromCharCode(chr3);
			}
		} while (i < input.length);

		return output;

	} catch (exception) {
		ERROR_REPORT.processException("base64_decode", exception);
	}
}

////////////////////////////////////////////////////////////////////////////////
// The method returns URL parameter value by given name
////////////////////////////////////////////////////////////////////////////////
function get_url_parameter(name) {

	try {

		name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");

		var regexS = "[\\?&]" + name + "=([^&#]*)",
		regex = new RegExp(regexS),
		results = regex.exec(window.location.href);

		return (results == null) ? "" : results[1];

	} catch (exception) {
		ERROR_REPORT.processException("get_url_parameter", exception);
	}
}

////////////////////////////////////////////////////////////////////////////////
// The method allows to remove specified parameters from url
// http://stackoverflow.com/questions/1634748/how-can-i-delete-a-query-string-parameter-in-javascript
////////////////////////////////////////////////////////////////////////////////
function remove_url_parameters(names) {

	try {

		if (false == isNullOrEmpty(window.location.search)) {

			var pars = window.location.search.substring(
				1, window.location.search.length - 1).split(/[&;]/g);

			var changed = false, indexes_to_remove = [];

			for (var i = 0; i < pars.length; i++) {

				for (var j = 0; j < names.length; j++) {

					// idiom for string.startsWith
					if (pars[i].lastIndexOf(encodeURIComponent(names[j]) + '=', 0) !== -1) {
						indexes_to_remove.push(i);
						changed = true;
					}
				}
			}

			var new_pars = [], should_be_removed = false;

			for (i = 0; i < pars.length; i++) {

				should_be_removed = false;

				for (var k = 0; k < indexes_to_remove.length; k++) {

					if (i == indexes_to_remove[k]) {
						should_be_removed = true;
						break;
					}
				}

				if (false == should_be_removed)
					new_pars.push(pars[i]);
			}

			if (changed) {
				window.location.search = new_pars.length > 0 ? new_pars.join('&') : "";
			}
		}
	} catch (exception) {
		ERROR_REPORT.processException("get_url_parameter", exception);
	}
}

////////////////////////////////////////////////////////////////////////////////
// The method returns localized string representation of given date
////////////////////////////////////////////////////////////////////////////////
function GetLocalDateString(date, month, year) {

	try {
		return new Date(year, month - 1, date).toLocaleDateString();

	} catch (exception) {
		ERROR_REPORT.processException("GetLocalDateString", exception);
	}
}


////////////////////////////////////////////////////////////////////////////////
// The method returns true if given string is null or empty
////////////////////////////////////////////////////////////////////////////////
function isNullOrEmpty(str) {

	try {
		return null == str || 0 == str.length || "null" == str;

	} catch (exception) {
		ERROR_REPORT.processException("isNullOrEmpty", exception);
	}
}


////////////////////////////////////////////////////////////////////////////////
// The method used to disable enter key behaviour in forms
////////////////////////////////////////////////////////////////////////////////
function disableEnterKey(e) {

	try {

		var key = (window.event) ? window.event.keyCode /*IE*/ : e.which; /*firefox*/;
		return (key != 13);

	} catch (exception) {
		ERROR_REPORT.processException("disableEnterKey", exception);
	}
}


////////////////////////////////////////////////////////////////////////////////
// The method is used to simulate non W3C property 'innerText' in Mozilla 
// based browsers. See http://forum.vingrad.ru/faq/topic-158203.html
////////////////////////////////////////////////////////////////////////////////
function innerText(node) {

	try {

		var ret = "", i = 0;

		if (null == node || null == node.childNodes)
			return;

		for (i = 0; i < node.childNodes.length; i++) {

			switch (node.childNodes[i].nodeType) {
				// if element 
				case 1:
					ret += innerText(node.childNodes[i]);
					break;
				// if text node 
				case 3:
					ret += node.childNodes[i].nodeValue;
					break;
			}
		}
		return ret;

	} catch (exception) {
		ERROR_REPORT.processException("innerText", exception);
	}
}


////////////////////////////////////////////////////////////////////////////////
// The method allows you to sort json array by any field
// http://stackoverflow.com/questions/979256/how-to-sort-a-json-array
////////////////////////////////////////////////////////////////////////////////
function json_array_sort_by(field, reverse, primer) {

	try {

		reverse = (reverse) ? -1 : 1;

		return function (a, b) {

			a = a[field];
			b = b[field];

			if (typeof (primer) != 'undefined') {
				a = primer(a);
				b = primer(b);
			}

			if (a < b) return reverse * -1;
			if (a > b) return reverse * 1;
			return 0;

		}

	} catch (exception) {
		ERROR_REPORT.processException("json_array_sort_by", exception);
	}
}


////////////////////////////////////////////////////////////////////////////////
// The method used to check server reply for an errors and update view
// true returned if any errors detected and false otherwise
////////////////////////////////////////////////////////////////////////////////
function CheckOfbServerReply(response) {

	try {

		// make sure server response is not null
		if (null == response || null == response.result) {
			return true;
		}

		// try to get error message.
		var error_message = false == isNullOrEmpty(response.result.ERROR)
			? response.result.ERROR 
			: null == response.result[0] ? null : response.result[0].ERROR;

		// do not continue if there are not any error messages
		if (isNullOrEmpty(error_message))
			return false;

		// update info message panel
		info_message_panel_update(error_message);

		return true;

	} catch (exception) {
		ERROR_REPORT.processException("CheckOfbServerReply", exception);
	}
}


function getFileExtension(file_name) {

	try {

		var pos = file_name.lastIndexOf('.');

		if (pos > 0) {

			file_name = file_name.substring(pos + 1).toLowerCase();

			pos = file_name.indexOf('?');

			if (pos > 0)
				return file_name.substring(0, pos);

			return file_name;
		}
		else
			return null;

	} catch (exception) {
		ERROR_REPORT.processException("getFileExtension", exception);
	}
}

function isValidEmail(email) {

	try {
		var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
		return reg.test(email);

	} catch (exception) {
		ERROR_REPORT.processException("isValidEmail", exception);
	}
}

function getValue(id_or_object) {

	try {

		if (typeof id_or_object == "string")
			return document.getElementById(id_or_object).value;

		if (typeof id_or_object == "object")
			return id_or_object.value;

		throw "utils::getValue::invalid argument";

	} catch (exception) {
		ERROR_REPORT.processException("getValue", exception);
	}
}

function setValue(id_or_object, value) {

	try {

		if (typeof id_or_object == "string") {
			document.getElementById(id_or_object).value = value;
		}

		else if (typeof id_or_object == "object") {
			id_or_object.value = value;
		}

		else throw "utils::setValue::invalid argument";

	} catch (exception) {
		ERROR_REPORT.processException("setValue", exception);
	}
}

function setInnerHTML(id_or_object, value) {

	try {

		if (typeof id_or_object == "string")
			document.getElementById(id_or_object).innerHTML = value;

		else if (typeof id_or_object == "object")
			id_or_object.innerHTML = value;

		else
			throw "utils::setInnerHTML::invalid argument";

	} catch (exception) {
		ERROR_REPORT.processException("setInnerHTML", exception);
	}
}

function getInnerHTML(id_or_object, value) {

	try {

		if (typeof id_or_object == "string")
			return document.getElementById(id_or_object).innerHTML;

		else if (typeof id_or_object == "object")
			return id_or_object.innerHTML;

		throw "utils::setInnerHTML::invalid argument";

	} catch (exception) {
		ERROR_REPORT.processException("getInnerHTML", exception);
	}
}


function setClass(id_or_object, style) {

	try {

		if (typeof id_or_object == "string")
			return document.getElementById(id_or_object).setAttribute("class", style);

		if (typeof id_or_object == "object")
			return id_or_object.setAttribute("class", style);

		throw "utils::setClass::invalid argument";

	} catch (exception) {
		ERROR_REPORT.processException("setClass", exception);
	}
}

function getClass(id_or_object, style) {

	try {

		if (typeof id_or_object == "string")
			return document.getElementById(id_or_object).getAttribute("class");

		if (typeof id_or_object == "object")
			return id_or_object.getAttribute("class")

		throw "utils::getClass::invalid argument";

	} catch (exception) {
		ERROR_REPORT.processException("getClass", exception);
	}
}


function appendClass(id_or_object, class_to_append) {

	try {

		var new_style = getClass(id_or_object) + " " + class_to_append;
		setClass(id_or_object, new_style);

	} catch (exception) {
		ERROR_REPORT.processException("appendClass", exception);
	}
}

function removeClass(id_or_object, class_to_remove) {

	try {

		var new_style = getClass(id_or_object).replace(class_to_remove, "");
		setClass(id_or_object, new_style);

	} catch (exception) {
		ERROR_REPORT.processException("removeClass", exception);
	}
}


function showElement(id_or_object, visible) {

	try {

		if (typeof id_or_object == "string")
			id_or_object = document.getElementById(id_or_object);

		if (null != id_or_object)
			id_or_object.style.visibility = visible ? "visible" : "hidden";
		else
			throw "utils::showElement::invalid argument";

	} catch (exception) {
		ERROR_REPORT.processException("showElement", exception);
	}
}

function enableElement(id_or_object, enabled) {

	try {

		if (typeof id_or_object == "string")
			id_or_object = document.getElementById(id_or_object);

		if (null != id_or_object)
			id_or_object.disabled = !enabled;
		else
			throw "utils::enableElement::invalid argument";

	} catch (exception) {
		ERROR_REPORT.processException("enableElement", exception);
	}
}

function getTheBestDialogWidth(best_width) {

	var best_width_px = best_width ? best_width : 480, view_port_width = YAHOO.util.Dom.getViewportWidth() - 20;

	return (!MOBILE ? best_width_px : (view_port_width < best_width_px ? view_port_width : best_width_px)) + "px";
}
