// GreenFish base helper library

var TXT_ERROR_UNKNOWN = 'Ootamatu tehniline viga! Vea kordumisel anna sellest teada ' + 'arendus' + '@nagi.' + 'ee';
var TXT_XFORM_LOAD = 'Laeb...';
//var TXT_ERROR_JSON = 'Ootamatu tehniline viga! Vigane vastus serverist';
var TXT_XFORM_LOAD = 'Laeb...';
var TXT_XFORM_POST = 'Oota hetk...';
//var SERVICE_XFORM_URI = '/services/xhtml/';
var SERVICE_XFORM_URI = '/nagi/module_photo_upload.html';

function GF () {
	return {
		UI: {},
		DOM: {},
		RPC: {},
		classmgr: {},
		session: {},
		reload: {},
		form: {},
		util: {}
	}
}

/*	DOM namespace for DOM queries
	*/
GF.DOM = function () {
	return {

		/*	Get single node by its id
			you can pass multiple arguments and get an collection in this case
			you can also pass collection or element itself,
			an single first element or element itself is returned in that case
			*/
		get: function (el) {
			if (arguments.length > 1) {
				collect = [];
				for (var i = 0; i < arguments.length; i++) {
					collect[i] = YAHOO.util.Dom.get(arguments[i].toString());
				}
				return collect;
			} else return (!el[0] || (typeof el == 'string')) ? YAHOO.util.Dom.get(el) : el[0];
		},

		/*	Get child node collection
			*/
		classChildren: function (el, classname) {
			//alert(el);
		},
		
		/*	Get single child element by class name
			*/
		classChild: function (el, classname) {
			if (GF.classmgr.isSet(el, classname))
					return el;
			else {
				for (var i=0; i < el.childNodes.length; i++) {
					if ((el.childNodes[i].nodeType == 1) && (GF.DOM.classChildren(el.childNodes[i], classname) != false)) return el.childNodes[i];
				}
			}
			return false;
		},
		
		/*	Get parent element by class name
			*/
		classParent: function (el, classname) {
			while (el.parentNode) {
				if (GF.classmgr.isSet(el, classname))
					return el;
				el = el.parentNode;
			}
			return null;
		},

		/*	Get parent element by tagname
			*/
		tagParent: function (el, tagname) {
			while (el.parentNode) {
				if (el.tagName.toLowerCase() == tagname)
					return el;
				el = el.parentNode;
			}
			return null;
		},
		
		/*	Performs CSS syntax query against entire DOM
			The following code is Copyright (C) Simon Willison 2004.
			ripped from Behaviour v1.1 by Ben Nolan, June 2005. 
			*/
		query: function (selector) {
			// Attempt to fail gracefully in lesser browsers
			if (!document.getElementsByTagName) {
				return new Array();
			}
			// Split selector in to tokens
			var tokens = selector.split(' ');
			var currentContext = new Array(document);
			for (var i = 0; i < tokens.length; i++) {
				token = tokens[i].replace(/^\s+/,'').replace(/\s+$/,'');;
				if (token.indexOf('#') > -1) {
					// Token is an ID selector
					var bits = token.split('#');
					var tagName = bits[0];
					var id = bits[1];
					var element = document.getElementById(id);
					if (tagName && element.nodeName.toLowerCase() != tagName) {
						// tag with that ID not found, return false
						return new Array();
					}
					// Set currentContext to contain just this element
					currentContext = new Array(element);
					continue; // Skip to next token
				}
				if (token.indexOf('.') > -1) {
					// Token contains a class selector
					var bits = token.split('.');
					var tagName = bits[0];
					var className = bits[1];
					if (!tagName) {
						tagName = '*';
					}
					// Get elements matching tag, filter them for class selector
					var found = new Array;
					var foundCount = 0;
					for (var h = 0; h < currentContext.length; h++) {
						var elements;
						if (tagName == '*') {
							elements = currentContext[h].all ? currentContext[h].all : currentContext[h].getElementsByTagName('*');
						} else {
							elements = currentContext[h].getElementsByTagName(tagName);
						}
						for (var j = 0; j < elements.length; j++) {
							found[foundCount++] = elements[j];
						}
					}
					currentContext = new Array;
					var currentContextIndex = 0;
					for (var k = 0; k < found.length; k++) {
						if (found[k].className && found[k].className.match(new RegExp('\\b'+className+'\\b'))) {
							currentContext[currentContextIndex++] = found[k];
						}
					}
					continue; // Skip to next token
				}
				// Code to deal with attribute selectors
				if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
					var tagName = RegExp.$1;
					var attrName = RegExp.$2;
					var attrOperator = RegExp.$3;
					var attrValue = RegExp.$4;
					if (!tagName) {
						tagName = '*';
					}
					// Grab all of the tagName elements within current context
					var found = new Array;
					var foundCount = 0;
					for (var h = 0; h < currentContext.length; h++) {
						var elements;
						if (tagName == '*') {
							elements = getAllChildren(currentContext[h]);
						} else {
							elements = currentContext[h].getElementsByTagName(tagName);
						}
						for (var j = 0; j < elements.length; j++) {
							found[foundCount++] = elements[j];
						}
					}
					currentContext = new Array;
					var currentContextIndex = 0;
					var checkFunction; // This function will be used to filter the elements
					switch (attrOperator) {
						case '=': // Equality
							checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
							break;
						case '~': // Match one of space seperated words 
							checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('\\b'+attrValue+'\\b'))); };
							break;
						case '|': // Match start with value followed by optional hyphen
							checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp('^'+attrValue+'-?'))); };
							break;
						case '^': // Match starts with value
							checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
							break;
						case '$': // Match ends with value - fails with "Warning" in Opera 7
							checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
							break;
						case '*': // Match ends with value
							checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
							break;
						default :
							// Just test for existence of attribute
							checkFunction = function(e) { return e.getAttribute(attrName); };
					}
					currentContext = new Array;
					var currentContextIndex = 0;
					for (var k = 0; k < found.length; k++) {
						if (checkFunction(found[k])) {
							currentContext[currentContextIndex++] = found[k];
						}
					}
					// alert('Attribute Selector: '+tagName+' '+attrName+' '+attrOperator+' '+attrValue);
					continue; // Skip to next token
				}
				if (!currentContext[0]){
					return;
				}
				// If we get here, token is JUST an element (not a class or ID selector)
				tagName = token;
				var found = new Array;
				var foundCount = 0;
				for (var h = 0; h < currentContext.length; h++) {
					var elements = currentContext[h].getElementsByTagName(tagName);
					for (var j = 0; j < elements.length; j++) {
						found[foundCount++] = elements[j];
					}
				}
				currentContext = found;
			}
			return currentContext;
			/* That revolting regular expression explained 
			/^(\w+)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/
			  \---/  \---/\-------------/    \-------/
				|      |         |               |
				|      |         |           The value
				|      |    ~,|,^,$,* or =
				|   Attribute 
			   Tag
			*/
		}

	};
}();




/**
 * GF util namespace
 * container various shorthand wrappers
 */
GF.util = function () {
	return {
		dump: function (obj) {
			var str = '';
			for (var k in obj) { str += k + ':' + obj[k] + '\n'; }
			return str;
		},
		isFunction: function (obj) {
			return (obj.toString().toLowerCase().indexOf('function') == 0 && obj.toString().lastIndexOf('}') == obj.toString().length-1) ? true : false;
		},
		QueryStrFromArgs: function (arr) {
			var start = (arguments[1]) ? arguments[1] : 0;
			var uri = '';
			for (var i=start; i<arr.length-1; i=i+2) {
				uri += ((uri == '') ? '' : '&') + arr[i] + '=' + arr[i+1];
			}
			return uri;
		}
	}
}();



GF.form = function () {
	return {
		selectbox: {},
		csubmit: function(fname) {
			var success = function(el) {
				GF.classmgr.toggle(el.argument.fname + '_area', 'hide');
				GF.classmgr.toggle(el.argument.fname + '_show', 'hide');

				var module = GF.DOM.get(el.argument.fname + '_show');
				module.innerHTML = el.responseText;
			};

			var my_txt = GF.DOM.get(fname + '_textfield');
			var id = GF.DOM.get('picture_id');

			var req = '/services/json/?context=user_photo_details';
			var param = 'set=' + fname + '&' + fname + '='+encodeURIComponent(my_txt.value)+'&picture_id='+id.value;
			var request = YAHOO.util.Connect.asyncRequest( 'POST', req, {success:success, argument:{fname:fname}}, param );

			return false;
		},
               /*      Submit a form while setting elements' values before
                       form name or element as first argument
                       arbitrary even number of additional arguments to set existing values
                       or create new ones
                       */
               submit: function (frm) {
                       var f = GF.DOM.get(frm);
                       for (var i=1; i < arguments.length; i=i+2) {
                               var el = f.elements[arguments[i]];
                               if (el == null) {
                                       el = document.createElement('input');
                                       el.type = 'hidden';
                                       el.name = arguments[i];
                                       f.appendChild(el);
                               }
                               el.value = arguments[i+1];
                       }
                       f.submit();
                        return false;
               }/*,
               ajaxpost: function (frm) {
                       var f = GF.DOM.get(frm);
                       var success = function (r) { GF.UI.message.create('messagebox', 'confirm', r.responseText); };
                       var failure = function (r) { GF.UI.message.create('messagebox', 'error', r.responseText); };
                       try {
                               var callback = (arguments[1]) ? arguments[1] : {success:success, failure:failure};
                               if (!callback.success) callback.success = success;
                               if (!callback.failure) callback.failure = failure;
                               YAHOO.util.Connect.setForm(frm);
                               Nagi.actions.current[Nagi.actions.current.length] = YAHOO.util.Connect.asyncRequest( frm.method.toUpperCase(), frm.action, callback); 
                       } catch (e) {
                               GF.UI.message.create('messagebox', 'error', e.message);
                       }
                       return false;
               }*/
	}
}();

GF.form.selectbox = function () {
	return {
		createOptions: function (el, data) {
			var sel = GF.DOM.get(el);
			var opt = null;
			var cur = (arguments[2]) ? arguments[2] : null;
			for (var key in data) {
				opt = document.createElement("option");
				opt.appendChild(document.createTextNode(data[key]));
				opt.value = key;
				opt.selected = (key == cur);
				sel.appendChild(opt);
			}
		},
		removeOptions: function (el, empty) {
			var sel = GF.DOM.get(el);
			var idx = (empty) ? 0 : 1;
			while (sel.options.length > idx) {
				sel.removeChild(sel.options[idx]);
			}
		},
		replaceOptions: function (el, data, empty) {
			GF.form.selectbox.removeOptions(el, empty);
			GF.form.selectbox.createOptions(el, data);
		}
	}
}();


/*GF.DOM = function () {
}

//	get DOM node whether id or object itself is specified
GF.DOM.get = function (elm) {
	return YAHOO.util.Dom.get(elm);
}*/

//	get first upper node matching classname
/*GF.DOM.getContainerNodeByClassname = function (el, classname) {
	while (el.parentNode) {
		if (GF.classmgr.isSet(el, classname))
			return el;
		el = el.parentNode;
	}
	return false;
}

//	get first inner node matching classname
GF.DOM.getInnerNodeByClassname = function (el, classname) {
	for (var i=0; i<el.childNodes.length; i++) {
		if (GF.classmgr.isSet(el.childNodes.item(i), classname)) {
			return el.childNodes.item(i);
		}
	}
	return false;
}*/


/**
* function for page reloading
**/
GF.reload = function () {
        document.location.reload();
}


/**
 * GF classMGR namespace
 * for managing multiple node classes runtime
 */
GF.session = function () {
	return {
		set: 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 = "";

			var tmp1 = document.location.toString().split('//');
			var tmp2 = tmp1[1].split('/');
			var tmp3 = tmp2[0].split('.');
			var domain = '.'+tmp3[tmp3.length-2] + '.' + tmp3[(tmp3.length-1)];

			document.cookie = name+"="+value+expires+"; path=/; domain="+escape(domain);
		},
		get: function (name) {
			var tmp = '';
			var cname = '';
			var ca = document.cookie.split(';');
			for(var i=0;i < ca.length;i++) {
				tmp = ca[i].split( '=' );
				cname = tmp[0].replace(/^\s+|\s+$/g, '');
				if (cname == name)
					return(unescape(tmp[1].replace(/^\s+|\s+$/g, '')));
			}
			return null;
		},
		remove: function (name) {
			GF.session.set(name,"",-1);
		}
   	}
}();



/**
 * GF classMGR namespace
 * for managing multiple node classes runtime
 */
GF.classmgr = function () {
	return {
		//	set class name if it does not exist, remove otherwise
		toggle: function (elm, classItem) {
			var f = function (elm, classItem) {
				return (YAHOO.util.Dom.hasClass(elm, classItem)) ? YAHOO.util.Dom.removeClass(elm, classItem) : YAHOO.util.Dom.addClass(elm, classItem);
			}
			YAHOO.util.Dom.batch(elm, f, classItem, true);
			return false;
		},
		// swap class presence in two nodes
		swap: function (el1, el2, classItem) {
			YAHOO.util.Dom.removeClass(el2, classItem);
			YAHOO.util.Dom.addClass(el1, classItem);
			return true;
		},
		//	set single class item to the node
		attach: function(elm, classItem) {
			return YAHOO.util.Dom.addClass(elm, classItem);
		},
		setStyle: function(elm, styleItem, styleVal) {
			return YAHOO.util.Dom.setStyle(elm, styleItem, styleVal);
		},
		//	return true if class is specified on the node 
		isSet: function(elm, classItem) {
			return YAHOO.util.Dom.hasClass(elm, classItem);
		},
		//	remove single class from node class collection
		remove: function(elm, classItem) {
			return YAHOO.util.Dom.removeClass(elm, classItem);
		},
		//	get node classes as a array
		toArray: function(elm) {
			classStr = (elm.className != 'undefined') ? elm.className : '';
			classArr = (classStr) ? elm.className.split(" ") : new Array();
			return classArr;
		}
	}
}();





/**
 * NAGI UI namespace
 * for user interface library specific functions
 * should use this as a wrapper for common ui actions
 * such as menu switching, module handling, messaging
 */

GF.UI = function () {
	return {
		menu: {
			tabToggle: function (el) { // el - tab link reference or id
				li = GF.DOM.tagParent(el, 'li');
				if (GF.classmgr.isSet(li, 'selected')) {
					GF.UI.menu.reset( GF.DOM.tagParent(el, 'ul') );
				} else {
					return GF.UI.menu.tabOpenSingle(el);
				}
				el.blur();
				return false;
			},
			isSelected: function (el) { // el - tab link reference or id
				li = GF.DOM.tagParent(el, 'li');
				return GF.classmgr.isSet(li, 'selected');
			},
			tabOpenSingle: function (el) { // el - tab link reference or id
				ul = GF.DOM.tagParent(el, 'ul');
				li = GF.DOM.tagParent(el, 'li');
				GF.UI.menu.reset(ul);
				try {
					GF.classmgr.remove( GF.DOM.get(el.hash.substring(1)), 'hide' );
				} catch (e) {
					throw new Error('Link hash not found in current document!');
				}
				GF.classmgr.attach(li, 'selected');
				el.blur();
				return false;
			},
			tickToggle: function (el) {
				var container = el.parentNode;
				GF.classmgr.toggle(container, 'on');
				return false;
			},
			resetByHref: function (el) { 
				var x = document.getElementsByTagName('a');
				for (var i=0;i<x.length;i++) {
					tmp = x[i].getAttribute('href');
					if (tmp != null && tmp == el || tmp == document.location + el) {
						ul = GF.DOM.tagParent(x[i], 'ul');
						return(GF.UI.menu.reset(ul));
					}
				}
			},
			reset: function (el) { // el - menu container ul reference or id
				ul = GF.DOM.get(el);
				for (var i=0; i<ul.childNodes.length; i++) {
					oli = ul.childNodes[i];
					if ((oli.nodeType==1) && GF.classmgr.isSet(oli, 'selected')) {
						GF.classmgr.remove(oli, 'selected');
						try {
							GF.classmgr.attach( GF.DOM.get(oli.firstChild.hash.substring(1)), 'hide' );
						} catch (e) {
							throw new Error('Link hash not found in current document!');
						}
					}
				}
				return true;
			}
		},
		message: {
			create: function (container, stat, message) {
				if (message.length > 0) {
					GF.UI.message.reset(container);
					div = GF.DOM.get(container);
					if (div != null) {
						msg = document.createElement('div');
						h2 = document.createElement('h2');
							GF.classmgr.attach(h2, 'pagemessage');
							GF.classmgr.attach(h2, stat);
						a = document.createElement('a');
							a.href = '#' + container;
							a.onclick = function () { return GF.UI.message.close(a) };
						em = document.createElement('em');
						em.appendChild(document.createTextNode('Sulge'));
						a.appendChild(em);
						h2.appendChild(document.createTextNode(message));
						h2.appendChild(a);
						msg.appendChild(h2);
						div.appendChild(msg);
					}
				}
			},
			close: function (el) {
				msg = GF.DOM.classParent(el, 'pagemessage');
				msg.parentNode.removeChild(msg);
				return false;
			},
			reset: function (container) {
				div = GF.DOM.get(container);
				if (div != null) {
					while (child = div.firstChild) {
						div.removeChild(child);
					}
				}
			}
		},
		module: {
			minimizeToggle: function (el) {
				var f = function(el) {
					moduleElm = GF.DOM.classParent(el, 'module');
					if (moduleElm) {
						var context = document.body.id;
						var module = moduleElm.id;
						var uri = '/services/json/?context='+context+'&module='+module+'&set=';
						if (GF.classmgr.isSet(moduleElm, 'closed')) {
							GF.classmgr.remove(moduleElm, 'closed');
							uri = uri + '1';
						} else {
							GF.classmgr.attach(moduleElm, 'closed');
							uri = uri + '0';
						}
						if ( YAHOO.util.Connect != null)
							var request = YAHOO.util.Connect.asyncRequest( 'GET', uri, {} );
					}
					return false;
				}
				YAHOO.util.Dom.batch(el, f, this, true);
				return false;
			},
			create: function (id) {
			},
			open: function (el) {
			},
			close: function (el) {
				var f = function(el) {
					moduleElm = GF.DOM.classParent(el, 'module');
					if (moduleElm) {
						moduleElm.parentNode.removeChild(moduleElm);
						//todo: check if containing zone is empty. hide in this case
						return false;
					}
				}
				YAHOO.util.Dom.batch(el, f, this, true);
				return false;
			},
			load: function (el) {
				},
			reload: function (el) {
				}
		},
		zone: {}
	}
}();






/*	Nagi namespace for application specific UI procedures */


Nagi = function () {
	return {
		module: {},
		badges: {},
		actions: {},
		masterpage: {},
		session: {},
		json: {},
		mail: {},
		Login: {}
	};
};


Nagi.masterpage = {
	toggleSidebar: function (elm) {
		var el = GF.DOM.get('container');
		var classItem = 'compact';
		var uri = '/services/json/?context=usermenu&module=sidebar&set=';

		if (YAHOO.util.Dom.hasClass(el, classItem)) {
			YAHOO.util.Dom.removeClass(el, classItem);
			uri = uri + '1';
		} else {
			YAHOO.util.Dom.addClass(el, classItem);
			uri = uri + '0';
		}

		if ( YAHOO.util.Connect != null)
			var request = YAHOO.util.Connect.asyncRequest( 'GET', uri, {} );
		return false;
	},
	toggleSubheader: function (trigger) {
		var shd = GF.DOM.get('subheader');
		var div = GF.DOM.get(trigger.hash.substring(1));
		var tab = GF.DOM.tagParent(trigger, 'li');
		if (GF.classmgr.isSet(div, 'hide')) {
			GF.classmgr.remove(div, 'hide');
			GF.classmgr.attach(tab, 'selected');
			GF.classmgr.remove(shd, 'hide');
		} else {
			GF.classmgr.attach(div, 'hide');
			GF.classmgr.remove(tab, 'selected');
			if (!Nagi.masterpage.isSubheaders()) GF.classmgr.attach(shd, 'hide');
		}
		//GF.classmgr.remove(shd, 'hide');
		//GF.classmgr.remove(div, 'hide');
		//alert(div);
		return false;
	},
	isSubheaders: function () {
		var shd = GF.DOM.get('subheader');
		var cld = shd.getElementsByTagName('p');
		for (var i=0; i < cld.length; i++) {
			if (!GF.classmgr.isSet(cld[i], 'hide')) return true;
		}
		return false;
	},
	opentab: function(el) {
		args = new Object();
		for (var i=1; i<arguments.length; i=i+2) {
			args[arguments[i]] = arguments[i+1];
		}
		var trigger = GF.DOM.get(el);
		GF.UI.menu.tabToggle(trigger);
		if (GF.UI.menu.isSelected(trigger)) return Nagi.actions.open(trigger, args);
		else return Nagi.actions.close(trigger);
	},
	decorate: function () {
		modules = GF.DOM.query('.boxed');
		for (var i=0; i<modules.length; i++) {
			//create new wrapper elements
			headerDiv = document.createElement('div');
			footerDiv = document.createElement('div');
			headerCornerDiv = document.createElement('div');
			footerCornerDiv = document.createElement('div');
			GF.classmgr.attach(headerDiv, "moduleheader");
			GF.classmgr.attach(footerDiv, "modulefooter");
			GF.classmgr.attach(headerCornerDiv, "corner");
			GF.classmgr.attach(footerCornerDiv, "corner");
			//build DOM
			headerDiv.appendChild(headerCornerDiv);
			footerDiv.appendChild(footerCornerDiv);
			modules[i].insertBefore(headerDiv, modules[i].childNodes[0]);
			modules[i].appendChild(footerDiv);
			GF.classmgr.attach(modules[i], "decorated");
		}
		return true;
	}
};


Nagi.actions = {
	current: [],
	toggle: function (trigger) {
		args = new Object();
		evts = new Array();
		callback = null;
		for (var i=1; i<arguments.length; i=i+2) {
			if (arguments[i].toString().lastIndexOf('}')==arguments[i].toString().length-1) callback = arguments[i];
			else args[arguments[i]] = arguments[i+1];
		}
		GF.UI.menu.tabToggle(trigger);
		if (GF.UI.menu.isSelected(trigger)) return Nagi.actions.open(trigger, args, callback);
		else return Nagi.actions.close(trigger);
	},
	open: function (trigger, args, callback) {
		var timeout = null;
		var success = function (r) {
			var module = r.argument.container;
			Nagi.actions.hideStatus(module);
			module.innerHTML = r.responseText;
			if (callback) callback();
		};
		var failure = function (r) {
			//alert(Nagi.actions.current[Nagi.actions.current.length-1].tId);
			var module = r.argument.container;
			Nagi.actions.displayStatus(module, 'Error loading form.', 'no');
		};
		var div = GF.DOM.get(trigger.hash.substring(1));
		if (div.childNodes.length == 0) {
			Nagi.actions.displayStatus(div, TXT_XFORM_LOAD);
			var context = document.body.id;
			var module = div.id;
			var uri = '/services/xhtml/?context=' + context + '&module=' + module;
			for (var k in args) uri += "&" + k + "=" + args[k];
			// no las olla see kontroll
			if (YAHOO.util.Connect != null) {
				Nagi.actions.current[Nagi.actions.current.length] = YAHOO.util.Connect.asyncRequest( 'GET', uri, {success:success, failure:failure, argument:{container:div}} ); 
			} else {
				Nagi.actions.displayStatus(div, TXT_ERROR_UNKNOWN, 'no');
			}
		} else {
			if (callback) callback();
		}
		return false;
	},
	close: function (trigger) {
		var div = GF.DOM.get(trigger.hash.substring(1));
		return false;
	},
	tickRequest: function (trigger, uri) {
		var success = function (r) {
			GF.UI.menu.tickToggle(r.argument.trigger);
			GF.UI.message.create('messagebox', 'confirm', r.responseText); /*trigger.blur();*/
		};
		var callback = (arguments[2]) ? arguments[2] : {success:success, argument:{trigger:trigger}};
		if (!callback.success) callback.success = success;
		var args = (arguments[3]) ? arguments[3] : null;
		Nagi.actions.requestGET(uri, callback, args);
		return false;
	},
	requestGET: function (uri) {
		var success = function (r) { GF.UI.message.create('messagebox', 'confirm', r.responseText); };
		var failure = function (r) { GF.UI.message.create('messagebox', 'error', r.responseText); };
		try {
			var args = (arguments[2]) ? arguments[2] : new Array();
			var request = uri + '?' + GF.util.QueryStrFromArgs(args) + '&context=' + document.body.id;
			var callback = (arguments[1]) ? arguments[1] : {success:success, failure:failure};
			if (!callback.success) callback.success = success;
			if (!callback.failure) callback.failure = failure;
			Nagi.actions.current[Nagi.actions.current.length] = YAHOO.util.Connect.asyncRequest( 'GET', request, callback); 
			//YAHOO.util.Connect.asyncRequest( 'GET', request, callback); 
		} catch (e) {
			GF.UI.message.create('messagebox', 'error', e.message);
		}
		return false;
	},
	requestPostSuccess: function (r) {
		if (Nagi.JSON.responseCode(r.responseText) >= 0) {
			var tmpurl = Nagi.JSON.redirect(r.responseText);
			var tmpreload = Nagi.JSON.reload(r.responseText);
			if (tmpurl != '') {
				document.location.href = tmpurl;
			} else if (tmpreload) {
				document.location.reload();
			} else if (r.argument.redirect) {
				document.location.href = r.argument.redirect + '?' + Nagi.JSON.varCode + '=' + Nagi.JSON.responseCode(r.responseText);
			} else {
				if (r.argument.container) {
					Nagi.actions.hideStatus(r.argument.container);
					if (r.argument.form.onreset) r.argument.form.onreset();
				}
				GF.UI.message.create(r.argument.messagebox, 'confirm', Nagi.JSON.responseMessage(r.responseText) );
			}
		} else {
			r.argument.failure(r);
		}
	},
	requestPostFailure: function (r) {
		Nagi.actions.hideStatus(r.argument.container);
		GF.UI.message.create(r.argument.messagebox, 'error', 
			Nagi.JSON.responseMessage(r.responseText) );
	},
	requestPOST: function (frm) {
		try {
			// var f = GF.DOM.get(frm);
			var parameter = (arguments[1]) ? arguments[1] : {};
			var argument = {
				action: (parameter.action) ? parameter.action : frm.action,
				redirect: (parameter.redirect) ? parameter.redirect : null,
				container: (parameter.container) ? parameter.container : GF.DOM.classParent(frm, 'actionform'),
				messagebox: (parameter.messagebox) ? parameter.messagebox : 'messagebox',
				failure: (parameter.failure) ? parameter.failure : Nagi.actions.requestPostFailure,
				form: frm
				};
			var callback = {
				success: (parameter.success) ? parameter.success : Nagi.actions.requestPostSuccess,
				failure: argument.failure,
				argument: argument
				};
			if (argument.container) Nagi.actions.displayStatus(argument.container, TXT_XFORM_POST);
			frm.action = argument.action;
			YAHOO.util.Connect.setForm(frm);
			Nagi.actions.current[Nagi.actions.current.length] = YAHOO.util.Connect.asyncRequest( frm.method.toUpperCase(), frm.action, callback); 
		} catch (e) {
			GF.UI.message.create(argument.messagebox, 'error', e.message);
			return true;
		}
		return false;
	},
	displayStatus: function (module, message) {
		module = GF.DOM.get(module);
		if (module != null) {
			var e = module.childNodes;
			Nagi.actions.hideStatus(module);
			d = document.createElement('div');
			d.appendChild( document.createTextNode(message) );
			d.className = 'status';
			module.insertBefore(d, module.firstChild);
			if (arguments[2]) {
				GF.classmgr.attach(d, arguments[2]);
			} else d.className = 'status';
		}
	},
	hideStatus: function (module) {
		module = GF.DOM.get(module);
		if (module != null) {
			var div = module.firstChild;
			if (div != null && div.nodeType == 1) {
				if (GF.classmgr.isSet(div, 'status')) module.removeChild(div);
			}
		}
	},

	// for prompting and adding an select option to select menu
	AskAndAddSelectOption: function (str,id) {
		name = prompt(str);
		if (name != null && name.length > 0) {
			s = GF.DOM.get(id);
			if (s != null) {
				var opt = new Option(name,'new:'+name,0,0);
				s.options[s.options.length] = opt;
				s.options.selectedIndex = s.options.length -1;
				return(true);
			}
        	}
        	return(false);
	}
};


Nagi.module = {
	toggle: function (el) {
		GF.UI.module.minimizeToggle(el);
		return false;
	},
	xtoggle: function (trigger) {
		args = new Object();
		evts = new Array();
		callback = null;
		for (var i=1; i<arguments.length; i=i+2) {
			if (arguments[i].toString().lastIndexOf('}')==arguments[i].toString().length-1) callback = arguments[i];
			else args[arguments[i]] = arguments[i+1];
		}
		moduleElm = GF.DOM.classParent(trigger, 'module');
		if (moduleElm) {
			if (GF.classmgr.isSet(moduleElm, 'closed')) {
				var div = GF.DOM.get(trigger.hash.substring(1));
				if (div.childNodes.length == 0) {
					GF.classmgr.remove(moduleElm, 'closed');
					return Nagi.module.open(trigger, args, callback);

				// use json for module which has contents
				}else
				{
					GF.UI.module.minimizeToggle(trigger);
					Nagi.badges.add(trigger.hash.substring(1),rows);
					return(false);
				}
			} else {
				return(GF.UI.module.minimizeToggle(trigger));
			}
		}
	},
	open: function (trigger, args, callback) {
		var timeout = null;

		var success = function (r) {
			var module = r.argument.container;
			var rows = r.argument.rows;
			Nagi.actions.hideStatus(module);
			module.innerHTML = r.responseText;

			Nagi.badges.add(module.id,rows);
		};

		var failure = function (r) {
			var module = r.argument.container;
			Nagi.actions.displayStatus(module, 'Error loading form.', 'no');
		};

		var div = GF.DOM.get(trigger.hash.substring(1));
		if (div.childNodes.length == 0) {
			Nagi.actions.displayStatus(div, TXT_XFORM_LOAD);
			var context = document.body.id;
			moduleElm = GF.DOM.classParent(trigger, 'module');
			if (moduleElm) {
				var module = moduleElm.id;
			} else {
				var module = div.id;
			}
			var uri = '/services/xhtml/module.php?context=' + context + '&module=' + module;
			for (var k in args) uri += "&" + k + "=" + args[k];
			// no las olla see kontroll
			if (YAHOO.util.Connect != null) {
				Nagi.actions.current[Nagi.actions.current.length] = YAHOO.util.Connect.asyncRequest( 'GET', uri, {success:success, failure:failure, argument:{container:div, rows: args['rows']} } ); 
			} else {
				Nagi.actions.displayStatus(div, TXT_ERROR_UNKNOWN, 'no');
			}
		}
		return false;
	}
};

function activateSelect(id, obj)
{
	var i = -1;
	while(true)
	{
		if (GF.DOM.get(id+i))
			GF.classmgr.attach(id+i, 'hide');
		else if (i > 0)
			break;
		i++;
	}

	if (obj.selectedIndex > 0)
	{
		var sel = obj.options[obj.selectedIndex].value;

		GF.classmgr.remove(id+sel, 'hide');
	}
}

function registerKey(key,url) {
	if (url != null)
		keyArray[key] = url;
	else
		keyArray[key] = null;
}

function registerKeyAction(key,action) {
	keyAction[key] = action;
}

document.onkeydown = function (evt) {
        evt = evt || window.event;
        keycode = evt.keyCode || evt.which;   
        tag = (evt.srcElement) ? evt.srcElement.tagName : evt.target.nodeName;
	if (tag != null) tagname = tag.toUpperCase();
	else tagname = '';
 
        // disable for form elements && input
        if (tagname == 'INPUT' || tagname == 'TEXTAREA' || tagname == 'SELECT')
                return(true);

	// disable shortcuts if something is selected
	if (window.getSelection && window.getSelection() != '') 
		return(true);
	else if (document.selection && document.selection.createRange && 
		document.selection.createRange().text != '')
		return(true);

        // evt.ctrlKey
        // evt.shiftKey
        // evt.altKey

        var index = numindex = '';
        if (evt.ctrlKey) index = index + 'CTRL+';
        if (evt.shiftKey) index = index + 'SHIFT+';
        if (evt.altKey) index = index + 'ALT+';
	numindex = index + keycode
	index = index + String.fromCharCode(keycode);

	if (keyArray[index] != null) {
		document.location = keyArray[index];
		return(false);

	}else if (keyArray[numindex] != null) {
		document.location = keyArray[numindex];
		return(false);

	}else if (keyAction[index] != null) {
		eval(keyAction[index]);
		return(false);

	}else if (keyAction[numindex] != null) {
		eval(keyAction[numindex]);
		return(false);
	}

	//testing purpose only
	//alert(index);

	return(true);
}

var keyArray = new Array();
var keyAction = new Array();
var nagi_username;

Nagi.badges = {
	add: function (name, rows) {
		opts = { name: name, rows: rows };
		// already in body

		if (GF.DOM.get(name) != null)
			Nagi.badges.displayUpdate(null,opts);

		YAHOO.util.Event.addListener(window, 'load', Nagi.badges.displayUpdate, opts, false );
		YAHOO.util.Event.addListener(window, 'resize', Nagi.badges.displayUpdate, opts, false );
	},
	displayUpdate: function (e, o) {
		name = o.name;
		rows = o.rows;
		holder = GF.DOM.get(name);
		if (holder == null)
				return;
		badges = holder.getElementsByTagName('a');
		if (badges.length == 0)
				return;
		var count = parseInt(holder.offsetWidth / badges[0].offsetWidth);
		if (count == 0)
				return;
		if (rows > 1) count = count * rows;
		var topoffset = badges[0].offsetTop;
		var currow = 1;
		for (var i=1; i < badges.length; i++) {
			p = badges[i].parentNode;

			if (p == null)
				break;

			if (i < count) {

				GF.classmgr.remove(p, 'hide');
				if (badges[i].offsetTop > topoffset) {
	
					if (currow < rows) {

						topoffset = badges[i].offsetTop;
						currow++;

					}else
						GF.classmgr.attach(p, 'hide');
				}
			}else 
				GF.classmgr.attach(p, 'hide');
		}
	}
};


Nagi.JSON = {
        varMessage: 'NagiStatusMsg',
        varCode: 'NagiStatusCode',
        varRedirect: 'NagiRedirect',
        varReload: 'NagiReload',

        responseData: function (text) {
                var r = "var d=" + text + ";";
                try {
                        eval(r);
                } catch (e) {
                        var d = { NagiStatusCode: -1, NagiStatusMsg: TXT_ERROR_UNKNOWN, NagiRedirect: "" };
                }
                return d;
        },
        responseMessage: function (text) {
                var data = Nagi.JSON.responseData(text);
                return (data[Nagi.JSON.varMessage]) ? data[Nagi.JSON.varMessage] : "";
        },
	redirect: function (text) {
		var data = Nagi.JSON.responseData(text);
                return (data[Nagi.JSON.varRedirect]) ? data[Nagi.JSON.varRedirect] : "";
        },
	reload: function (text) {
		var data = Nagi.JSON.responseData(text);
                return (data[Nagi.JSON.varReload]) ? data[Nagi.JSON.varReload] : "";
        },
        responseCode: function (text) {
		var data = Nagi.JSON.responseData(text);
		return (data[Nagi.JSON.varCode]) ? parseInt(data[Nagi.JSON.varCode]) : 0;
        }
};

Nagi.mail = {
	send: function(obj) {
		if (groupValidate(obj)) {
			 Nagi.actions.requestPOST(obj,{success: Nagi.mail.sendSuccess})
		}
		return(false);
		
	},
	sendSuccess: function (r) {
		Nagi.actions.requestPostSuccess(r);
		GF.UI.menu.resetByHref('#sendmessage');
	}
};

Nagi.Login = {
	open: function (trigger) {
		Nagi.masterpage.toggleSubheader(trigger);
		if (!GF.classmgr.isSet('subheader_login', 'hide')) GF.DOM.get('login_username').focus();
		return false;
	},
	failure: function (r) {
		Nagi.actions.displayStatus('login_status',  Nagi.JSON.responseMessage(r.responseText), 'no');
		GF.DOM.get('login_username').disabled = false;
		GF.DOM.get('login_password').disabled = false;
	},
	process: function (frm) {
		Nagi.actions.requestPOST(frm, {
						container: 'login_status',
						failure: Nagi.Login.failure
						}
		);
		GF.DOM.get('login_username').disabled = true;
		GF.DOM.get('login_password').disabled = true;
		return(false);
	}
};

function KuvaBanner(url, w, h, wmode)
{
	document.writeln('<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0" width="'+w+'" height="'+h+'">');
	document.writeln('<param name="movie" value="'+url+'" />');
	document.writeln('<param name="quality" value="high" />');
	document.writeln('<param name="name" value="movie" />');
	document.writeln('<param name="swLiveConnect" value="true" />');
	if (wmode == 1)
	{
		document.writeln('<param name="wmode" value="transparent" />');
		document.writeln('<embed src="'+url+'" wmode="transparent" quality="high" scale="noscale" width="'+w+'" height="'+h+'" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />');
	}
	else
	{
		document.writeln('<embed src="'+url+'" quality="high" scale="noscale" width="'+w+'" height="'+h+'" align="middle" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" />');
	}
	document.writeln('</object>');
}

