// Core Models Direct Class
// Details with infrastructural stuff like: logging, messaging and core template functions
var MD = function () {
	var debug = false;
	var messageData = {
		error: {
			title: 'The following error(s) occured',
			messages: [],
			help: []
		},
		warning: {
			title: 'The following warning(s) occured',
			messages: [],
			help: []
		},
		confirmation: {
			title: '',
			messages: [],
			help: []
		},
		information: {
			title: '',
			messages: [],
			help: []
		}
	};

	return {
		MESSAGE_TYPE_ERROR: 'error',
		MESSAGE_TYPE_WARNING: 'warning',
		MESSAGE_TYPE_CONFIRMATION: 'confirmation',
		MESSAGE_TYPE_INFORMATION: 'information',

		TEMPLATE_USER_LOGIN_DEFAULT_USERNAME: 'Username',
		TEMPLATE_USER_LOGIN_DEFAULT_PASSWORD: 'password',

		confirmAction: function(message, url) {
			if (confirm(message)) {
				document.location.href = url;
			}
		},

		// DEBUGGING INFRASTRUCTURE ********************************
		// enable debugging
		enableDebugging: function() {
			debug = true;
		},
		// disable debugging
		disableDebugging: function() {
			debug = false;
		},
		// is in debug mode
		isDebug: function() {
			return debug;
		},

		// CONSOLE LOGGING *****************************************
		// log debug message
		// NOTE: for more complex console logging (formatted, multi-argument logging then use console.(debug|info|warn|error directly): http://getfirebug.com/logging.html
		logDebug: function(message) {
			(MD.isDebug() && window.console && console.debug)? console.debug(message) : false;
		},
		// log information debug message
		logInformation: function(message) {
			(MD.isDebug() && window.console && console.info)? console.info(message) : false;
		},
		// log warning debug message
		logWarning: function(message) {
			(MD.isDebug() && window.console && console.warn)? console.warn(message) : false;
		},
		// log error debug message
		logError: function(message) {
			(MD.isDebug() && window.console && console.error)? console.error(message) : false;
		},
		logTimeStart: function(message) {
			(MD.isDebug() && window.console && console.time)? console.time(message) : false;
		},
		logTimeEnd: function(message) {
			(MD.isDebug() && window.console && console.timeEnd)? console.timeEnd(message) : false;
		},
		logProfileStart: function() {
			(MD.isDebug() && window.console && console.profile)? console.profile() : false;
		},
		logProfileEnd: function() {
			(MD.isDebug() && window.console && console.profileEnd)? console.profileEnd() : false;
		},
		logGroupStart: function(message) {
			(MD.isDebug() && window.console && console.group)? console.group(message) : false;
		},
		logGroupEnd: function() {
			(MD.isDebug() && window.console && console.groupEnd)? console.groupEnd() : false;
		},
		logTrace: function() {
			(MD.isDebug() && window.console && console.trace)? console.trace() : false;
		},
		logDumpObject: function(object) {
			(MD.isDebug() && window.console && console.dir)? console.dir(object) : false;
		},
		logDumpXml: function(Xml) {
			(MD.isDebug() && window.console && console.dirxml)? console.dirxml(Xml) : false;
		},
		logAssert: function(condition) {
			(MD.isDebug() && window.console && console.assert)? console.assert(condition) : false;
		},

		// MESSAGE MANAGEMENT **************************************
		isValidMessageType: function(type) {
			MD.logAssert(type == MD.MESSAGE_TYPE_ERROR || type == MD.MESSAGE_TYPE_WARNING || type == MD.MESSAGE_TYPE_CONFIRMATION || type == MD.MESSAGE_TYPE_INFORMATION);
		},
		// set main title of the error bar
		setMessageTitle: function (type, title) {
			MD.isValidMessageType(type);
			messageData[type]['title'] = title;
		},
		// add error 
		addMessage: function (type, message) {
			MD.isValidMessageType(type);
			messageData[type]['messages'].push(message);
		},
		// has any current errors in the list
		hasMessages: function (type) {
			MD.isValidMessageType(type);
			return (messageData[type]['messages'].length > 0)? true : false; 
		},
		// returns the number of errors in the list
		countMessages: function (type) {
			MD.isValidMessageType(type);
			return parseInt(messageData[type]['messages'].length);
		},
		// clears the error list
		clearMessages: function (type) {
			MD.isValidMessageType(type);
			messageData[type]['messages'] = [];
		},
		// adds a error help message
		addMessageHelp: function (type, help) {
			MD.isValidMessageType(type);
			messageData[type]['help'].push(help);
		},
		// has any current error help messages in the list
		hasMessageHelp: function (type) {
			MD.isValidMessageType(type);
			return (messageData[type]['help'].length > 0)? true : false; 
		},
		// returns the number of error help messages in the list
		countMessageHelp: function (type) {
			MD.isValidMessageType(type);
			return parseInt(messageData[type]['help'].length);
		},
		// clears the help list
		clearMessageHelp: function (type) {
			MD.isValidMessageType(type);
			messageData[type]['help'] = [];
		},
		// displays the current errors/error help messages in the list (and clears them after displaying)
		displayMessages: function (type) {
			MD.isValidMessageType(type);

			if (MD.hasMessages(type) || MD.hasMessageHelp(type)) {
				var titleHtml = '<h3>'+messageData[type]['title']+':</h3>';

				var contentHtml = '';
				if (MD.hasMessages(type)) {
					contentHtml += '<ul>';
					$.each(messageData[type]['messages'], function(index, value){
						contentHtml += '<li>'+value+'</li>';
					});
					contentHtml += '</ul>';
				}

				var helpHtml = '';
				$.each(messageData[type]['help'], function(index, value){
					helpHtml += '<p>'+value+'</p>';
				});

				$('#template-bar-'+type).html(titleHtml+contentHtml+helpHtml);
				$('#template-bar-'+type).slideDown('slow');

				MD.clearMessages(type);
				MD.clearMessageHelp(type);

				return true;
			}

			return false;
		},
		// error wrapper functions for message functions above
		setErrorTitle: function (title) {
			return MD.setMessageTitle(MD.MESSAGE_TYPE_ERROR, title);
		},
		addError: function (message) {
			return MD.addMessage(MD.MESSAGE_TYPE_ERROR, message);
		},
		hasErrors: function () {
			return MD.hasMessages(MD.MESSAGE_TYPE_ERROR);
		},
		countErrors: function () {
			return MD.countMessages(MD.MESSAGE_TYPE_ERROR);
		},
		clearErrors: function () {
			return MD.clearMessages(MD.MESSAGE_TYPE_ERROR);
		},
		addErrorHelp: function (help) {
			return MD.addMessageHelp(MD.MESSAGE_TYPE_ERROR, help);
		},
		hasErrorHelp: function () {
			return MD.hasMessageHelp(MD.MESSAGE_TYPE_ERROR);
		},
		countErrorHelp: function () {
			return MD.countMessageHelp(MD.MESSAGE_TYPE_ERROR);
		},
		clearErrorHelp: function () {
			return MD.clearMessageHelp(MD.MESSAGE_TYPE_ERROR);
		},
		displayErrors: function () {
			return MD.displayMessages(MD.MESSAGE_TYPE_ERROR);
		},
		// warning wrapper functions for message functions above
		setWarningTitle: function (title) {
			return MD.setMessageTitle(MD.MESSAGE_TYPE_WARNING, title);
		},
		addWarning: function (message) {
			return MD.addMessage(MD.MESSAGE_TYPE_WARNING, message);
		},
		hasWarnings: function () {
			return MD.hasMessages(MD.MESSAGE_TYPE_WARNING);
		},
		countWarnings: function () {
			return MD.countMessages(MD.MESSAGE_TYPE_WARNING);
		},
		clearWarnings: function () {
			return MD.clearMessages(MD.MESSAGE_TYPE_WARNING);
		},
		addWarningHelp: function (help) {
			return MD.addMessageHelp(MD.MESSAGE_TYPE_WARNING, help);
		},
		hasWarningHelp: function () {
			return MD.hasMessageHelp(MD.MESSAGE_TYPE_WARNING);
		},
		countWarningHelp: function () {
			return MD.countMessageHelp(MD.MESSAGE_TYPE_WARNING);
		},
		clearWarningHelp: function () {
			return MD.clearMessageHelp(MD.MESSAGE_TYPE_WARNING);
		},
		displayWarnings: function () {
			return MD.displayMessages(MD.MESSAGE_TYPE_WARNING);
		},
		// confirmation wrapper functions for message functions above
		setConfirmationTitle: function (title) {
			return MD.setMessageTitle(MD.MESSAGE_TYPE_CONFIRMATION, title);
		},
		addConfirmation: function (message) {
			return MD.addMessage(MD.MESSAGE_TYPE_CONFIRMATION, message);
		},
		hasConfirmation: function () {
			return MD.hasMessages(MD.MESSAGE_TYPE_CONFIRMATION);
		},
		countConfirmation: function () {
			return MD.countMessages(MD.MESSAGE_TYPE_CONFIRMATION);
		},
		clearConfirmation: function () {
			return MD.clearMessages(MD.MESSAGE_TYPE_CONFIRMATION);
		},
		addConfirmationHelp: function (help) {
			return MD.addMessageHelp(MD.MESSAGE_TYPE_CONFIRMATION, help);
		},
		hasConfirmationHelp: function () {
			return MD.hasMessageHelp(MD.MESSAGE_TYPE_CONFIRMATION);
		},
		countConfirmationHelp: function () {
			return MD.countMessageHelp(MD.MESSAGE_TYPE_CONFIRMATION);
		},
		clearConfirmationHelp: function () {
			return MD.clearMessageHelp(MD.MESSAGE_TYPE_CONFIRMATION);
		},
		displayConfirmation: function () {
			return MD.displayMessages(MD.MESSAGE_TYPE_CONFIRMATION);
		},
		// information wrapper functions for message functions above
		setInformationTitle: function (title) {
			return MD.setMessageTitle(MD.MESSAGE_TYPE_INFORMATION, title);
		},
		addInformation: function (message) {
			return MD.addMessage(MD.MESSAGE_TYPE_INFORMATION, message);
		},
		hasInformation: function () {
			return MD.hasMessages(MD.MESSAGE_TYPE_INFORMATION);
		},
		countInformation: function () {
			return MD.countMessages(MD.MESSAGE_TYPE_INFORMATION);
		},
		clearInformation: function () {
			return MD.clearMessages(MD.MESSAGE_TYPE_INFORMATION);
		},
		addInformationHelp: function (help) {
			return MD.addMessageHelp(MD.MESSAGE_TYPE_INFORMATION, help);
		},
		hasInformationHelp: function () {
			return MD.hasMessageHelp(MD.MESSAGE_TYPE_INFORMATION);
		},
		countInformationHelp: function () {
			return MD.countMessageHelp(MD.MESSAGE_TYPE_INFORMATION);
		},
		clearInformationHelp: function () {
			return MD.clearMessageHelp(MD.MESSAGE_TYPE_INFORMATION);
		},
		displayInformation: function () {
			return MD.displayMessages(MD.MESSAGE_TYPE_INFORMATION);
		},
		// display all pending messages/help for all types
		displayAll: function () {
			MD.displayMessages(MD.MESSAGE_TYPE_ERROR);
			MD.displayMessages(MD.MESSAGE_TYPE_WARNING);
			MD.displayMessages(MD.MESSAGE_TYPE_CONFIRMATION);
			MD.displayMessages(MD.MESSAGE_TYPE_INFORMATION);
		},

		_: function() {}
	};
}();
