/*global $, alert, cmsLoad, document, jQuery, unescape, urldecode */
var cmsFiles = ['js/jquery/form/2.36/jquery.form.js'];
if(typeof(cmsLoad) === 'function'){
    cmsLoad(cmsFiles);
}

/**
 * CMS Ajax Module
 * A jQuery object that enables all CMS crud forms to be submitted via ajax.
 * This class is meant to be used for sychronous ajax usage so a modal window is displayed
 * during ajax calls. It submits forms to a hidden iframe.
 *
 * @version 1.0
 * @requires
 * 		jquery.js
 * 		core.js
 * 		common.js - query data parsing
 * 		jquery.form.js - For resetting the form if need be
 * @author Ed Rodriguez Ed.Rodriguez@watermatters.org
 */
(function($){
	$.cms.ajax = {		
		submit: function(options){
			var elemForm;
			var success = false;
			
			// DEFAULTS
			$.cms.ajax = $.extend(true, $.cms.ajax, $.cms.ajax.defaults, options);
			
			// FRAME SETUP
			var elemFrame = $.cms.ajax.getElement('frame');
			
			// DYNAMIC FORMS SETUP
			if(typeof($.cms.ajax.data) !== 'undefined'){
				var data = $.cms.ajax.data;
				if(typeof(data) === 'string' && $.query){
					data = $.query(data);
				}
				if(typeof(data) === 'object'){
					$('#cms-hidden-form').html('');
					var action = (typeof($.cms.ajax.action) === 'string') ? $.cms.ajax.action : '';
					$('#cms-hidden-form').attr('action',action);
					$.cms.ajax.form = 'cms-hidden-form';
					for(var key in data){
						if(typeof(data[key]) === 'string' || typeof(data[key]) === 'number'){
							$('#cms-hidden-form').append("<input type='hidden' name='"+key+"' value='"+unescape(urldecode(data[key]).replace(/\'/gi,'&apos;'))+"' />");
						}
					}
					elemForm = $.cms.ajax.getElement('form');
				}else{
					$.cms.log('[Error] The Ajax Module failed to dynamically generate the form.');
				}
			}
			// FORMS SETUP
			else{
				elemForm = $.cms.ajax.getElement('form');
				if(elemForm.length === 0){ // TRY ANOTHER COMMON FORM/STATUS ID PAIRING
					$.cms.ajax.form = 'form';
					$.cms.ajax.status = 'status';
					elemForm = $.cms.ajax.getElement('form');
				}
			}
			
			if(typeof(elemForm) !== 'undefined'){
				if(elemForm.length > 0){ // SUBMITS A FORM
					
					// VALIDATION
					if($.cms.ajax.validate){
						var errors = $.cms.validate(elemForm);
						if(errors.length > 0){
							alert(errors.join(''));
							return false;
						}
					}
					
					var ajax = $("input[name='ajax']", elemForm);
					if(ajax.length <= 0){
						$(elemForm).prepend("<input type='hidden' name='ajax' value='1' />");
					}
					
					var status = $.cms.ajax.getElement('status');
					if(status.length > 0){
						status.hide();
					}
					
					elemFrame.unbind('load');
					elemFrame.load($.cms.ajax.callback);
					
					$.cms.openModal();
					
					/*
						SET TARGET
						
						BUG 1: MSIE sometimes doesn't allow changing the target attribute.
						An example of this occurs in the following pages. I am not sure
						exactly why this is happening on these pages.
						1. cms/layouts/form-staff.snip
						2. staff/data/edit.php
						
						BUG 2: JQuery attr doesn't work if there is a form element named 'target'
						
						NOTES: The dashboard needs this enabled to function properly.
					*/
					try{
						var attr = elemForm[0].getAttribute('target');
						if(attr !== String($.cms.ajax.frame)){
							elemForm[0].setAttribute('target', String($.cms.ajax.frame));
							$.cms.log('Setting Target...');
						}
						attr = elemForm[0].getAttribute('target');
						$.cms.log('Target: '+elemForm[0].getAttribute('target'));
						/* OLD (BUG 2)
						if(elemForm.attr('target') !== String($.cms.ajax.frame)){
							elemForm.attr('target', String($.cms.ajax.frame));
						}
						*/
					}catch(err){
						$.cms.log("The following error occured while trying to set the form's target.");
						$.cms.log(err);
					}
					
					// SUBMITS FORM
					// BUG: Don't use id='submit' for any html elements within the form tag.
					elemForm[0].submit();
					success = true;
				}
			}
			if(success === false){
				alert("The form could not be sent at this time.");
			}
			return false;
		},
		
		response: function(){
			$.cms.closeModal();
			var elemFrame = $.cms.ajax.getElement('frame');
			elemFrame.unbind('load');
			return(elemFrame.contents().find('body:first').html());
		},
		
		/*
			02/17/10
			Can a custom success function override the need to reset?
			The code I wrote below requires reset to be true for custom success
			function to fire.
			
			At the moment the only way a custom success function will trigger
			is if the string success or thanks are present in the response and
			reset is set to true. This needs to be revisited at some point. At
			the moment it is difficult to use custom success functions.
			
			08/19/10
			This was rewritten to fix the previous version issues
		*/
		callback: function(){
			var debug = '',
			message = undefined,
			response = $.cms.ajax.response(),
			status = $.cms.ajax.getElement('status'),
			form = $.cms.ajax.getElement('form'),
			query = $.query(document.location.href),
			type = 'other',
			success = 0,
			redirect = 0;
			
			// 1) INITIAL PROCESSING
			response = response.trim();
			if(typeof(response) === 'undefined' ||
			   response === null || response === ''){
				message = 'Unable to submit form.';
			}
			
			/*
				2) QUERY PROCESSING
				--------------------------
				Source: Event.php
				Type: Event Response
				Field Name: response
				Field Values:
					- query (Ex: query string formatted response)
			*/
			if(typeof(message) === 'undefined'){
				for(var i=0; i<response.length; i++){
					if(response.charAt(i) === ' '){
						break;
					}else if(response.charAt(i) === '='){
						type = 'query';
						break;
					}
				}
				if(type === 'query'){
					var query = $.query(response);
					if(typeof(query.errors) !== 'undefined'){
						var errors = urldecode(query.errors);
						errors = errors.split('|');
						if(errors.length > 0){
							message = '';
							for(var i=0; i<errors.length; i++){
								if(status.length > 0){
									message += '<div class="error">'+errors[i]+'</div>\n';
								}else{
									message += String(errors[i]).trim()+'\n';
								}
							}
						}
					}else if(typeof(query.error) !== 'undefined'){
						message = response.error;
					}else if(typeof(query.location) !== 'undefined'){
						redirect = 1;
						message = 'Redirecting page';
						document.location.href = urldecode(query.location);
					}else if(typeof(query.success) !== 'undefined' && query.success === 1){
						message = 'The form has been successfully submitted.';
						if(typeof(query.message) !== 'undefined'){
							message = urldecode(query.message);
						}
						success = 1;
					}
				}
			}
			
			/*
				3) OTHER PROCESSING
				--------------------------
				Source: FormsUtils.php
				Type: Ajax Response
				Field Name: ajax_response
				Field Values:
					- html (Ex: template formatted logs)
					- text (Ex: plain text logs)
					- json (Ex: json encoded logs)
					- xml (Ex: xml encoded logs)
			*/
			if(typeof(message) === 'undefined'){
				message = response;
				if(message.toLowerCase().indexOf('success') >= 0 ||
					message.toLowerCase().indexOf('thanks') >= 0){
					success = 1;
				}
			}
			
			// 4) DEBUGGING
			if(typeof(query.cms) !== 'undefined'){
				debug += '\n \
				---------------------------------------\n \
				CMS Ajax Module - Debugging\n \
				---------------------------------------\n \
				Form Length: '+form.length+'\n \
				Form ID: '+form.attr('id')+'\n \
				Status Length: '+status.length+'\n \
				Status ID: '+status.attr('id')+'\n \
				Response: '+response+'\n \
				Message: '+message.toLowerCase()+'\n \
				Reset: '+$.cms.ajax.reset+'\n \
				Success: '+typeof($.cms.ajax.success)+'\n \
				Speed: '+$.cms.ajax.speed+'\n';
				$.cms.log(debug+'\n');
			}			
			
			// 5) FORMATTED STATUS
			if(status.length > 0){
				// ERRORS or SUCCESS
				status.html(message);
				status.fadeIn($.cms.ajax.speed);
				setTimeout(function(){
					status.fadeOut($.cms.ajax.speed);
					// SUCCESS
					if(success){
						if(typeof($.cms.ajax.success) === 'function'){
							$.cms.ajax.success(form);
						}
						if($.cms.ajax.reset){
							form.resetForm();
						}
					}
				}, $.cms.ajax.timeout);
			}
			
			// 6) PLAIN STATUS
			else{
				// SUCCESS
				if(success){
					if(typeof($.cms.ajax.success) === 'function'){
						$.cms.ajax.success(form);
					}else if(!redirect){
						// IE BUG WITH LINE BREAKS
						alert(message.replace(/\\n/gi,'\n'));
					}
					if($.cms.ajax.reset){
						form.resetForm();
					}
				}
				// ERRORS
				else if(!redirect){
					alert(message.replace(/\\n/gi,'\n'));
				}
			}
		},
		
		getElement: function(name){
			return($.cms.getElement(name, $.cms.ajax));
		}
	};
	$.cms.ajax.defaults = {
		module: 'Ajax',		
		speed: 'normal',
		timeout: 4000,
		reset: false,
		validate: false,
		success: undefined,
		action: undefined,
		data: undefined,
		
		// ELEMENTS
		form: 'cms-form',
		frame: 'cms-frame',
		status: 'cms-status'
	};
}(jQuery));
