// browser is IE
var broserIsIE = /*@cc_on!@*/false;
// browser is at least Internet Explorer 7
var broserIsAtLeastIE7 = false /*@cc_on || @_jscript_version >= 5.7 @*/;

function loadJavascript(scriptFile, onScriptLoad) {
	if(typeof this.loadedJavascripts == 'undefined')
		this.loadedJavascripts = {};
		
     if (!this.loadedJavascripts[scriptFile]) {
     	
     	this.loadedJavascripts[scriptFile] = true;

		var head = document.getElementsByTagName('head')[0];
		var script = document.createElement('script');
		script.type= 'text/javascript';
		
		if (onScriptLoad) {
			script.onreadystatechange = function () {
				if (this.readyState == 'loaded' || this.readyState == 'complete') {
					onScriptLoad();
				}
			}
			script.onload = function() {
				onScriptLoad();
			};
		}
		script.src = scriptFile;
		head.appendChild(script);
	} else {
		onScriptLoad();
	}
}

function returnObjectById(id) {
	var elm;
	if (document.getElementById)
		elm = document.getElementById(id);
	else if (document.all)
		elm = document.all[id];
	else if (document.layers)
		elm = document.layers[id];
	
	return elm;
}

function returnObjectsValue(id) {
	var obj = returnObjectById(id);
	return obj ? obj.value : '';
}

function returnObjectsHTML(id) {
	var obj = returnObjectById(id);
	return obj ? obj.innerHTML : '';
}

function hascss(elm, css){
	var r = new RegExp('(^|\\s+)' + css + '($|\\s+)','gi');
	return r.test(elm.className);
};

function addcss(elm){
	for (var a = 1;a<arguments.length;a++) {
		if (!hascss(elm, arguments[a])) {
			elm.className += ' ' + arguments[a];
		}
	}
};

function removecss(elm){
	if(arguments.length<2) elm.className = '';
	var r;

	for (var a = 1;a<arguments.length;a++) {
		r = new RegExp('(^|\\s+)' + arguments[a] + '($|\\s+)','gi');
		elm.className = elm.className.replace(r,' ');
	}
};

function stopPropagation(e) {
	var e = e || window.event;
	if (e) {
		e.cancelBubble = true;
		if (e.stopPropagation) e.stopPropagation();
	}
};

function isRightClick(e) {
	var rightclick;
	var e = e || window.event;
	if (e.ctrlKey) rightclick = true // handle Opera not allowing to disable context menu
	else if (e.which) rightclick = (e.which == 3);
	else if (e.button) rightclick = (e.button == 2);
	
	return rightclick; // true or false
}

function addEvent( obj, type, fn, uid ) {
  if ( obj.attachEvent ) {
  	if (!uid) var uid = '';
    obj['e'+type+fn+uid] = fn;
    obj[type+fn+uid] = function(){obj['e'+type+fn+uid]( window.event );}
    obj.attachEvent( 'on'+type, obj[type+fn+uid] );
  } else
    obj.addEventListener( type, fn, false );
}

function removeEvent( obj, type, fn, uid ) {
  if ( obj.detachEvent ) {
  	if (!uid) var uid = '';
    obj.detachEvent( 'on'+type, obj[type+fn+uid] );
    obj[type+fn] = null;
  } else
    obj.removeEventListener( type, fn, false );
}

function addLoadEvent(func) {
  var oldonload = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = func;
  } else {
    window.onload = function() {
      if (oldonload) {
        oldonload();
      }
      func();
    }
  }
}

function firstChild(obj) {
	var first = obj.firstChild;
	while (first && first.nodeType != 1) {
		first = first.nextSibling;
	}
	return first;
}

function lastChild(obj) {
	var last = obj.lastChild;
	while (last && last.nodeType != 1) {
		last = last.previousSibling;
	}
	return last;
}

function nextSibling(obj) {
	do {
		obj = obj.nextSibling;
	} while (obj && obj.nodeType != 1)
	return obj;
}

function previousSibling(obj) {
	do {
		obj = obj.previousSibling;
	} while (obj && obj.nodeType != 1)
	return obj;
}

function inArray(array, item) {
	for (var i=0;i<array.length;i++) {
		if (array[i] == item)
			return true;
	}
	return false;
}

function trim(string){
	return string.replace(/^\s+|\s+$/g, '');
}

function windowPosition() {
	var winH = 
		typeof window.innerHeight != 'undefined' ? window.innerHeight : (
		typeof document.documentElement.clientHeight != 'undefined' ? document.documentElement.clientHeight : (
		typeof document.body.clientHeight != 'undefined' ? document.body.clientHeight : 0));
	var winW =
		typeof window.innerWidth != 'undefined' ? window.innerWidth : (
		typeof document.documentElement.clientWidth != 'undefined' ? document.documentElement.clientWidth : (
		typeof document.body.clientWidth != 'undefined' ? document.body.clientWidth : 0));
	var scrollT =
		typeof window.pageYOffset != 'undefined' ? window.pageYOffset : (
		typeof document.documentElement.scrollTop != 'undefined' ? document.documentElement.scrollTop : (
		typeof document.body.scrollTop != 'undefined' ? document.body.scrollTop : 0));
	var scrollL =
		typeof window.pageXOffset != 'undefined' ? window.pageXOffset : (
		typeof document.documentElement.scrollLeft != 'undefined' ? document.documentElement.scrollLeft : (
		typeof document.body.scrollLeft != 'undefined' ? document.body.scrollLeft : 0));
	
	return {'windowHeight':winH, 'windowWidth':winW, 'scrollTop':scrollT, 'scrollLeft':scrollL};
}

function objectPosition(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
	}
	return {'offsetLeft':curleft, 'offsetTop':curtop};
}

function toggleElementVisibility(id, hiddenClassName) {
	var element = returnObjectById(id);
	if (element) {
		if (element.style.display == 'none' || hiddenClassName && !element.style.display && element.className == hiddenClassName) {
			element.style.display = '';
		} else {
			element.style.display = 'none';
		}
	}
}

function showDialog (domHolder, overlayClass, dialogClass) {
	document.body.appendChild(domHolder);
	divs = domHolder.getElementsByTagName('DIV');
	var pos = windowPosition();

	var cnt = 0;
	for (var i = 0; i < divs.length; i++) {
		if (divs[i].className == dialogClass) {
			divs[i].style.left = (pos.windowWidth ? pos.scrollLeft + (pos.windowWidth - divs[i].offsetWidth) / 2 : 100) + 'px';
			divs[i].style.top = (pos.windowHeight ? pos.scrollTop + (pos.windowHeight - divs[i].offsetHeight) / 2 : 100) + 'px';
			divs[i].style.visibility = 'visible';
			cnt++;
		}
		if (divs[i].className == overlayClass) {
			var h = document.body.parentNode.offsetHeight > document.body.offsetHeight
				? document.body.parentNode.offsetHeight : document.body.offsetHeight;
			if (!h || h < pos.windowHeight)
				h = pos.windowHeight;
			divs[i].style.height = h + 'px';
			cnt++;
		}
		if (cnt > 1)
			break;
	}

	inputs = domHolder.getElementsByTagName('INPUT');
	for (var i = 0; i < inputs.length; i++) {
		if (inputs[i].type == 'text') {
			inputs[i].focus();
			break;
		}
	}
}

function buildDialog(domHolder, overlayClass, dialogClass, title, domContent, buttons, cancelAction) {

	var elm1 = document.createElement('DIV');
	elm1.className = overlayClass;
	domHolder.appendChild(elm1);
	
	var elm2 = document.createElement('DIV');
	elm2.className = dialogClass;
	domHolder.appendChild(elm2);
	
	var ttl = document.createElement('DIV');
	ttl.className = 'title';
	ttl.innerHTML = title;
	elm2.appendChild(ttl);

	if (typeof cancelAction == 'function') {
		var cancel = document.createElement('DIV');
		cancel.className = 'close';
		elm2.appendChild(cancel);
		var cancelInp = document.createElement('INPUT');
		cancelInp.onclick = cancelAction;
		cancelInp.type = 'button';
		cancel.appendChild(cancelInp);
	}
	
	elm2.appendChild(domContent);

	var elm3 = document.createElement('DIV');
	elm3.className = 'buttons';
	elm2.appendChild(elm3);

	var btn;
	for (var i=0;i<buttons.length;i++) {
		btn = document.createElement('INPUT');
		btn.type = 'button';
		btn.value = buttons[i]['title'];
		if (typeof buttons[i]['action'] == 'function') {
			btn.onclick = buttons[i]['action'];
		}
		elm3.appendChild(btn);
	}
}

// usage: 
// dialog('TITLE', 'SOME TEXT', {'ok': 'OK', 'cancel': 'CANCEL'}, function(i){alert(i);} );
function dialog(title, text, buttons, callBack, callBackParams, cancelFunction, dialogClass, externalJavascript, onScriptLoad) {
	if (typeof callBack != 'function') {
		throw new Error('Invalid callback function for dialog ' + title);
	}
	var holder = document.createElement('DIV');
	var content = document.createElement('DIV');
	content.className = dialogClass ? dialogClass : 'dialogText';;
	content.innerHTML = text;
	var btnList = [], fn;
	for (var i in buttons) {
		eval('fn = function() {'
			+ 'callBack(\'' + i + '\', callBackParams);'
			+ 'holder.parentNode.removeChild(holder);'
			+ '}');
		btnList[btnList.length] = {'title':buttons[i], 'action': fn};
	}

	var cancel = function() { 
		holder.parentNode.removeChild(holder);
		if (typeof cancelFunction == 'function') {
			cancelFunction();
		}
	};

	buildDialog(holder, 'windowOverlay', 'dialogContent', title, content, btnList, cancel);
	if (externalJavascript) {
		var _onScriptLoad = function() {
			if (onScriptLoad) onScriptLoad();
			showDialog(holder, 'windowOverlay', 'dialogContent');
		}
		
		loadJavascript(externalJavascript, _onScriptLoad);
	} else {
		showDialog(holder, 'windowOverlay', 'dialogContent');
	}
}

function inspect(obj, level) {
	var str = '';
	var pad = '';
	for (var i=0;i<level;i++) {
		pad += '\t';
	}
	for (var i in obj) {
		if (typeof obj[i] == 'Object')
			str += inspect(obj[i], level+1);
		else
			str += pad + i + ': ' + obj[i] + '\n';
	}
	if (!level)
		alert(str);
}

function tooltip(event, elm, tooltipName) {
	function getPosition(tooltip, target, tooltipHeight, tooltipWidth) {
		var target = event.srcElement || event.target;		
		var maxx = document.body.offsetWidth - 25;
		var maxy = document.body.offsetHeight - 30;
		var targetPosition = objectPosition(target);
		var screenPosX = event.clientX - 10 ;		
		var screenPosY = event.clientY + 25 ;
		var x = targetPosition.offsetLeft - 5 ;		
		var y = targetPosition.offsetTop + 22 ; 		
		var xModified = false;
		if (screenPosX + tooltipWidth > maxx) {
			xModified = true;
			x = targetPosition.offsetLeft - tooltipWidth + 13;
		}
		if (screenPosY + tooltipHeight > maxy) {				
			y = targetPosition.offsetTop - tooltipHeight + 22;
			x += (xModified ? -20 : +20);
		}   	
		var tooltipPos = {'x': x, 'y': y};
		return tooltipPos;
	}

	var target = event.srcElement || event.target;
	if (tooltipName){
		var tooltip = target.ownerDocument.getElementById(tooltipName);	
	} else {
		var tooltip = target.getElementsByTagName('div')[0];	
	}
	if (!tooltip) {
		return;
	}
        
	var timeoutID = window.setTimeout(function () {tooltip.style.visibility = 'hidden';}, 30000); 
	elm.onmouseout = function () {tooltip.style.visibility = 'hidden'; window.clearTimeout(timeoutID);};
	
    tooltip.style.visibility = 'visible';
    height = tooltip.offsetHeight;
    width = tooltip.offsetWidth;
	    
	var	 position = getPosition(tooltip, target, height, width);
	tooltip.style.left = position.x + "px";
	tooltip.style.top = position.y + "px";
}

function showPopup(address) {
	window.open(address, 
		'', 'width=780,height=580,left=' + (screen.width ? (screen.width - 780) / 2 : 0) + ',top=' + (screen.height ? (screen.height - 580) / 2 : 0) + ',toolbar=no,menubar=no,resizable=yes,scrollbars=yes');
}


// **************** Custom messages START ****************

// Checks browser compatibility.
function browserIsCustomMessageCompatible() {
	if (!document.getElementById) {
		return false;
	}
	if (broserIsIE) {
		if (broserIsAtLeastIE7 == undefined) {
			return false;
		}
		if (broserIsAtLeastIE7 == false) {
			return false;
		}
	}
	return true;
}

// Over-ride the alert method only if this a newer browser.
// IMPORTANT: Currently disabled, because if enabled and more alerts are thrown, only the first one is displayed.
/*if(browserIsCustomMessageCompatible()) {
	window.alert = function(messageText) {
		showCustomMessage('', messageText, 'OK', 'warning');
	}
}*/

// shows a custom message
function showCustomMessage(messageTitle, messageText, buttonTitle, cssClass) {
	// check browser compatibility
	if (!browserIsCustomMessageCompatible()) {
		return;
	}
	
	// shortcut reference to the document object
	var d = document;

	// if the customMessageContainer object already exists in the DOM, bail out.
	if(d.getElementById("customMessageContainer")) return;

	// create the customMessageContainer div as a child of the BODY element
	var container = d.getElementsByTagName("body")[0].appendChild(d.createElement("div"));
	container.id = "customMessageContainer";
	 // make sure its as tall as it needs to be to overlay all the content on the page
	container.style.height = document.documentElement.scrollHeight + "px";
	
	// different processing for IE - looks like IE cannot add table elements dynamically
	if (broserIsIE) {
		// create the DIV that will be the alert 
		var messageNode = container.appendChild(d.createElement("div"));
		messageNode.id = "customMessage";
		messageNode.className = cssClass;
		// MSIE doesnt treat position:fixed correctly, so this compensates for positioning the alert
		//if(d.all && !window.opera) messageNode.style.top = document.documentElement.scrollTop + "px";
		if(d.all && !window.opera) messageNode.style.top = document.body.scrollTop + "px";
		// center the alert box
		messageNode.style.left = (d.documentElement.scrollWidth - messageNode.offsetWidth)/2 + "px";
	
		// create an p element as the title bar
		var p = messageNode.appendChild(d.createElement("p"));
		p.id = "customMessageTitle";
		p.appendChild(d.createTextNode(messageTitle));
	
		// create a paragraph element to contain the messageText argument
		var msg = messageNode.appendChild(d.createElement("p"));
		msg.id = "customMessageText";
		msg.appendChild(d.createTextNode(messageText));
	
		// create an anchor element to use as the confirmation button.
		var btn = messageNode.appendChild(d.createElement("a"));
		btn.id = "customMessageButton";
		btn.appendChild(d.createTextNode(buttonTitle));
		btn.href = "#";
		// set up the onclick event to remove the alert when the anchor is clicked
		btn.onclick = function() { removeCustomMessage(); return false; }
	}
	else {
		var tableNode = container.appendChild(d.createElement("table"));
		tableNode.id = "customMessage";
		tableNode.className = cssClass;
		
		// MSIE doesnt treat position:fixed correctly, so this compensates for positioning the alert
		//if(d.all && !window.opera) tableNode.style.top = document.documentElement.scrollTop + "px";
		if(d.all && !window.opera) tableNode.style.top = document.body.scrollTop + "px";
		// center the alert box
		tableNode.style.left = (d.documentElement.scrollWidth - tableNode.offsetWidth)/2 + "px";
		
		var trTitleNode = tableNode.appendChild(d.createElement("tr"));
		var tdTitleNode = trTitleNode.appendChild(d.createElement("td"));
		tdTitleNode.id = "customMessageTitle";
		tdTitleNode.appendChild(d.createTextNode(messageTitle));
		
		var trMessageNode = tableNode.appendChild(d.createElement("tr"));
		var tdMessageNode = trMessageNode.appendChild(d.createElement("td"));
		tdMessageNode.id = "customMessageText";
		tdMessageNode.appendChild(d.createTextNode(messageText));
		
		var trButtonNode = tableNode.appendChild(d.createElement("tr"));
		var tdButtonNode = trButtonNode.appendChild(d.createElement("td"));
		// create an anchor element to use as the confirmation button.
		var btn = tdButtonNode.appendChild(d.createElement("a"));
		btn.id = "customMessageButton";
		btn.appendChild(d.createTextNode(buttonTitle));
		btn.href = "#";
		// set up the onclick event to remove the alert when the anchor is clicked
		btn.onclick = function() { removeCustomMessage(); return false; }
	}
}

// removes the custom message from the DOM
function removeCustomMessage() {
	// check browser compatibility
	if (!browserIsCustomMessageCompatible()) {
		return;
	}
	document.getElementsByTagName("body")[0].removeChild(document.getElementById("customMessageContainer"));
}

// **************** Custom messages END ****************

// get elements by class name, can be narrowed by tag name and parent element of subtree
var getElementsByClassName = function (className, tag, elm){
	if (document.getElementsByClassName) {
		getElementsByClassName = function (className, tag, elm) {
			elm = elm || document;
			var elements = elm.getElementsByClassName(className),
				nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
				returnElements = [],
				current;
			for(var i=0, il=elements.length; i<il; i+=1){
				current = elements[i];
				if(!nodeName || nodeName.test(current.nodeName)) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	else if (document.evaluate) {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "),
				classesToCheck = "",
				xhtmlNamespace = "http://www.w3.org/1999/xhtml",
				namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
				returnElements = [],
				elements,
				node;
			for(var j=0, jl=classes.length; j<jl; j+=1){
				classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
			}
			try	{
				elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
			}
			catch (e) {
				elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
			}
			while ((node = elements.iterateNext())) {
				returnElements.push(node);
			}
			return returnElements;
		};
	}
	else {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "),
				classesToCheck = [],
				elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
				current,
				returnElements = [],
				match;
			for(var k=0, kl=classes.length; k<kl; k+=1){
				classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
			}
			for(var l=0, ll=elements.length; l<ll; l+=1){
				current = elements[l];
				match = false;
				for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
					match = classesToCheck[m].test(current.className);
					if (!match) {
						break;
					}
				}
				if (match) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	return getElementsByClassName(className, tag, elm);
};
// **************** get element by class name END ****************