var isOpera = navigator.userAgent.indexOf("Opera") > -1;
var isSafari = navigator.userAgent.indexOf("Safari") > -1;
var isFirefox = navigator.userAgent.indexOf("Firefox") > -1;
var isFirefoxWin = isFirefox && navigator.userAgent.indexOf("Windows") > -1;
var isFirefoxMac = isFirefox && navigator.userAgent.indexOf("Mac") > -1;
var isExplorer = navigator.userAgent.indexOf("MSIE") > -1;
var isExploder = isExplorer;
var isExplorerWin = isExploder && navigator.appName.indexOf("Microsoft") != -1 && navigator.userAgent.indexOf("Windows") != -1
var isExplorer6 = navigator.userAgent.indexOf("MSIE 6") > -1;
var isExplorer7 = navigator.userAgent.indexOf("MSIE 7") > -1;
var fireOnObj;
var SNWebUI_NamingContainerHashTable = null;

Array.prototype.indexOf = function(value) {
	for (var i = 0; i < this.length; i++) {
		if (this[i] == value) return i;
	}
	return -1;
}
Array.prototype.contains = function(value) {
	return this.indexOf(value) != -1;
}

String.prototype.isEmpty = function (find, replace) {
	return this.trim() == "";
}
String.prototype.replaceAll = function (find, replace) {
	return this.split(find).join(replace);
}
String.prototype.trim = function() {
	var match = /\s*(.*?)\s*/.exec(this);
	return match[1];
}

document.getElementByServerId = function (id) {
	var obj = document.getElementById(id);
	if (!isUndefined(obj)) return obj;
	if (!isUndefined(SNWebUI_NamingContainerHashTable)) {
		if (SNWebUI_NamingContainerHashTable.containsKey(id)) return document.getElementById(SNWebUI_NamingContainerHashTable.get(id));
	}
	return obj;
}

var Hashtable = function(keysArray, valuesArray) {
	this.keys = new Array();
	this.values = new Array();

	if ((!isUndefined(keysArray) && isUndefined(valuesArray)) || (isUndefined(keysArray) && !isUndefined(valuesArray))) throw "Both keys and values array must be defined.";
	if (!isUndefined(keysArray) && !isUndefined(valuesArray)) {
		if (keysArray.length != valuesArray.length) throw "Keys array and values array must be the same length.";
		for (var i = 0; i < keysArray.length; i++) this.set(keysArray[i], valuesArray[i]);
	}
}
Hashtable.prototype.add = function(key, value) {
	if (key == null) throw "Key cannot be null.";
	if (this.keys.indexOf(key) > -1) throw "Key exists in the collection already.";
	this.keys[this.keys.length] = key;
	this.values[key] = value;
	this.length = this.keys.length;
}
Hashtable.prototype.set = function(key, value) {
	if (key == null) throw "Key cannot be null.";
	if (this.keys.indexOf(key) == -1) this.add(key, value);
	else this.values[key] = value;
}
Hashtable.prototype.clear = function() {
	this.keys = new Array();
	this.values = new Array();
	this.length = 0;
}
Hashtable.prototype.containsKey = function(key) {
	return this.keys.indexOf(key) > -1;
}
Hashtable.prototype.get = function(key){
	return this.values[key];
}
Hashtable.prototype.remove = function(key){
	if (this.keys.indexOf(key) == -1) throw "Key does not exists in the collection.";
	this.values[key] = null;
	var index = this.keys.indexOf(key);
	this.keys.splice(index, 1);
}
Hashtable.prototype.size = function() {
	return this.keys.length;
}

var Tracer = function(width, height, left, top) {
	this.width = width || 500;
	this.height = height || 500;
	this.left = left || (document.body.offsetWidth - this.width - 23);
	this.top = top || (document.body.offsetHeight - this.height - 13);

	this.body = document.createElement('div');
	this.body.style.border = "#000 1px solid";
	this.body.style.clear = "both";
	this.body.style.padding = "2px";
	this.body.style.width = this.width + 'px';
	this.body.style.height = this.height + 'px';
	this.body.style.position = 'absolute';
	this.body.style.top = this.top + 'px';
	this.body.style.left = this.left + 'px';

	this.output = document.createElement('div');
	this.output.style.color = "#f00";
	this.output.style.textAlign = "left";
	this.output.style.width = (this.width - 4) + 'px';
	this.output.style.height = (this.height - 22) + 'px';
	this.output.style.overflow = 'scroll';

	var btn = document.createElement('button');
	btn.output = this.output;
	btn.innerHTML = "Clear";
	btn.onclick = function() { this.output.innerHTML = ''; }

	this.body.appendChild(btn);
	this.body.appendChild(this.output);
	document.body.appendChild(this.body);
}
Tracer.prototype.setWidth = function(value) {
	this.width = value;
	this.body.style.width = this.width;
}
Tracer.prototype.setWidth = function(value) {
	this.height = value;
	this.body.style.height = this.height;
}
Tracer.prototype.writeLine = function(message) {
	var div = document.createElement('DIV');
	div.innerHTML = message;
	this.body.childNodes[1].appendChild(div);
	div.scrollIntoView()
}

function convertToObject(objOrString) {
	if (typeof(objOrString) == "string") {
		var result = null;
		try {
			result = eval(objOrString);
		} catch(e){}
		if (isUndefined(result)) result = document.getElementByServerId(objOrString);
		if (!isUndefined(result)) return result;
	}
	return objOrString;
}

function copyValueTo(obj, id) {
	var destination = convertToObject(id);
	if (!isUndefined(obj) && !isUndefined(destination)) destination.value = obj.value;
}

function createTable(numRows, numCells, rowHeights, cellWidths) {
	var tbl = document.createElement("TABLE");
	if (!isUndefined(rowHeights) && !isUndefined(cellWidths)) tbl.style.tableLayout = "fixed";
	for (var i = 0; i < numRows; i++) {
		var row = tbl.insertRow(i);
		for (var j = 0; j < numCells; j++) {
			var cell = row.insertCell(j);
			if (!isUndefined(rowHeights)) {
				if (!isExploder || (isExploder && rowHeights[i] > 0)) cell.height = rowHeights[i];
			}
			if (!isUndefined(cellWidths)) {
				if (!isExploder || (isExploder && cellWidths[j] > 0)) cell.width = cellWidths[j];
			}
		}
	}
	return tbl;
}

function fireEventOnObject(obj, relatedObj, eventName) {
	obj = convertToObject(obj);
	relatedObj = convertToObject(relatedObj);

	if (fireOnObj == relatedObj) {
		fireOnObj = null;
		return;
	}

	fireOnObj = obj;

	if (isExploder) obj.fireEvent(eventName);
	else {
		var evt = document.createEvent("MouseEvents");
		if (eventName.substring(0, 2) == "on") eventName = eventName.substring(2);

		evt.initMouseEvent(eventName, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
		obj.dispatchEvent(evt);
	}
}

function getCookie(name) {
	if (document.cookie.length > 0) {
		var index = document.cookie.indexOf(name + "=")
		if (index != -1) {
			index = index + name.length + 1;
			ends = document.cookie.indexOf(";", index)
			if (ends == -1) ends = document.cookie.length;
			return unescape(document.cookie.substring(index, ends))
		}
	}
	return null;
}

function getChildNodeCount(obj) {
	var curr = 0;
	for (var i = 0; i < obj.childNodes.length; i++) {
		if (obj.childNodes[i].nodeType == 3) continue;
		curr++;
	}
	return curr;
}

function getChildNode(obj, index) {
	var curr = 0;
	for (var i = 0; i < obj.childNodes.length; i++) {
		if (obj.childNodes[i].nodeType == 3) continue;
		if (curr == index) return obj.childNodes[i];
		curr++;
	}
	return null;
}

function getFileExtension(path) {
	return path.substring(path.lastIndexOf("."), path.length);
}

function getOffsetLeftFromBody(obj) {
	obj = convertToObject(obj);
	if (isUndefined(obj) || obj == null) return 0;
	var temp = obj;
	var result = temp.offsetLeft;
	if (temp.tagName == "TABLE" && temp.align == "center") result = 0; //this needs to be looked at in detail
	while (temp.offsetParent != null) {
		temp = temp.offsetParent;
		result += temp.offsetLeft;
	}
	return result;
}

function getOffsetTopFromBody(obj) {
	obj = convertToObject(obj);
	if (isUndefined(obj) || obj == null) return 0;
	var temp = obj;
	var result = temp.offsetTop;
	while (temp.offsetParent.tagName != 'BODY') {
		temp = temp.offsetParent;
		result += temp.offsetTop;
	}
	return result;
}

function getOffsetParentOfType(obj, tagName) {
	if (obj == null) return null;
	if (isUndefined(obj)) return null;
	if (isUndefined(obj.tagName)) return null;
	while (obj.parentNode != null) {
		if (obj.parentNode.tagName.toUpperCase() == tagName.toUpperCase()) return obj.parentNode;
		obj = obj.parentNode;
	}
	return null;
}

function getRectangle(obj) {
	if (isUndefined(obj)) return null;
	if (isUndefined(obj.tagName)) return null;
	var ix = getOffsetLeftFromBody(obj);
	var iy = getOffsetTopFromBody(obj);
	var iw = obj.offsetWidth;
	var ih = obj.offsetHeight;
	return { x:ix, y:iy, width:iw, height:ih };
}

function hookupEvent(control, eventType, functionString, isPrefix) {
	if (isUndefined(isPrefix)) isPrefix = true;
	var ev;
	eval("ev = control." + eventType + ";");
	if (typeof(ev) == "function") {
		ev = ev.toString();
		ev = ev.substring(ev.indexOf("{") + 1, ev.lastIndexOf("}"));
	}
	else ev = "";

	var func;
	if (navigator.appName.toLowerCase().indexOf('explorer') > -1) {
		if (isPrefix) func = new Function(functionString + " " + ev);
		else func = new Function(ev + " " + functionString);
	}
	else {
		if (isPrefix) func = new Function("event", functionString + " " + ev);
		else func = new Function("event", ev + " " + functionString);
	}
	eval("control." + eventType + " = " + func);
}

function isUndefined(obj) {
	if (typeof(obj) == "undefined") return true;
	return obj == null;
}

function registerNonIEFocusSetActiveElement() {
	if (!isExploder) document.addEventListener("focus", setActiveElementHandler, false);
}

function registerNonIEClickSetActiveElement() {
	if (!isExploder) document.addEventListener("click", setActiveElementHandler, false);
}

function setCookie(name, value, expires) {
	if (isUndefined(expires)) {
		expires = new Date();
		expires.setDate(expires.getDate() + 365);
	}
	document.cookie = name + "=" + escape(value) + ";expires=" + expires.toGMTString();
}

function setOpacity(obj, opacity) {
	obj = convertToObject(obj);
	obj.opacity = opacity;
	if (isFirefox || isSafari) obj.style.opacity = opacity / 100;
	else if (isExploder) obj.style.filter = "alpha(opacity=" + opacity + ")";
}

function setActiveElementHandler(event) {
	document.activeElement = (event.target.nodeType == Node.TEXT_NODE) ? event.target.parentNode : event.target;
}

function setObjectFloat(obj, value) {
	if (isExploder) obj.style.styleFloat = value;
	else obj.style.cssFloat = value;
}

function swapImage(imageObj, imageUrl) {
    imageObj = convertToObject(imageObj);

    var usesAlphaImageFilter = isExplorer6 && (imageObj.style.cssText.indexOf('DXImageTransform.Microsoft.AlphaImageLoader') > -1 || imageObj.parentNode.style.cssText.indexOf('DXImageTransform.Microsoft.AlphaImageLoader') > -1);

    //alert(usesAlphaImageFilter);

    if (isUndefined(imageUrl)) imageUrl = imageObj.originalSrc;
    else {
    if (isUndefined(imageObj.originalSrc)) {
    if (!usesAlphaImageFilter) imageObj.originalSrc = imageObj.src;
    else imageObj.originalSrc = isUndefined(imageObj.filters['DXImageTransform.Microsoft.AlphaImageLoader']) ? imageObj.parentNode.filters['DXImageTransform.Microsoft.AlphaImageLoader'].src : imageObj.filters['DXImageTransform.Microsoft.AlphaImageLoader'].src;
    }
    }
    if (usesAlphaImageFilter)
    {
    if (imageObj.parentNode.filters['DXImageTransform.Microsoft.AlphaImageLoader'])
        imageObj.parentNode.filters['DXImageTransform.Microsoft.AlphaImageLoader'].src = imageUrl;
    else if (imageObj.filters['DXImageTransform.Microsoft.AlphaImageLoader'])
        imageObj.filters['DXImageTransform.Microsoft.AlphaImageLoader'].src = imageUrl;
    }
    else imageObj.src = imageUrl;
}


function toggleErrorDetails(anchor, id) {
	var r = convertToObject(id);
	if (r.style.display == 'none') {
		r.style.display = '';
		anchor.innerHTML = 'Hide details';
	}
	else {
		r.style.display = 'none';
		anchor.innerHTML = 'Show details';
	}
}

function toggleHeaderRowSiblingDisplay(clickee) {
	var table = clickee.parentNode.parentNode.parentNode.parentNode;//img->cell->row->tbody->table
	if (isExplorer && typeof(clickee.isExpanded) == "string") clickee.isExpanded = clickee.isExpanded == 'True';
	else if (typeof(clickee.isExpanded) == "undefined") clickee.isExpanded = clickee.getAttribute('isExpanded') == 'True';
	var args = toggleHeaderRowSiblingDisplay.arguments;
	for (var i = 1; i < args.length; i++) {
		var index = parseInt(args[i]);
		table.rows[index].style.display = clickee.isExpanded ? 'none' : '';
	}
	clickee.isExpanded = !clickee.isExpanded;
	clickee.src = clickee.isExpanded ? minusImageUrl : plusImageUrl;
	clickee.title = clickee.isExpanded ? 'Click to collapse' : 'Click to Expand';
}

function toggleSelectVisibility(state) {
	var selects = document.getElementsByTagName('SELECT');
	for (var i=0; i<selects.length; i++) {
		if (isUndefined(selects[i].xvisibility)) selects[i].xvisibility = selects[i].style.visibility;
		selects[i].style.visibility = state ? selects[i].xvisibility : 'hidden';
	}
}