/*global $, INCLUDE_ROOT, SITE_ROOT, console, document, escape, isArray, jQuery, unescape, ucwords, urldecode, window */

if(typeof(SITE_ROOT) === 'undefined'){
	window.SITE_ROOT = '/';
}
if(typeof(INCLUDE_ROOT) === 'undefined'){
	window.INCLUDE_ROOT = SITE_ROOT+'include/';
}

// DYNAMIC RESOURCE LOADING
var cmsLoaded = [];
var cmsLoadQueue = 0;
var cmsLoadComplete = 0;
function cmsLoadDone(event){
	cmsLoadComplete++;
}
function cmsLoad(files, method, path){
	var head, elem, tag;
	if(typeof(path) === 'undefined'){
		path = INCLUDE_ROOT;
	}
	if(typeof(method) === 'string'){
		method = method.toLowerCase();
	}
	for(var i=0;i<files.length; i++){
		cmsLoadQueue++;
		var file = path + files[i];
		var found = false;
		
		// CHECK ALREADY LOADED
		if(file.match("js$") == 'js'){
			if($('script[src$="'+files[i]+'"]').length > 0){
				found = true;
			}
		}else if(file.match("css$") == 'css'){
			if($('style[href$="'+files[i]+'"]').length > 0){
				found = true;
			}
		}
		
		if(found === false){
			for(var j=0; j<cmsLoaded.length; j++){
				if(cmsLoaded[j] === file){
					found = true;
					break;
				}
			}
		}
		
		if(found === false){
			if(file.match("js$") == 'js'){
				tag = ["<script type=\'text\/javascript\' src=\'", file,"?gzip=1\'><\/script>"].join('');
				if(method &&
						method === 'async' &&
						document.createElement &&
						document.getElementsByTagName &&
						(head = document.getElementsByTagName('head')[0]) &&
						head.appendChild &&
						(elem = document.createElement('script'))){
					elem.onload = cmsLoadDone;
					elem.setAttribute('type', 'text/javascript');
					elem.setAttribute('src', file);
					head.appendChild(elem);
				}else if(method && method === 'jquery'){
					$('head:first').append(tag);
					cmsLoadDone();
				}else{
					document.write(tag);
					cmsLoadDone();
				}
				cmsLoaded[cmsLoaded.length] = file;
			}else if(file.match("css$") == 'css'){
				tag = ["<link type=\'text\/css\' rel=\'stylesheet\' href=\'", file,"?gzip=1\' \/>"].join('');
				if(method &&
						method === 'async' &&
						document.createElement &&
						document.getElementsByTagName &&
						(head = document.getElementsByTagName('head')[0]) &&
						head.appendChild &&
						(elem = document.createElement('link'))){
					elem.onload = cmsLoadDone; // !!!! DOESN'T WORK IN FIREFOX
					elem.setAttribute('type', 'text/css');
					elem.setAttribute('rel', 'stylesheet');
					elem.setAttribute('href', file);
					head.appendChild(elem);
				}else if(method && method === 'jquery'){
					$('head:first').append(tag);
					cmsLoadDone();
				}else{
					document.write(tag);
					cmsLoadDone();
				}
				cmsLoaded[cmsLoaded.length] = file;
			}
		}else{
			cmsLoadDone();
		}
	}
	head = null;
	elem = null;
	tag = null;
	return true;
}  
var cmsFiles = ['js/common.js',
				'js/jquery/form/2.36/jquery.form.js',
				'js/jquery/timers/1.1.2/jquery.timers.js',
				'js/jquery/cookie/jquery.cookie.js',
				'js/jquery/base64/jquery.base64.js',
				'js/jquery/simplemodal/1.2.3/jquery.simplemodal.min.js',
				'cms/css/common.css',
				'cms/css/interface.css'];
if(typeof(cmsLoad) === 'function'){
    cmsLoad(cmsFiles);
}

$(function(){
	$.cms.setup();
});

/**
 * CMS Core Module
 * A jQuery object that contains various core properties and functions for the
 * overall CMS javascript framework.
 * 
 * @version 1.0
 * @requires
 * 		jquery.js
 * 		jquery.cookie.js - storing cms component configs
 * 		jquery.base64.js - cookie encryption
 * @author Ed Rodriguez Ed.Rodriguez@watermatters.org
 */
(function($){
	$.cms = {
		valid: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-. ',
		scripts: [],
		snippets: [],
		simpleLoad: '<div align="left">Loading...</div>',
		snippetLoad: SITE_ROOT+'snippet/cms/ui/loading.snip',
		snippetUpload: SITE_ROOT+'snippet/cms/dialogs/file-upload.snip',
		htmlLoadBar: '<div class="loading"><img src="'+SITE_ROOT+'images/loading_bar.gif" align="right" alt="" border="0" style="margin:2px 0px 0px 3px;" />Loading:</div>',
		htmlLoad: '',
		modal: null,
		debug: false,
		cookie: 'cmsConfig', // cookie name
		path: '/', // cookie path
		expires: 365,
		
		/*------------------
			CMS CORE FUNCTIONS
		------------------*/
		
		// CMS SETUP
		setup: function(){
			// EMAIL REPLACE (spam bot prevention)
			$('span[data-to]').each(function(){
				var email = $.base64Decode($(this).attr('data-to'));
				$(this)
				  .after('<a href="mailto:'+email+'" />').next()
				  .html($(this).text().replace(/@/,'<wbr />@'))
				  .prev().remove();
			});
			
			// DATE PICKER
			if($.fn.datepicker){
				$('input.cms-date').datepicker();
			}
			$('img.cms-date-icon').bind('click',{},function(){
				$(this).prev().focus();	
			});
            
			if(this.debug){
				$.cms.log(cmsLoaded.join("\n"));
			}
			$.ajax({
				url: this.snippetLoad,
				type: 'POST',
				data: {
					whitespace: 0
				},
				success: function(response){
					$.cms.setHtml('Load',response);
				}
			});
			
			// HIDDEN IFRAME
			var elem;
			if(window.ActiveXObject){
				elem = document.createElement('<iframe id="cms-frame" name="cms-frame" />');
				elem.src = INCLUDE_ROOT+'cms/blank.htm';
			}else{
				elem = document.createElement('iframe');
				elem.id = 'cms-frame';
				elem.name = 'cms-frame';
				elem.src = INCLUDE_ROOT+'cms/blank.htm';
			}
			elem.style.position = 'absolute';
			if($.cms.debug){
				elem.style.top = '0px';
				elem.style.left = '0px';
				elem.style.backgroundColor = '#FFF';
				elem.style.width = '500px';
				elem.style.height = '300px';
			}else{
				elem.style.top = '-1000px';
				elem.style.left = '-1000px';
				elem.style.backgroundColor = '#FFF';
				elem.style.width = '10px';
				elem.style.height = '10px';
			}
			document.body.appendChild(elem);
			
			// HIDDEN FORM
			elem = document.createElement('form');
			elem.id = 'cms-hidden-form';
			elem.name = 'cms-hidden-form';
			elem.method = 'post';
			elem.action = '';
			document.body.appendChild(elem);
			
			this.setupPage();
		},
		
		setupPage: function(){
			$('[editor="jeditable-markitup"] a').bind('click',{},function(event){
				stopEvent(event);
			});
			$('img[align="left"]').addClass('img-left');
			$('img[align="right"]').addClass('img-right');
		},
		
		// ADD DIALOGS
		addDialog: function(module, name){
			if(name){
				if($('#cms'+module+name+'Dialog').length > 0){
					return(true);
				}else{
					var html = "<div id='cms"+module+name+"Dialog' class='hidden' title='"+name+"'></div>";
					$('body').prepend(html);
				}
				return(true);
			}
			return(false);
		},		
		
		addDialogLoad: function(module, name){
			$("#cmsFiles"+name+"Dialog").parent().find('.ui-dialog-buttonpane').prepend(this.htmlLoadBar);
		},
		
		// SAVES SETTINGS (cookie)
		saveSettings: function(module, opts, settings){
			var i;
			var value = '';
			var delimiter = '';
			var options = {path: this.path, expires: this.expires};
			for(var key in opts){
				if(typeof(opts[key]) === 'string' || typeof(opts[key]) === 'number'){
					var val = opts[key];
					if(settings.inArray(key)){
						value += delimiter+key+'='+val;
						if(delimiter === ''){
							delimiter = '&';
						}
					}
				}
			}
			if(value !== ''){
				var found = false;
				var configs = this.getSettings();
				if(configs !== ''){
					configs = configs.split(';');
					// FIND MODULE CONFIG
					for(i=0; i<configs.length; i++){
						if(configs[i].indexOf(module+':') === 0){
							// UPDATE MODULE CONFIG
							found = true;
							configs[i] = module+':'+value;
							break;
						}
					}
				}else{
					configs = [];
				}
				// CREATE MODULE CONFIG
				if(!found){
					configs[configs.length] = module+':'+value;
				}
				// PREPARE & SAVE CONFIG
				value = '';
				for(i=0; i<configs.length; i++){
					if(i === (configs.length - 1)){
						delimiter = '';
					}else{
						delimiter = ';';
					}
					value += configs[i]+delimiter;
				}
				$.cms.log('Saving Cookie: '+value);			
				value = escape(value);
				if(value !== null){
					value = $.base64Encode(value);
				}
				$.cookie(this.cookie, value, options);
			}
		},
		
		// GET SETTINGS (cookie)
		getSettings: function(module){
			var value = $.cookie(this.cookie);
			if(value === null){
				value = '';
			}
			value = $.base64Decode(value);
			value = unescape(value);
			if(typeof(module) === 'undefined'){
				return(value);
			}
			var configs = value.split(';');
			var array;
			for(var i=0; i<configs.length; i++){
				if(configs[i].indexOf(module) === 0){
					array = configs[i].split(':');
					break;
				}
			}
			if(typeof(array) !== 'undefined'){
				value = array[array.length-1];
				$.cms.log('Getting Cookie: '+value);
				value = $.query(value);
			}
			return(value);
		},
		
		// DEBUGGER TOOL
		showDebug: function(options){
			var selector = '#cms-frame';
			var top = 0;
			var left = 0;
			var width = 500;
			var height = 300;
			var mode = 'toggle';
			if(typeof(options) === 'object'){
				if(typeof(options.selector) !== 'undefined'){
					selector = options.selector;
				}
				if(typeof(options.top) !== 'undefined'){
					top = options.top;
				}
				if(typeof(options.left) !== 'undefined'){
					left = options.left;
				}
				if(typeof(options.width) !== 'undefined'){
					width = options.width;
				}
				if(typeof(options.height) !== 'undefined'){
					height = options.height;
				}
				if(typeof(options.mode) !== 'undefined'){
					mode = options.mode;
				}
			}
			var debug = $(selector);
			if(debug.length === 1){
				if($(selector).css('left') === left+'px' && mode !== 'show'){
					this.debug = false;
					$(selector).css({top:-1000,left:-1000,width:10,height:10});
				}else{
					this.debug = true;
					$(selector).css({top:top,left:left,width:width,height:height});
				}
			}
		},
		
		// DEBUGGING OBJECTS
		show: function(obj){
			var i = 0;
			var output = '--------------------------------------------------------';
			output += '\nType: '+typeof(obj);
			var strings = [];
			var numbers = [];
			var booleans = [];
			var objects = [];
			var functions = [];
			var errors = [];
			var misc = [];
			for(var item in obj){
				if(typeof(obj[item]) === 'function'){
					functions[functions.length] = item;
				}else if(typeof(obj[item]) === 'string'){
					strings[strings.length] = item;
				}else if(typeof(obj[item]) === 'number'){
					numbers[numbers.length] = item;
				}else if(typeof(obj[item]) === 'object'){
					objects[objects.length] = item;
				}else if(typeof(obj[item]) === 'boolean'){
					booleans[booleans.length] = item;
				}else{
					misc[misc.length] = item;
				}
			}
			if(strings.length > 0){
				output += '\nStrings: '+strings.length;
				strings.sort();
				for(i=0; i<strings.length; i++){
					output += '\n\t\t'+(i+1)+'.) string: '+strings[i]+' = '+obj[strings[i]];
				}
			}
			if(numbers.length > 0){
				output += '\nNumbers: '+numbers.length;
				numbers.sort();
				for(i=0; i<numbers.length; i++){
					output += '\n\t\t'+(i+1)+'.) number: '+numbers[i]+' = '+obj[numbers[i]];
				}
			}
			if(booleans.length > 0){
				output += '\nBooleans: '+booleans.length;
				booleans.sort();
				for(i=0; i<booleans.length; i++){
					output += '\n\t\t'+(i+1)+'.) boolean: '+booleans[i]+' = '+obj[booleans[i]];
				}
			}
			if(objects.length > 0){
				output += '\nObjects: '+objects.length;
				objects.sort();
				for(i=0; i<objects.length; i++){
					output += '\n\t\t'+(i+1)+'.) objects: '+objects[i];
				}
			}
			if(functions.length > 0){
				output += '\nFunctions: '+functions.length;
				functions.sort();
				for(i=0; i<functions.length; i++){
					output += '\n\t\t'+(i+1)+'.) function: '+functions[i]+'()';
				}
			}
			if(misc.length > 0){
				output += '\nMisc: '+misc.length;
				misc.sort();
				for(i=0; i<misc.length; i++){
					output += '\n\t\t'+(i+1)+'.) misc: '+misc[i];
				}
			}
			if(errors.length > 0){
				output += '\nErrors: '+errors.length;
				errors.sort();
				for(i=0; i<errors.length; i++){
					output += '\n\t\t'+(i+1)+'.) error: '+errors[i];
				}
			}
			output += '\n--------------------------------------------------------';
			$.cms.log(obj);
			$.cms.log(output);
		},
		
		// LOGGING
		log: function(message, show){
			if(typeof(window.console) !== 'undefined' && typeof(window.console.log) !== 'undefined'){
				console.log(message);
			}
			if(typeof(show) !== 'undefined' && $.fn.dialog){
				// DIALOG INITIALIZE
				if($.cms.addDialog('Core','Debug')){
					$('#cmsCoreDebugDialog').dialog({
						title: 'Debug',
						bgiframe: false,
						autoOpen: false,
						width: 500,
						height: 400,
						resizable: true,
						modal: false,
						zIndex: 1,
						close: function(){}
					});
				}
				
				// DIALOG LOAD
				if($('#cmsCoreDebugDialog').html() === ''){
					$('#cmsCoreDebugDialog').css({'padding':'6.05px 12.1px 6.05px 12.1px'});
					$('#cmsCoreDebugDialog').html($.cms.simpleLoad);
					$('#cmsCoreDebugDialog').dialog('open');
					$.ajax({
						url: SITE_ROOT+'snippet/cms/dialogs/debug.snip',
						success: function(response){
							$('#cmsCoreDebugDialog').html(response);
							$('#cmsCoreDebugDialog textarea[name="debug"]').val(message);
							$('#cmsCoreDebugDialog button').bind('click',{},function(){
								$('#cmsCoreDebugDialog textarea[name="debug"]').val('');
							});
						}
					});
				}else{
					$('#cmsCoreDebugDialog textarea[name="debug"]').val($('#cmsCoreDebugDialog textarea[name="debug"]').val()+'\n'+message);
					$('#cmsCoreDebugDialog').dialog('open');
				}
			}
		},
		
		// GET PARENT ID (tranverses upward to get the first parent with an id)
		getParentID: function(elem){
			var id = $(elem).parent().attr('id');
			if(!id){
				return($.cms.getParentID($(elem).parent()));
			}
			return(id);
		},
		
		// SET & GET HTML FRAGMENTS (snippets)
		setHtml: function(name, html){
			name = name.replace(/\//gi,'_');
			name = name.replace(/\./gi,'_');
			this['html'+name] = String(html);
		},
		
		getHtml: function(name, html){
			name = name.replace(/\//gi,'_');
			name = name.replace(/\./gi,'_');
			if(typeof(this['html'+name]) === 'string'){
				return(this['html'+name]);
			}
			return(false);
		},
		
		prepend: function(html){
			$('body:first').prepend(String(html));
		},
		
		append: function(html){
			$('body:first').prepend(String(html));
		},
		
		// INCLUDE JAVASCRIPT (on demand)
		include: function(jsFile){
			if(!this.scripts.inArray(jsFile)){
				if(jQuery.browser.safari || jQuery.browser.msie ){
					jQuery.ajax({url:jsFile, dataType:'script', async:false, cache: true});
					this.scripts[this.scripts.length] = jsFile;
				}else{
					var oHead = document.getElementsByTagName('head')[0];
					var oScript = document.createElement('script');
					oScript.type = 'text/javascript;charset=utf-8';
					oScript.src = jsFile;
					oHead.appendChild(oScript);
					this.scripts[this.scripts.length] = jsFile;
				}
			}
		},
		
		// TOGGLES THE DATA COMPONENT
		toggleData: function(elem){
			$(elem).nextAll('textarea:first[class="hidden"]').toggle();
		},
		
		// LOADS MULTIPLE CMS FILES (on demand)
		loadFiles: function(files, path){
			if(typeof(path) === 'undefined'){
				path = INCLUDE_ROOT+'/';
			}
			for(var i=0;i<files.length; i++){
				var jsFile = path + files[i];
				$.cms.include(jsFile);
			}
		},
		
		// ADDS SNIPPET (prevents duplicates)
		addSnippet: function(url){
			if(!this.snippets.inArray(url)){
				this.snippets[this.snippets.length] = url;
				$.ajax({
					url: url,
					type: 'POST',
					data: {
						whitespace: 0
					},
					success: function(response){
						$('body').prepend(response);
					}
				});
			}
		},
		
		getElement: function(name, elements){
			if(typeof(elements) === 'object'){
				if(typeof(elements[name]) === 'string'){
					return($('#'+elements[name]));
				}else if(typeof(elements[name]) === 'object'){
					return($(elements[name]));
				}
			}
			var obj = {length: 0};
			return(obj);
		},
		
		submit: function(action, data, form){
			if(typeof(form) === 'undefined'){
				form = $('#cms-hidden-form');
			}else if(typeof(form) === 'string'){
				form = $(form);
			}
			if(typeof(form) === 'object' && form.length === 1){
				form.html('');
				if(typeof(action) === 'string'){
					form.attr('action', action);
				}
				var query = $.query(data);
				for(var key in query){
					if(typeof(query[key]) === 'string' || typeof(query[key]) === 'number'){
						form.append("<input type='hidden' name='"+key+"' value='"+unescape(urldecode(query[key]).replace(/\'/gi,'&apos;'))+"' />");
					}
				}
				form.submit();
			}
			return false;
		},
		
		go: function(url){
			if(url.indexOf('://') < 0){
				url = urldecode(url);
			}
			if(url !== ''){
				document.location.href = url;
			}
		},
		
		openModal: function(){
			if($.fn.modal){
				$.modal($.cms.htmlLoad,{close: false});
			}
		},
		
		closeModal: function(){
			if($.fn.modal){
				$.modal.close();
			}
		},
		
		validate: function(form, required){
			var errors = [];
			if(typeof(form) === 'string'){
				form = $('#'+form);
			}
			if(typeof(required) === 'string'){
				required = required.split(',');
			}
			if(typeof(form) === 'object' && form.length === 1){
				if(typeof(required) === 'undefined'){
					if($('input[name="required"]', form).length !== 0){
						required = $('input[name="required"]', form).val().split(',');
					}
				}
				if(isArray(required)){
					var value, found, item, type, field;
					for(var i=0; i<required.length; i++){
						field = required[i].trim();
						if(field !== ''){
							found = false;
							item = $('[name="'+field+'"]', form);
							if(item.length > 0){
								type = item.attr('type');
								value = undefined;
								
								if(type === 'checkbox' || type === 'radio'){
									item = $('[name="'+field+'"]:checked', form);
									if(item.length > 0){
										value = item.val();
									}else{
										item = $('[name="'+field+'"]:first', form);
									}
								}else{
									value = item.val();
								}
								if(typeof(value) === 'string'){
									value = value.trim();
								}
								if((typeof(value) === 'string' && value !== '') || (isArray(value) && value.length >= 1)){
									found = true;
								}
							}
							if(!found){
								if(typeof(item.attr('data-message')) === 'string' && item.attr('data-message').trim() !== ''){
									errors[errors.length] = item.attr('data-message').trim()+'\n';
								}else{
									if(typeof(item.attr('data-label')) === 'string' && item.attr('data-label').trim() !== ''){
										field = item.attr('data-label').trim();
									}else{
										field = ucwords(field.replace(/_/gi,' '));
										field = field.replace(/\[\]$/,'');
									}
									errors[errors.length] = field+' is a required field.\n';
								}
							}
						}
					}
				}
			}else{
				errors[errors.length] = 'Unable to validate form.\n';
			}
			return(errors);
		},
		
		track: function(track){
			if(typeof(track) === 'undefined' || track !== 0){
				$.ajax({
					type: 'POST',
					data: {
						event: 'tracking',
						title: document.title,
						url: document.location.href,
						referrer: document.referrer,
						depth: screen.colorDepth,
						width: screen.width,
						height: screen.height
					}
				});
			}
		},
		
		stringToId: function(str){
			var id = '';
			for(var i=0; i<str.length; i++){
				var character = str.charAt(i);
				if($.cms.valid.indexOf(character) >= 0){
					id += character;
				}else{
					id += '';
				}
			}
			id = id.replace(/ /gi,'_');
			return(id);
		}
	};
}(jQuery));