
var AppUtilsClass = Class.create();

AppUtilsClass.prototype = {

	initialize: function () {
		this.ajaxEventCSSClass = "ajax";
		this.ajaxEventURLExt = "ajax=true";
		this.failureContainer = "mainLayoutContentDiv";
		this.loadingContainer = "loadingLayer";
		this.messageDiv = "messageLayer";
		Event.observe(window, 'load', function () {
			AppUtils.attachAJAXEvents();
			AppUtils.attachAjaxResponders();
		});
		
		this.overlayDuration = 0.2;
		this.overlayOpacity = 0.5;
		
		this.showMessageCounter = 0;
		
		//setTimeout(this.initializeOverlay.bind(this), 1000);
	},
	
	initializeOverlay: function() {
		var objBody = document.getElementsByTagName("body").item(0);
		var objOverlay = document.createElement("div");
		objOverlay.setAttribute('id','overlay');
		objOverlay.style.display = 'none';
		objBody.appendChild(objOverlay);
	},
	
	toString: function() {
		return "Utility Javascript";
	},
	
	attachAJAXEvents: function() {
		var anchorElements = document.getElementsByTagName('a');
		var cssClass = this.ajaxEventCSSClass;
		$A(anchorElements).each((function(element) {
			if(element.className.match(new RegExp("(^|\\s)" + this.ajaxEventCSSClass + "(\\s|$)"))) {
				Event.observe(element, "click", (function(event){
					var element = Event.element(event);
					var target = element.className.replace(/.*target-([\w\d\-]+)(\b.*|$)/i, "$1");
					this._attachAjaxEvent(element, target);
					Event.stop(event);
				}).bind(this));
			}
		}).bind(this));
	},
	
	_attachAjaxEvent: function(anchorElem, target, options) {
		var href = anchorElem.getAttribute("href");
		var url = href + (href.indexOf('?') < 0 ? "?" : "&") + this.ajaxEventURLExt;
		new Ajax.Updater({success: target, failure: this.failureContainer}, url, {method: "GET", evalScripts: true, 
			onSuccess: function(originalReq) {
				if (options && options.onSuccess) options.onSuccess(originalReq);
			}
		});
	},
	
	attachAjaxResponders: function () {
		// TODO: Attach the onError handler to show the generic error messages
		Ajax.Responders.register({ 
			onCreate: (function () {
				new Effect.Appear(this.loadingContainer, {duration: 0.3, queue: {position: 'end', scope: 'loadingContainer'}});
			}).bind(this),
			onComplete: (function() { 
				new Effect.Fade(this.loadingContainer, {duration: 0.3, queue: {position: 'end', scope: 'loadingContainer'}});
				AppUtils.attachAJAXEvents();
			}).bind(this),			
			onException: (function() {
				try{ 
				console.log("--- Error START ---")
				$A(arguments).each(function(arg, index) {
					console.log(index + ': ' + arg);
					console.dir(arg);
				});
				console.log("--- Error END ---")
				}catch(e){
					//swallow
				}
			}).bind(this)
		});
	}, 
	
	loadScripts: function(module) {
		var reqModules = depends.findDependencies(module);
		reqModules.each( function(script) {
			var url= "../js/" + script;
			var element = document.createElement("script");
			element.setAttribute("type", "text/javascript");
			element.setAttribute("src", url);
			document.getElementsByTagName("head")[0].appendChild(element);
		});
	},

	isEmpty: function(text) {
		if (text) return !/\S/.test(text);
		return true;
	},
	
	isNotEmpty: function(text) {
		return !AppUtils.isEmpty(text);
	},
	
	emptyFunction: function() {
	},
	
	ajaxDisplayTable: function(target, options){
		setTimeout((function() {
			this._ajaxDisplayTable(target, options);
		}).bind(this), 50);
	},
	
	_ajaxDisplayTable: function(target, options) {
		var options = Object.extend({tableOrder: 1, tableClass: 'DisplayTable', tableHeaderClass: 'DisplayTableHeader', pageLinksClass: 'pagelinks', onSuccess: this.emptyFunction}, options);
		document.getElementsByClassName(options.tableClass, target).each((function(tableElem, index) {
				document.getElementsByClassName(options.tableHeaderClass, tableElem).each((function(headerElem) {
					$A(headerElem.getElementsByTagName('a')).each((function(anchorElem) {
						Event.observe(anchorElem, 'click', (function(event) {
							var elem = Event.element(event);
							this._attachAjaxEvent(elem, target, options);
							Event.stop(event);
						}).bind(this));
					}).bind(this));
				}).bind(this));
		}).bind(this));
		
		document.getElementsByClassName(options.pageLinksClass, target).each((function(pageLinksElem, index) {
				$A(pageLinksElem.getElementsByTagName('a')).each((function(anchorElem) {
					Event.observe(anchorElem, 'click', (function(event) {
						var elem = Event.element(event);
						/* gets the anchor element img tag is wrapped within */
						if (elem.nodeName.toLowerCase() == 'img') elem = elem.parentNode;
						this._attachAjaxEvent(elem, target, options);
						Event.stop(event);
					}).bind(this));
				}).bind(this));
		}).bind(this));
	},
	
	showMessage: function(message, isError) {
		var messageLayer = $(this.messageDiv);
		var isErrorMsg = isError ? isError : false;
		var msg = '';
		if (message.responseXML) {
		    if (message.responseXML.getElementsByTagName("error")[0]){
				isErrorMsg = true;
				msg = message.responseXML.getElementsByTagName("error")[0].firstChild.data;
			} else if (message.responseXML.getElementsByTagName("success")[0]){
				isErrorMsg = false;
				msg = message.responseXML.getElementsByTagName("success")[0].firstChild.data;
			} else {
				msg = message.responseXML;
			}
		} else if (message.responseText){
			msg = message.responseText;
		} else {
			msg = message;
		}
		
		if (isErrorMsg) 
			alert(msg);
		else {
			messageLayer.style.color = 'green';
			messageLayer.innerHTML = msg;
			new Effect.ScrollTo(messageLayer, {offset: -200, duration: 0.5 });
			new Effect.Appear(messageLayer);
			this.showMessageCounter++;
			var counter = this.showMessageCounter;
			setTimeout((function() {
				if (counter == this.showMessageCounter) {
					new Effect.Fade(messageLayer);
				}
			}).bind(this), 5000);
		}
	},
	
	/**
	 * Serializes an associative array e.g. converts "{foor: bar, month: jan}" to "foo=bar&month=jan"
	 */
	serialize: function(object) {
		var result = new Array();
		for (key in object) {
			var value = object[key];
			if (key != 'extend') result.push(encodeURIComponent(key) + "=" + encodeURIComponent(value));
		}
		return result.join('&');
	},

	/* used to encode the xml so that it can be safely passed to servers */
	encodeXML: function(xmlText) {	
		return encodeURIComponent(xmlText.replace(/</g, '[').replace(/>/g, ']'));
	},
	
	isEmptyObject: function (theObject) {
		if(typeof theObject != 'undefined' && theObject != '' && theObject != 'null' && theObject != null) return false;
		return true;
	},
	
	toggleNavBox: function(handler, elem) {
		this.toggleNavBoxClassName(handler, elem, {maxClass: 'nav_box_maximize', minClass: 'nav_box_minimize'});
	},

	toggleNavBox: function(handler, elem, params) {
		if (handler.className.indexOf(params.minClass) > -1) {
			new Effect.BlindUp(elem, {queue: 'end',duration: 0.3});
			handler.className=params.maxClass;
			handler.title="Expand";
		} else {
			new Effect.BlindDown(elem, {queue: 'end',duration: 0.3});
			handler.className=params.minClass;
			handler.title="Collapse";
		}
		handler.blur();
	},

	helpWindow:function (wDoc){
		hWin = window.open(wDoc, "HelpWin", "resizable,menubar,scrollbars,top=300,left=300,width=600,height=400");
	},

	replaceAll:function (str, searchFor, replacement){ 
		if (searchFor.length == 0)
			return str;
		var index = str.indexOf(searchFor);
		while (index >= 0) {  
			str = str.substring(0,index) + replacement + str.substr(index+searchFor.length);
			index = str.indexOf(searchFor);
		}
		return str;
	},

	decodeURIComponent: function(decodedTxt) {
		// first we replace any + chars with single space as javascript built in functions do not replace + wih space character
		var tempTxt = decodedTxt.replace(/\+/g, ' ');
		return decodeURIComponent(tempTxt);
	},
	
	// getPageSize()
	// Returns array with page width, height and window width, height
	// Core code from - quirksmode.org
	// Edit for Firefox by pHaez
	getPageSize: function(){
		
		var xScroll, yScroll;
		
		if (window.innerHeight && window.scrollMaxY) {	
			xScroll = document.body.scrollWidth;
			yScroll = window.innerHeight + window.scrollMaxY;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
			xScroll = document.body.scrollWidth;
			yScroll = document.body.scrollHeight;
		} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
			xScroll = document.body.offsetWidth;
			yScroll = document.body.offsetHeight;
		}
		
		var windowWidth, windowHeight;
		if (self.innerHeight) {	// all except Explorer
			windowWidth = self.innerWidth;
			windowHeight = self.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		} else if (document.body) { // other Explorers
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}	
		
		// for small pages with total height less then height of the viewport
		if(yScroll < windowHeight){
			pageHeight = windowHeight;
		} else { 
			pageHeight = yScroll;
		}
	
		// for small pages with total width less then width of the viewport
		if(xScroll < windowWidth){	
			pageWidth = windowWidth;
		} else {
			pageWidth = xScroll;
		}
	
		arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
		return arrayPageSize;
	},
	
	getScrollXY: function() {
		return new Array(window.pageXOffset
                || document.documentElement.scrollLeft
                || document.body.scrollLeft
                || 0,
			    window.pageYOffset
                || document.documentElement.scrollTop
                || document.body.scrollTop
                || 0);
	},

	showSelectBoxes: function() {
		var selects = document.getElementsByTagName("select");
		for (i = 0; i != selects.length; i++) {
			selects[i].style.visibility = "visible";
		}
	},

	hideSelectBoxes: function(){
		var selects = document.getElementsByTagName("select");
		for (i = 0; i != selects.length; i++) {
			selects[i].style.visibility = "hidden";
		}
	},
	
	showFlash: function(){
		var flashObjects = document.getElementsByTagName("object");
		for (i = 0; i < flashObjects.length; i++) {
			flashObjects[i].style.visibility = "visible";
		}
	
		var flashEmbeds = document.getElementsByTagName("embed");
		for (i = 0; i < flashEmbeds.length; i++) {
			flashEmbeds[i].style.visibility = "visible";
		}
	},
	
	hideFlash: function(){
		var flashObjects = document.getElementsByTagName("object");
		for (i = 0; i < flashObjects.length; i++) {
			flashObjects[i].style.visibility = "hidden";
		}
	
		var flashEmbeds = document.getElementsByTagName("embed");
		for (i = 0; i < flashEmbeds.length; i++) {
			flashEmbeds[i].style.visibility = "hidden";
		}
	},
	
	/*
	 * options = {onClick: function (){}, zIndex: 1000}
	 */
	showOverlay: function (options) {
		this.hideSelectBoxes();
		this.hideFlash();

		// stretch overlay to fill page and fade in
		var arrayPageSize = this.getPageSize();
		var element = $('overlay');
    	element.style.height = arrayPageSize[1] +"px";
    	
    	// following is to fix the opacity problem on IE 6
    	element.style.width = arrayPageSize[0] +"px";
    	
    	if (options && options.zIndex) {
	    	element.style.zIndex = options.zIndex;
    	}
    	
    	if (options && options.onClick) {
			Event.observe(element, 'click', (function () {
				options.onClick();
				this.hideOverlay();
			}).bind(this));
    	} else {
    		Event.observe(element, 'click', this.hideOverlay.bind(this));
    	}
		
		new Effect.Appear('overlay', { duration: this.overlayDuration, from: 0.0, to: this.overlayOpacity });
	},
	
	hideOverlay: function() {
		new Effect.Fade('overlay', { duration: this.overlayDuration});
		this.showSelectBoxes();
		this.showFlash();
	},
	
	isNumber : function(value) {
		value=value.strip();
		var regExp=/^\d+$/;
		return regExp.test(value);
	},
	
	padChars: function(value, padChar, len) {
		// to make sure value is string object
		var value = value + "";
		if (value.length >= len) return value;
		var padString = "";
		for (i = 0; i < len - value.length; i++) {
			padString = padChar + padString;
		}
		
		return padString + value;
	},
	
	removeLeadingPadChars: function(value, padChar) {
		// to make sure value is string object
		var value = value + ""; 
		value = value.replace(/^0*/,'');
		if(value=='') value="0";
		return value; 
	},
	
	
	trim: function(s){
		// Trim whitespace from left and right sides of s.
		return s.replace(/^\s*/,'').replace(/\s*$/,'');
	},
	
	showModelDialog: function(dialog, options) {
		var dialogElem = $(dialog);
		var dialogWidth = Element.getWidth(dialogElem);
		var dialogHeight = Element.getHeight(dialogElem);
		var arrayPageSize = this.getPageSize();
		var scrollXY = this.getScrollXY();
		var elemLeft = (arrayPageSize[2] - dialogWidth) / 2;
		var elemTop = (arrayPageSize[3] - dialogHeight) / 2;
		
    	dialogElem.style.left = (elemLeft + scrollXY[0]) +"px";
    	dialogElem.style.top = (elemTop + scrollXY[1]) +"px";
    	dialogElem.style.zIndex = options.dialog_zIndex;
    	new Effect.Appear(dialogElem, { duration: 0.3});
		this.showOverlay({zIndex: options.overlay_zIndex, onClick: function() {
			new Effect.Fade(dialogElem, { duration: 0.3});
		}});
	},
	
	hideModelDialog: function(dialog) {
		this.hideOverlay();
		new Effect.Fade(dialog, {duration: 0.3});
	},
	
	createCookie: function(name,value,days) {
		if (days) {
			var date = new Date();
			date.setTime(date.getTime()+(days*24*60*60*1000));
			var expires = "; expires="+date.toGMTString();
		}
		else var expires = "";
		document.cookie = name+"="+value+expires+"; path=/";
	},
	
	getCookie:  function(name) {
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for(var i=0;i < ca.length;i++) {
			var c = ca[i];
			while (c.charAt(0)==' ') c = c.substring(1,c.length);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
		}
		return null;
	},
	
	deleteCookie: function(name) {
		createCookie(name,"",-1);
	}
	
};

// create object to be used all over as singleton
var AppUtils = new AppUtilsClass();

/*
			var myAjax = new Ajax.Request( url, {method: 'get', parameters: params, onSuccess: function(originalReq){
					var element = document.createElement("script");
					element.setAttribute("type", "text/javascript");
					element.innerHTML = originalReq.responseText;
					document.getElementsByTagName("head")[0].appendChild(element);
			} });

*/