/*
 * zlstCore.js
 *
 * Copyright (c) 2007-2011 by Zelestra, ZELESTRA.COM. All Rights Reserved.
 * Version 3.23 2011-05-31
 * Requires: prototype.js version v1.6.1
 */

// Document Functions

// adds preloadImage(path) method to document
document.preloadImage = function(path) {
	if (!document._zlstPreloadedImages) {
		document._zlstPreloadedImages = new Array();
	}
	var image = new Image();
	image.src = path;
	document._zlstPreloadedImages.push(image);
};

// Clears the specified cookie value.
// Path and domain are optional.
document.clearCookie = function(name,path,domain) {
	if (document.getCookie(name))
		document.cookie = name + "=" + ";path=" + ((path) ? path : "/") +
		((domain) ? (";domain=" + domain) : "") + ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
};

// Gets the specified cookie value.
document.getCookie = function(name) {
	var start = document.cookie.indexOf(name + "=");
	var len = start + name.length + 1;
	if ((!start) && (name != document.cookie.substring(0, name.length)))
		return null;
	if (start == -1)
		return null;
	var end = document.cookie.indexOf(";",len);
	if (end == -1)
		end = document.cookie.length;
	return unescape(document.cookie.substring(len,end));
};

// Gets local storage item
document.getLocalStorageItem = function(key) {
	return document.getCookie(key);
};

//Gets session storage item
document.getSessionStorageItem = function(key) {
	return document.getCookie(key);
};

// Returns true if cookies are allowed.
document._cookiesAllowed = -1;
document.getCookiesAllowed = function() {
	if (document._cookiesAllowed == -1) {
		document.setCookie("checkCookie","test",1);
		if (document.getCookie("checkCookie")) {
			document.clearCookie("checkCookie");
			document._cookiesAllowed = 1;
		} else
			document._cookiesAllowed = 0;
	}
	return (document._cookiesAllowed == 1);
};

// Removes local storage item
document.removeLocalStorageItem = function(key) {
	document.clearCookie(key);
};

// Removes session storage item
document.removeSessionStorageItem = function(key) {
	document.clearCookie(key);
};

// Sets the specified cookie to the specified value.
document.setCookie = function(name,value,options) {
	if (!options)
		options = {};
	if (options.expires) {
		var expires_date = new Date();
		expires_date.setTime(expires_date.getTime()+(options.expires * 1000 * 60 * 60 * 24));
	}
	document.cookie=name+"="+escape(value)+((expires_date) ? ";expires="+expires_date.toGMTString() : "")+
		";path=" + ((options.path) ? options.path : "/")+
		((options.domain) ? ";domain="+options.domain : "")+
		((options.secure) ? ";secure" : "");
};

// Sets local storage item
document.setLocalStorageItem = function(key,value) {
	document.setCookie(key,value,{expires:7300});
};

// Sets session storage item
document.setSessionStorageItem = function(key,value) {
	document.setCookie(key,value);
};

// set default local, service, and identity providers
document.localProviderId = window.location.hostname;
document.serviceProviderId = window.location.hostname;
document.identityProviderId = "www.zelestra.net";

// Window functions

// Overrides window.open to provide better window handling
window.openBase = window.open;
window.open = function(url,name,features) {

	// build a standard window name if one is not supplied
	var cUrl = url;
	var hashedName = false;
	if (!name || (name == "_blank")) {
		if ((cUrl.indexOf("http://") == -1) && (cUrl.indexOf("https://") == -1)) {
			if (cUrl.indexOf("/") == 0)
				cUrl = cUrl.substring(1);
			cUrl = window.location.protocol + "//" + window.location.host + "/" + cUrl;
		}
		name = "_" + cUrl.hashCode();
		hashedName = true;
	}

	// find base window
	var failSafe = 16;
	var baseWin = window;
	while(baseWin != null) {
		try {
			if (baseWin._zlstWindowList)
				break;
			baseWin = baseWin.opener;
			if (!baseWin || (baseWin == null) || baseWin.closed || (baseWin == window) || (--failSafe < 0)) {
				baseWin = window;
				break;
			}
		} catch(err) {
			baseWin = window;
		}
	}
	if (!baseWin._zlstWindowList) {
		baseWin._zlstWindowList = new Object();
		baseWin._zlstWindowUrls = new Object();
		baseWin._zlstTop = 0;
		baseWin._zlstLeft = 30;
	}

	// get target window
	var targetWin = null;
	if ((baseWin != window) && (baseWin.name == name)) {
		targetWin = baseWin;
	} else  {
		for (var item in baseWin._zlstWindowList) {
			var isClosed = false;
			try {
				isClosed = baseWin._zlstWindowList[item].closed;
			} catch(err) {
			}
			if (isClosed)
				delete baseWin._zlstWindowList[item];
			if (name == item) {
				targetWin = baseWin._zlstWindowList[item];
				break;
			}
		}
	}

	// test just needs to bring window forward
	if (targetWin != null) {
		if (hashedName) {
			baseWin._zlstFocus(targetWin);
			return;
		}
		try {
			if (targetWin.location.href == cUrl) {
				baseWin._zlstFocus(targetWin);
				return;
			}
		} catch(err) {
			targetWin = null;
		}
	}

	// adjust features for special cases
	if (!features)
		features = "toolbar=1,location=1,directories=1,status=1,menubar=1,scrollbars=1,resizable=1";
	else if ((features.indexOf("zlstStyle=popup") != -1) || (features.indexOf("zlstStyle=alert") != -1)) {
		var idx = features.indexOf("width=");
		if (idx != -1) {
			var tmpStr = features.substring(idx + 6).trim();
			var width = parseInt(tmpStr);
			idx = features.indexOf("height=");
			if (idx != -1) {
				tmpStr = features.substring(idx + 7).trim();
				var height = parseInt(tmpStr);
				if (features.indexOf("zlstStyle=alert") != -1) {
					var top = ((window.screen.availHeight / 2) - (height / 2));
					var left = ((window.screen.availWidth / 2) - (width / 2));
					features = "width=" + width + ",height=" + height + ",top=" + top + ",left=" + left + ",screenX=" + top + ",screenY=" + left;
				} else {

					try {

						// adjust placement for window
						if (targetWin == null) {
							baseWin._zlstTop = baseWin._zlstTop + 30;
							baseWin._zlstLeft = baseWin._zlstLeft + 10;
							if (baseWin._zlstTop >= 160)
								baseWin._zlstTop = 30;
							if (baseWin._zlstLeft >= 160) {
								baseWin._zlstTop = 30;
								baseWin._zlstLeft = 30;
							}
						}

						// adjust features for pop-up
						if (Prototype.Browser.IE)
							width += 20;
						features = "width=" + width + ",height=" + height + ",status=1,scrollbars=1,resizable=1,left=" +
							baseWin._zlstLeft + ",top=" + baseWin._zlstTop + ",screenX=" + baseWin._zlstLeft + ",screenY=" + baseWin._zlstTop;

					} catch(err) {
						baseWin = null;
					}
				}
			}
		}
	}

	// prevent multiple window bounce that occurs in some browsers
    if (document._zlstPrevWinUrl) {
		if ((document._zlstPrevWinUrl == url) &&
			(document._zlstPrevWinName == name) &&
			(Math.abs(new Date().getTime() - document._zlstPrevWinTime) < 1000))
			return null;
	}
	document._zlstPrevWinUrl = url;
	document._zlstPrevWinName = name;
	document._zlstPrevWinTime = new Date().getTime();

	// attempt to open window and bring to front or alert user if can't open
	var winRef = baseWin.openBase(url,name,features);
	if (!winRef) {
		alert("I am unable to open the window you requested.\nPlease disable your pop-up blocker for " + document.localProviderId + " and try again.");
	   	return null;
	}
	baseWin._zlstWindowList[name] = winRef;
	baseWin._zlstFocus(winRef);
   	return winRef;
};

// Opens an alert positioned browser window.
// Returns the window reference or null if failure.
window.openAlert = function(url,width,height,name) {
	return window.open(url,name,"width=" + width + ",height=" + height + ",zlstStyle=alert");
};

// Opens an popup browser window.
// Returns the window reference or null if failure.
window.openPopup = function(url,width,height,name) {
	return window.open(url,name,"width=" + width + ",height=" + height + ",zlstStyle=popup");
};

// focus work work-arounds
window._zlstFocus = function(targetWin) {
	this.setTimeout(this._zlstFocus2.bind(this,targetWin),1);
};
window._zlstFocus2 = function(targetWin) {
	targetWin.focus();
};

// Element Functions

Element.addMethods( {

	// Returns true if element is enabled
	getEnabled: function(elem) {
	   	return elem.hasClassName("enabled");
	},

	// Returns true if element is selected
	getSelected: function(elem) {
	   	return elem.hasClassName("selected");
	},

	// Adds or removes "enabled" class
	// The element is returned to facilitate method chaining.
	setEnabled: function(elem,enabled) {
	   	if (enabled) {
			elem.addClassName("enabled");
			if (elem.nodeName == "INPUT") {
				if ((elem.type == "text") || (elem.type == "password"))
					elem.disabled = false;
			}
			if (elem.hasClassName("_zlstLink"))
				elem.style.cursor = "pointer";
		} else {
			elem.removeClassName("enabled");
			if (elem.nodeName == "INPUT") {
				if ((elem.type == "text") || (elem.type == "password"))
					elem.disabled = true;
			}
			if (elem.hasClassName("_zlstLink"))
				elem.style.cursor = "default";
		}
		return elem;
	},

	// Sets a link on any element to open is a separate popup window.
	// Resulting link will only work if element has the "enabled" class.
	// May be specified without an url parameter on anchor elements that have an href attribute.
	// The element is returned to facilitate method chaining.
	setPopUpLink: function(elem,url,width,height,name) {
		if (!url)
			url = elem.href;
		return elem.setSimpleLink(window.openPopup.bind(window,url,width,height,name));
	},

	// Sets a link on any element, parameter may be a function. a URL.
	// Resulting link will only work if element has the "enabled" class.
	// May be specified without a fncOrUrl parameter on anchor elements that have an href attribute.
	// The element is returned to facilitate method chaining.
	setSimpleLink: function(elem,fncOrUrl) {
		if (!fncOrUrl)
			fncOrUrl = elem.href;
		if (elem.href)
			elem.removeAttribute("href");
		if (elem._zlstClickBindFnc)
			Event.stopObserving(elem,"click",elem._zlstClickBindFnc);
		elem._zlstClickBindFnc = Element._onClickHandler.bindAsEventListener(elem,fncOrUrl);
		Event.observe(elem,"click",elem._zlstClickBindFnc);
		elem.addClassName("_zlstLink");
		if (elem.hasClassName("enabled"))
			elem.style.cursor = "pointer";
		else
			elem.style.cursor = "default";
		elem.onclick = function() { return false; }; // hack for Safari
		return elem;
	},

	// on click handler for setSimpleLink
	_onClickHandler: function(event,obj) {
		if (this.hasClassName("enabled")) {
			if (typeof obj == "function")
				obj(event);
			else
				window.location.href = obj;
		}
		Event.stop(event);
		return false;
	},

	// Adds or removes "selected" class
	// The element is returned to facilitate method chaining.
	setSelected: function(elem,selected) {
	   	if (selected)
			elem.addClassName("selected");
		else
			elem.removeClassName("selected");
		return elem;
	},

	// Sets a link on any element to open is a separate window, parameter is a URL.
	// Resulting link will only work if element has the "enabled" class.
	// May be specified without an href parameter on anchor elements that have an href attribute.
	// The element is returned to facilitate method chaining.
	setWindowLink: function(elem,url,name) {
		if (!url)
			url = elem.href;
		return elem.setSimpleLink(window.open.bind(window,url,name,null));
	}

});

// String Functions

// Returns the basename of the string
String.prototype.basename = function(suffix) {
    var result = this.replace(/^.*[\/\\]/g, "");
    if (typeof(suffix) == "string" && result.substr(result.length-suffix.length) == suffix)
        result = result.substr(0, result.length-suffix.length);
    return result;
};

// Returns the dirname of the string
String.prototype.dirname = function() {
	return this.replace(/\\/g,"/").replace(/\/[^\/]*\/?$/,"");
};

// Returns a hash code for the string
String.prototype.hashCode = function() {
    var h = 0;
    for (var i = this.length-1; i >= 0; --i) {
        h ^= this.charCodeAt(i);
        for (var n = 0; n < 3; ++n) {
            var m = (h = h<<7 | h>>>25) & 150994944;
            h ^= m ? (m == 150994944 ? 1 : 0) : 1;
        }
    }
    h = Math.abs(h);
    if (h > 999999999)
        h = h - 1000000000;
    return h;
};

// converts the string from HTML
String.prototype.fromHtml = function() {
	return this.replace(/<a href="[^"]*"( target="_blank")?>([^<]*)<\/a>/g,"$2").replace(/&quot;/g,"\"").replace(/&gt;/g,">").replace(/&lt;/g,"<").replace(/&amp;/g,"&");
}; //"

// converts the string to HTML
String.prototype.toHtml = function() {
	return this.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/\"/g,"&quot;").replace(/(^|\s)([A-Z0-9._%-]+@[A-Z0-9._%-]+\.[A-Z]{2,4})(\s|$|(\.\s)|(\.$))/ig,"$1<a href=\"mailto:$2\">$2</a>$3").replace(/(^|\s)((http|https):\/\/[-A-Z0-9\+&@#\/%\?=~_\|\!:,\.;]*[-A-Z0-9\+&@#\/%=~_\|])(\s|$|(\.\s)|(\.$))/ig,"$1<a href=\"$2\" target=\"_blank\">$2</a>$4");
};

// trims whitespace from front and back of string and ruler-based sizing.
String.prototype.trim = function(ruler,elipsis) {
	var text = String.prototype.strip.call(this);
	if (!ruler)
		return text;
	if (!elipsis)
		elipsis = "\u2026";
	var minWidth = $(ruler).getStyle("minWidth");
	if (minWidth.indexOf("px") != -1)
		minWidth = minWidth.substring(0,minWidth.length - 2);
	ruler.innerHTML = text;
	if (ruler.getWidth() <= minWidth) {
		ruler.innerHTML = "";
		return text;
	}
	var len = ruler.innerHTML.length;
	ruler.innerHTML = ruler.innerHTML + elipsis;
	while(len > 0) {
		--len;
		ruler.innerHTML = ruler.innerHTML.substring(0,len) + elipsis;
		if (ruler.getWidth() <= minWidth) {
			var result = ruler.innerHTML;
			ruler.innerHTML = "";
			return result;
		}
	}
	return "";
},

// Load Scripts

// loads parameters from calling URL into associative array
document.parameters = new Object();
if (window.document.URL.indexOf("?") > 0) {
	var params = document.URL.substr(document.URL.indexOf("?")+1).split("&");
	for(var i=0; i < params.length; ++i) {
		var idx = params[i].indexOf("=");
		if (idx == -1)
			document.parameters[params[i]]="";
		else
			document.parameters[params[i].substring(0,idx)]=decodeURIComponent(params[i].substring(idx + 1));
	}
}
if (window.name == "")
	window.name = "_" + window.location.href.hashCode();
