<!--//
String.prototype.ucFirst = function () {
   return this.substr(0,1).toUpperCase() + this.substr(1,this.length);
}

/***
 * A simple message object
 */
function Msg(params) {
	var id;
	var text;
	var level;
	var field;
	var icon;
	var panel;
	var highlight;
	var highlightClass;

	// if we have no field
	if (!params.id) {
		throw new Error("An id is required for the message", "An id is required for the message");
	}

	// set defaults
	this.id				= params.id;										// the id for this message
	this.field 			= params.field || params.id							// the field name (defaults to the id)
	this.title 			= params.title || (params.id).ucFirst();			// the title (defaults to the id ucfirst'd)
	this.text 			= params.text  || '';								// the text for the message
	this.level 			= params.level || 'ERROR';							// the level of message (defaults to ERROR)
	this.icon 			= params.icon || true;								// do we show an icon if required (defaults to true)
	this.panel			= params.panel || true;								// do we add the message onto the panel (defaults to true)
	this.highlight 		= params.highlight || false;						// do we add field highlighting (defaults to false)
	this.highlightClass = params.highlightClass || 'highlightField';		// the class used for highlight (defaults to highlightField)

	// util method
	this.toString 		= function() {
		return this.id + ':' + this.title + ':' + this.text + ':' + this.level + ':' + this.field + ':' + this.icon + ':' + this.hightlight;
	}
}


/**
 * Javascript class to manage status messages [client side | server side and session based ]
 * Places messages into divs based on their level
 * The divs are placed into either <div id="MsgPanels"> if defined, or falls back to <div id="MsgPanelsPlaceHolder">
 * 
 * The css required is
 *  - #MsgPanel$Level where $level is on of Ok,Info,Warn,Error,Debug
 *	- highlightField (if field hightlights are to be used)
 *
 * @TODO 
 *	- we will want to remove the icons and just use CSS i suspect
 *  - 
 */
function MsgMgr() {

	var icon_path			= 'images/icons/';		// path to icons
	var highlightClass 		= 'highlightField';		// this should actually be built into an array of all highlightClasses used
	
	var msgs				= new Array();
	
	// Create unique array to hold each type of message
	var msgLevels = new Array('OK', 'INFO', 'WARN', 'ERROR', 'DEBUG');
	
	for (var i=0; i < msgLevels.length; i++) {
		msgs[msgLevels[i]] = new Array();
	}

	// public methods
	this.add			 		= add;
	this.hasMsgs				= hasMsgs;

	// msg array management
	this.clearMsgById			= clearMsgById;
	this.clearAll				= clearAll;
	
	// msg text
	this.removeMsgById			= removeMsgById;
	this.removeAllMsgText		= removeAllMsgText;
	this.removeMsgTextById		= removeMsgTextById;

	// field icons
	this.addFieldIcon			= addFieldIcon;
	this.removeFieldIconById	= removeFieldIconById;
	this.removeAllFieldIcons	= removeAllFieldIcons;

	// highlighting
	this.highlightField			= highlightField;
	this.removeHightlight		= removeHighlight;
	
	// 
	this.showConfirm			= showConfirm;
	this.showAlert				= showAlert;
	this.getText				= getText;
	

	/**
	 * @param field
	 * @param key
	 * @param msg
	 * @param level
	 * @param field
	 * @param highlight_field
	 */
	function add(msg) {

		// remove any existing messages/icons/etc with this id
		clearMsgById(msg.id);

        // add the message onto the stack
        msgs[msg.level].push(msg);

		// add or update the text if we need to? 
		if (msg.panel) {
		
			// we need to put the text in to place
			if (!$('MsgPanels')) {
				if (!$('MsgPanelsPlaceHolder')) {
					throw new Error("MsgPanelsPlaceHolder is not defined", "MsgPanelsPlaceHolder is not defined");
				} else {
					$('MsgPanelsPlaceHolder').replace('<div id="MsgPanels"></div>');
				}
			}

			// define the panel name
			var panel		= 'MsgPanel' + msg.level.toLowerCase().ucFirst();
		
			// define the ul id
			var ul_id	= msg.level + '_panel_ul';
			
			// if the panel for this level does not already exist
			if (!$(panel)) {
			
				// create the panel div
				var e_panel 	= new Element('div', {'id': panel});
				
				// create a list container
				var e_ul		= new Element('ul', {'id': ul_id});

				// set the li id
				var li_id	= msg.level + '_panel_li_' + msg.id;
				var e_li 	= new Element('li', {'id': li_id}).update('<strong>' + msg.title + '</strong>&nbsp;-&nbsp;' + msg.text);

				// see does this work
				e_ul.appendChild(e_li);
				
				// add the list onto the panel
				e_panel.appendChild(e_ul);

				// add the panel onto the list of panels
				$('MsgPanels').appendChild(e_panel);
				
			// otherwise if the panel already exists
			} else {

				// if the ul does not exist
				if (!$(ul_id)) {
					
					// create a list container
					var e_ul		= new Element('ul', {'id': ul_id});
					
					// add the list onto the panel
					$(panel).appendChild(e_ul);
				}
			
				// set the li id
				var li_id	= 'panel_li_' + msg.id;
				var e_li 	= new Element('li', {'id': li_id}).update('<strong>' + msg.title + '</strong>&nbsp;-&nbsp;' + msg.text);

				// see does this work
				$(ul_id).appendChild(e_li);
			}
		}
		
				
		// if we have the field
		if (msg.field != '') {

			// do we want to have the icon
			if (msg.icon) {
				addFieldIcon(msg.id, msg.field, msg.text, msg.level);
			}

			// do we want to highlight
			if (msg.highlight) {
				highlightField(msg.field, msg.highlightClass);
			}
		}

		// alert($('MsgPanels').innerHTML);
	}


	/**
	 * Sets a message on a field
	 * @param id
	 * @param field
	 * @param message
	 * @param level
	 */
	function addFieldIcon(id, field, msg, level) {

		// check the field exists
		if (!$(field)) {
			return false;
		}
		
		// if we have no message then skip that
		if (!msg || msg == '') {
			return removeFieldIconById(id);
		}
	
		// define the id
		var icon_id 	= "field_icon_" + id;

		// we might want to add a popup div layer onto this and then remove the title from the icon
		var icon_html = '<span id="' + icon_id + '" class="msgMgrIcon' + level + '" title="' + msg + '"></span>';

		// check is the next element <span class="required"></span>
		if ($(field).next('span.required')) {
			new Insertion.After(($(field).next('span.required')), icon_html);
		} else {
			new Insertion.After(field, icon_html);
		}
	}


	/**
	 * Removes an icon by its id
	 * @param msg id
	 */
	function removeFieldIconById(id) {

		// define the element id
		var icon_id = "field_icon_" + id;

		// if it exists (and it might not) - remove it
		if ($(icon_id)) {
			return $(icon_id).remove();
		}
	}


	/**
	 * Removed all the icons
	 */
	function removeAllFieldIcons() {
		$$('span[id^=field_icon_]').each(function(e) {e.remove();});
	}


	/**
	 * Remove message text
	 * @param msg id
	 */
	function removeMsgTextById(id) {
	
		var li_id = "panel_li_" + id;

		if ($(li_id)) {
			return $(li_id).remove();
		}
	}

	/**
	 * Removes all content in the msg panels
	 */
	function removeAllMsgText() {
	
		if ($('MsgPanels')) {
			$('MsgPanels').update('');
		}
	}
	

	/**
 	 * Clears the page messages
	 */
	function clearAll(level) {

		// empty the messages
		removeAllMsgText();

		// remove all the field icons
		removeAllFieldIcons();

		// clear any field highlighting
		$$('.' + highlightClass).each(function (element) {
			removeHighlight(element)
		});

		// wipe the array
		msgs = null;
		msgs = Array();

		// populate the placeholders
		for (var i=0; i < msgLevels.length; i++) {
			msgs[msgLevels[i]] = new Array();
		}
	}


	/**
	 * Clear the error value
	 * @param id
	 */
	function clearMsgById(id) {
	
		// removes a message by its id
		removeMsgTextById(id);

		// remove the icon
		removeFieldIconById(id);

		// remove the message from the array
		removeMsgById(id);

		return true;
	}

	
	/**
	 * @param id
	 */
	function removeMsgById(id) {

		// remove from the array
		msgLevels.each(function (level) {
		
			// for each of the messages
			for (var i=0; i < msgs[level].length; i++) {

				// 
				if (msgs[level][i]['id'] == id) {

					// set the matching value to null
					msgs[level][i] = null;
	
					// remove the null 
					msgs[level] = msgs[level].compact();
					
					// 
					return true;
				}
			}
		});
	}


	/**
	 * Add highlighting to a field
	 */
	function highlightField(field, highlightClass) {
		if ($(field)) {
			$(field).addClassName(highlightClass);
		}
	}


	/**
	 * Remove highlighting from a field
	 */
	function removeHighlight(field) {
		if ($(field)) {
			$(field).removeClassName(highlightClass);
		}
	}
	
	
	/**
	 * Returns true if messages exist
	 */
	function hasMsgs(level) {

		// if we page a level in
		if (level) {
			// return true or false if we have message
			return (msgs[level].length > 0) ? true : false;

		// otherwise
		} else {

			msgLevels.each(function (level) {
				if (msgs[level].length > 0) {
					return true;
				}
			});

		}
		return false;
	}
	
	
	/**
	 * Wrapper to standard js alert message
	 */
	function showAlert(msg) {
		return alert(getText(msg));
	}
	
	
	/**
	 * Wrapper to standard js alert message
	 */
	function showConfirm(msg) {
		return confirm(getText(msg));
	}
	
	
	/**
	 * Get text wrapper
	 */
	function getText(msg) {
		try {
			// check in the gettext
			if (l != null && l[msg] != null) {
				return l[msg];
			} else {
				return msg;
			}
		} catch (error) {
			return msg;
		}
	}
}

// on load - if we do not have a MsgPanels defined - replace with the placeholder
Event.observe(window, 'load', function() {
	if (!$('MsgPanels')) {
		if (!$('MsgPanelsPlaceHolder')) {
			throw new Error("MsgPanelsPlaceHolder is not defined", "MsgPanelsPlaceHolder is not defined");
		} else {
			$('MsgPanelsPlaceHolder').replace('<div id="MsgPanels"></div>');
		}
	}
});

// create the MsgMgr
msgMgr = new MsgMgr();
//--> 
