jQuery(function() {
	manu.init();
});

(function( window ) {
	gDisableJSValidation = false;
	gJsHandlers = [];
	gValidateRules = new Object;
	gValidateRules1 = new Object;
	gMessages = new Object;
	pageloadflag = true;
	lasthash = "";

var manu = {

	debugJavascript: true,
	supportHistoryPlugin : false,
	dialogElement : null,
	pendingJs : [],
	executedHandlers : [],
	ajaxError: false,
	loadedScripts: [],
	loadedStyles: [],

	// initialize
	init : function() {
		if (manu.supportHistoryPlugin) {
			if (location.hash) {
				manu.pagination.handlePageload(location.hash);
			}
			$.historyInit(manu.utils.handlePageload);
		}
		$.ajaxSetup( {
			cache : false,
			dataFilter : manu.sanitizeResponseData
		});

		$("#loading").hide();
		$("#loading").ajaxSend(function(event, xhr, options) {
			if(options.dataType == "json") {
				xhr.setRequestHeader('Fw-Json', 1);
			}
			xhr.setRequestHeader('Fw-Ajax', 1);
			$(this).show();
		});
		$("#loading").ajaxComplete(function(event, xhr, options) {
			$(this).hide();
			manu.executePendingJs();
		});
		$("#loading").ajaxError(function(event, request, settings) {
			manu.handleAjaxError(request.responseText, settings.url);
			return false;
		});
	},

	// handle the metadata (debug data, javascript) that framework sends along with the main data
	sanitizeResponseData : function(data, type) {
		if(data.indexOf("<!--FW_SEPARATOR-->") <= 0) return data;
		var temp = data.split("<!--FW_SEPARATOR-->");
		var fwdata = temp[0];
		data = temp[1];
		if (fwdata.match(/[\s\S]*<!--FW_DEBUG-->[\s\S]*/)) {
			var debugData = fwdata.replace(
					/^[\s\S]*?<!--FW_DEBUG-->([\s\S]*?)<!--FW_DEBUG-->[\s\S]*?$/,
			"$1");
			if (debugData) {
				$("#fw_debug_ajax_actions").append(debugData);
			}
		}
		if (fwdata.match(/[\s\S]*<!--FW_JS-->[\s\S]*/)) {
			var js = fwdata.replace(
					/^[\s\S]*?<!--FW_JS-->([\s\S]*?)<!--FW_JS-->[\s\S]*?$/,
			"$1");
			if (js) {
				manu.pendingJs.push(js);
			}
		}
		return data;
	},

	log: function(msg) {
		if (typeof console != "undefined") {
			if(console.log) {
				console.log(msg);
			}
		}
	},

	debug: function(msg) {
		if (typeof console != "undefined") {
			if(console.log && manu.debugJavascript && ENVIRONMENT != "PRD") {
				console.log(msg);
			}
		}
	},

	// execute all the pending js (from metadata)
	executePendingJs: function () {
		if (manu.pendingJs.length > 0) {
			var js = manu.pendingJs.pop();
			eval(js);
		}
	},

	loadScripts: function(scripts) {
		if(!scripts) return;
		for (var i in scripts) {
			var script = scripts[i];
			manu.debug("loading script " + script);
			if($.inArray(script, manu.loadedScripts) == -1) {
				$.ajax({
					  url: script,
					  dataType: 'script',
					  async: false
					});
				manu.loadedScripts.push(script);
			}
			else {
				manu.log('script already loaded');
			}
		}
	},

	loadStyles: function(styles) {
		if(!styles) return;
		for (var i in styles) {
			var style = styles[i];
			manu.debug("loading style " + style);
			if($.inArray(style, manu.loadedStyles) == -1) {
				$('<link rel="stylesheet" type="text/css" href="'+ style +'" >')
				   .appendTo("head");
				manu.loadedStyles.push(style);
			}
			else {
				manu.log('style already loaded');
			}
		}
	},

	// execute the javascript handlers
	executeJsHandlers: function(handlers) {
		for(var id in handlers) {
			var h = handlers[id];
			manu.executeJsHandler(id, h.name, h.params, h.alwaysExec);
		}
	},

	// execute the javascript handler. execute a handler only once unless requested otherwise
	executeJsHandler : function(id, handler, params, alwaysExec) {
		if (!alwaysExec	&& jQuery.inArray(id, manu.executedHandlers) != -1) {
			return;
		}
		if (handler == '') {	return; }
		var handler1 = eval(handler);
		if(!handler1) {
			throw "Handler " + handler + " is not defined";
		}
		var fparams = [];
		for(var i in params) {
			fparams.push(params[i]);
		}
		manu.debug("Executing handler [" + handler + "]" + "[" + fparams.join(",") + "]");
		handler1.apply(params, fparams);
		if (jQuery.inArray(id, manu.executedHandlers) == -1) {
			manu.executedHandlers.push(id);
		}
	},

	// get the localized static messages
	getMsg : function(msg_id, args) {
		arg_array = manu.utils.is_array(args);
		msg = gStaticMessages[msg_id];
		if (arg_array) {
			for ( var i = 0; i < args.length; i++) {
				msg = msg.replace("{" + (i + 1) + "}", args[i]);
			}
		} else {
			msg = msg.replace("{1}", args);
		}
		return msg;
	},

	alertMsg : function(msg_id, args) {
		alert(manu.getMsg(msg_id, args));
	},

	// show the localized msg as confirm window
	confirmMsg : function(msg_id, args) {
		return confirm(manu.getMsg(msg_id, args));
	},

	// Wrappers around jquery.get
	// TODO: evaluate if the functionality can be moved to jquery ajax fns.

	getAction : function(action, params, callback) {
		var actionUrl = URL_PREFIX_AJAX + action;
		return this.get(actionUrl, params, callback);
	},

	get : function(url, params, callback) {
		return jQuery.get(url, params, function(data) {
			var ret = manu.handleAjaxError(data, url);
			if (!ret)
				return;
			if (callback)
				callback(data);
		});
	},

	// Wrappers around jquery.post
	postAction : function(action, params, callback) {
		var actionUrl = URL_PREFIX_AJAX + action;
		return this.post(actionUrl, params, callback);
	},

	post: function(url, params, callback) {
		return jQuery.post(url, params, function(data) {
			var ret = manu.handleAjaxError(data, url);
			if (!ret)
				return;
			if (callback)
				callback(data);
		});
	},

	// Wrappers around jquery.getJSON
	getJSONAction : function(action, params, callback) {
		var actionUrl = URL_PREFIX_AJAX + action;
		return jQuery.getJSON(actionUrl, params, function(data) {
			var error_flag = false;
			for ( var i in data['messages']) {
				if (data['messages'][i]['type'] == 'E') {
					error_flag = true;
				}
			}
			for ( var i in data['verrors']) {
				error_flag = true;
			}
			manu.validation.displayMessages(action, data['messages'], true);
			for ( var h in data['handlers']) {
				var alwaysExec = data['handlers'][h];
				manu.executeJsHandler(handler, alwaysExec);
			}
			if (callback && !error_flag) {
				callback(data);
			}
		});
	},

	// Wrappers around jquery.load
	load: function(target, url, params, callback) {
		return jQuery.get(url, params, function(data) {
			var ret = manu.handleAjaxError(data, url);
			if (!ret)
				return;
			$(target).html(data);
			if (callback) {
				callback(data);
			}
		});
	},

	loadAction : function(target, action, params, callback) {
		var actionUrl = URL_PREFIX_AJAX + action;
		return this.load(target, actionUrl, params, callback);
	},


	// Wrappers around jquery.ajaxSubmit (provided by jquery.form )
	ajaxSubmitAction : function(form_id, callback) {
		var form = document.getElementById(form_id);
		var action = manu.getFormAction(form);
		var ret = manu.form.validateForm(form);
		if (!ret)
			return;
		$(form).ajaxSubmit( {
			success : function(data) {
			var ret = manu.handleAjaxError(data, action);
			if (!ret)
				return;
			if (callback) {
				callback(data);
			}
		}
		});
	},

	ajaxSubmitJSON : function(form_id, callback, errorcallback) {
		var form = document.getElementById(form_id);
		var ret = manu.form.validateForm1(form);
		if (!ret) {
			return;
		}
		$(form).ajaxSubmit( {
			dataType : 'json',
			success : function(data) {
			var error_flag = false;
			for (i in data['messages']) {
				if (data['messages'][i]['type'] == 'E') {
					error_flag = true;
				}
			}

			for (i in data['verrors']) {
				error_flag = true;
			}

			var action = manu.getFormAction(form);
			manu.validation.displayMessages(action, data['messages'], true);

			for ( var h in data['handlers']) {
				var alwaysExec = data['handlers'][h];
				manu.executeJsHandler(h, alwaysExec);
			}

			if (errorcallback && error_flag) {
				errorcallback(data);
			}

			if (callback && !error_flag) {
				callback(data);
			}
		},

		error : function(data) {
			if (errorcallback) {
				errorcallback(data);
			}
		}
		});
	},

	handleAjaxError : function(data, url) {
		if (!data)
			return true;
		if (data.match(/FW_PHP_ERROR/)) {
			var error = data.replace(/<!--FW_PHP_ERROR-->/g, '');
			alert("Oops! Something went wrong. Please try again.");
			return false;
		} else if (data.match(/FW_PHP_EXCEPTION/)) {
			alert("Oops! Something went wrong. Please try again.");
			return false;
		} else if (data.match(/FW_AJAX_REDIRECT/)) {
			var redirect_url = data.replace(
					/.*<!--FW_AJAX_REDIRECT-->(.*?)<!--FW_AJAX_REDIRECT-->.*/m,
			"$1");
			window.location.href = redirect_url;
			return false;
		}
		return true;
	},

	clearActionMessages : function(action) {
		$(".alert, .alertbox").each(
				function() {
					if (!this.className
							.match("m_" + action.toLowerCase() + "-")) {
						return;
					}
					$(this).html("");
					$(this).hide();
					$(this).parents('form.normal').find('label').removeClass(
					'error_label');
				});
	},

	getFormAction : function(form) {
		var action = form.action;
		if (!action) {
			var path = location.pathname;
			action = path.replace(/^(\w+).*/, "$1");
		}
		action = action.toLowerCase();
		action = action.replace(/(\w+)\?/, "$1");
		action = action.replace(/^.*?(\w+)$/g, "$1");
		return action;
	},

	// should move to a plugin
	typeAhead : function($input, func, minChars, maxChars, delay) {
		var timeout = false;
		if ($.browser.mozilla)
			$input.keypress(processKey); // onkeypress repeats arrow keys in
		// Mozilla/Opera
		else
			$input.keydown(processKey); // onkeydown repeats arrow keys in
		// IE/Safari

		function processKey(e) {
			// printable chars
			if (($(this).val().length < minChars - 1)
					|| ($(this).val().length > maxChars - 1))
				return;
			if (e.which >= 32 && e.which < 127 || e.which == 8) {
				if (timeout)
					clearTimeout(timeout);
				timeout = setTimeout(func, delay);
			}
		}
	},

	// wrapper around jquery ui dialog
	dialog : function(jelem, params) {
		jelem.dialog(params).dialog('open');
		manu.dialogElement = jelem;
	},

	closeDialog : function() {
		if (manu.dialogElement != null) {
			manu.dialogElement.dialog('destroy');
			//manu.dialogElement.remove();
			manu.dialogElement = null;
		}
		return false;
	},

	// Obsolete. should use jquery ui dialog instead
	actionDialog : function(msg, callbacks, params) {
		$("#action_dialog").remove();
		var html = '<div id="action_dialog"><div id="action_dialog_msg">' + msg + '</div>';
		if (callbacks) {
			for ( var action in callbacks) {
				html += '<a id="action_dialog_' + action
				+ '" href="javascript:void(0);" class="btn">' + action
				+ '</a>';
			}
		}
		if (params == null) {
			params = {};
		}
		if (params.width == null)
			params.width = 300;
		manu.dialog($(html), params);
		if (callbacks) {
			for ( var action in callbacks) {
				var cb = callbacks[action];
				$("#action_dialog_" + action).click(cb);
			}
		}
	},

	// obsolete. should use jquery dialog
	modal : function(jelem, params) {
		if ($('#jqm_window').length == 0) {
			$("body")
			.append(
			'<div id="jqm_container" ><div id="jqm_window" class="jqmWindow"><a href="#" class="jqmClose"></a></div></div>');
		}
		$('#jqm_window').append(jelem.html());
		$('#jqm_window').jqm( {
			modal : true
		});
		$('#jqm_window').jqmShow();
	}


	};

	manu.validation = {

	displayMessages : function(action, messages, ajax) {
		var alert_flag = false;

		// Hide existing alert messages for an action
		for ( var msg_id1 in messages) {
			var msg_style = messages[msg_id1]['style'];
			if (msg_style == 'A') {
				alert_flag = true;
			}
		}
		if (alert_flag) {
			if ($("#alert_messages").length > 0) {
				$("#alert_messages").html("");
			} else {
				$("body").append('<div id="alert_messages"></div>');
			}
		}
		jQuery(".m_global").html("");
		jQuery(".m_global").hide("");

		if (ajax) {
			manu.clearActionMessages(action);
		}

		for ( var msg_id1 in messages) {

			var msg_str = messages[msg_id1]['msg'];
			var msg_type = messages[msg_id1]['type'];
			var msg_style = messages[msg_id1]['style'];
			var global_flag = messages[msg_id1]['global'];
			// for normal loading actions, do not show messages other than alert
			// and flash
			// those messages are shown by function.msg.php
			if (!ajax && !msg_style)
				continue;
			if (global_flag) {
				this.displayGlobalMessage(msg_str, msg_type);
			} else {
				if(action.match(/^f_/)) {
					//var form_id = action.replace(/^f_(.*)$/, "$1");
					manu.form.displayFormMessage(action, msg_id1, msg_str, msg_type,'');
				}
				else {
					this.displayActionMessage(action, msg_id1, msg_str, msg_type,
							msg_style);
				}
			}
		}
		if (alert_flag) {
			if (jQuery().dialog) {
				manu.dialog($("#alert_messages"), {
					buttons : {
					"Ok" : function() {
					manu.closeDialog();
				}
				},
				closeText : ''
				});
			} else {
				manu.modal($("#alert_messages"));
			}
		}
	},

	displayGlobalMessage : function(msg_str, msg_type) {
		var error_class = "";
		if (msg_type == 'S') {
			error_class = "success";
		} else if (msg_type == 'W') {
			error_class = "warning";
		} else if (msg_type == 'E') {
			error_class = "error";
		} else if (msg_type == 'I') {
			error_class = "info";
		}
		$(".m_global").append(
				"<div class='" + error_class + "'>" + msg_str + "</div>");
		$(".m_global").show();
	},

	displayActionMessage : function(action, msg_id, msg_str, msg_type,
			msg_style) {
		var elem_id = ".m_" + action.toLowerCase() + "-" + msg_id;
		var rest_id = ".m_" + action.toLowerCase() + "-REST";
		var all_id = ".m_" + action.toLowerCase() + "-ALL";

		var error_class = "";
		if (msg_type == 'S') {
			error_class = "success";
		} else if (msg_type == 'W') {
			error_class = "warning";
		} else if (msg_type == 'E') {
			error_class = "error";
		} else if (msg_type == 'I') {
			error_class = "info";
		}

		if (!msg_style)
			msg_style = "";

		if (msg_style == 'A') {
			$("#alert_messages").append(
					"<div class='" + error_class + "'>" + msg_str + "</div>");
		} else {
			if ($(elem_id).length > 0) {
				$(elem_id).html(msg_str);
				$(elem_id).height("");
				$(elem_id).addClass(error_class);
				$(elem_id).show();
				if (msg_style == "F") {
					$(elem_id).show("fast", function() {
						setTimeout('$("' + elem_id + '").hide()', 5000);
					});
				}
			} else if ($(rest_id).length > 0) {
				$(rest_id).height("");
				$(rest_id).append(
						"<div class='" + error_class + "' >" + msg_str
						+ "</div>");
				$(rest_id).show();
				if (msg_style == "F") {
					$(rest_id).show("fast", function() {
						setTimeout('$("' + rest_id + '").hide()', 5000);
					});
				}
			}
			if ($(all_id).length > 0) {
				$(all_id).height("");
				$(all_id).append(
						"<div class='" + error_class + "' >" + msg_str
						+ "</div>");
				$(all_id).show();
				if (msg_style == "F") {
					$(all_id).show("fast", function() {
						setTimeout('$("' + all_id + '").hide()', 5000);
					});
				}
			}
			if (msg_id.match('-e-')) {
				var elem = msg_id.replace('-e-', '');
				$("form").find("label[for='" + elem + "']").addClass(
				"error_label");
			}
		}
	}
	};

	manu.utils = {
			is_array : function(mixed_var) {
		return (mixed_var instanceof Array);
	},
	is_object : function(mixed_var) {
		if (mixed_var instanceof Array) {
			return false;
		} else {
			return (mixed_var !== null) && (typeof (mixed_var) == 'object');
		}
	},

	stripslashes : function(elem) {
		return elem.replace(/^\/+|\/+$/g, "");
	},


	// Encoding HTML special characters(<, >, &, ', ") present in the string
	htmlSpecialCharsEncode : function(string) {
		string = string.replace(/\&/g, "&amp;");
		string = string.replace(/>/g, "&gt;");
		string = string.replace(/</g, "&lt;");
		string = string.replace(/\"/g, "&quot;");
		string = string.replace(/\'/g, "&#39;");

		return string;
	},

	// Decoding HTML special characters(<, >, &, ', ") present in the string
	htmlSpecialCharsDecode : function(string) {
		string = string.replace(/\&gt;/g, ">");
		string = string.replace(/\&lt;/g, "<");
		string = string.replace(/\&quot;/g, "\"");
		string = string.replace(/\&#039;/g, "'");
		string = string.replace(/\&#39;/g, "'");
		string = string.replace(/\&apos;/g, "'");
		string = string.replace(/\&amp;/g, "&");

		return string;
	},

	alertObj : function(obj) {
		var output = "";
		for ( var i in obj) {
			output += i + "=" + obj[i];
		}
	}
	};

	window.manu = manu;
	window.Global = manu;
	window.Utils = manu.utils;

})(window);
