/** cs libray, last update: June 10th, 2009

/**
* Submits a form via AJAX
* @param {Object} params 
	@param {jQuery Object} jqSection the wrapper of the form and it's related items(notices etc)
	@param {jQuery Object} jqForm the form that is submitted via AJAX(information read from the form attributes/elements: action, method(default: get), data(all form elements in serialized form))
	@param {Function(jqSection, frm, AJAXresponse)} fSuccess the function called on successful AJAX request
	@param {Function(jqSection, frm)} fPending the function called while AJAX request is pending
	@param {Function(jqSection, frm, AJAXerror)} fError the function called on unsuccessful AJAX request
*/
function AJAXFormSubmit(params)
{
	var settings = jQuery.extend({
									jqSection: null, 
									jqForm: null, 
									fSuccess: function(){return false}, 
									fPending: function(){return false}, 
									fError: function(){return false}
								 }, 
								 params);
	
	var jqForm = settings.jqForm;
	var jqSection = settings.jqSection;
	
	if ((jqForm.size() < 0) || (jqSection.size() < 0))
		return false;
		
	var formAJAXInfo = {};
	
	formAJAXInfo.url = jQuery.trim(jqForm.attr('action'));
	if(formAJAXInfo.url == '')
		return false;
		
	formAJAXInfo.method = jqForm.attr('method')||'get';
	
	jqForm
		.unbind('submit')
		.submit(function()
				{
					var frm  = jQuery(this);				
					settings.fPending(jqSection, frm);
					
					formAJAXInfo.formData = frm.serialize();
					
					jQuery
						.ajax({
								url: formAJAXInfo.url,
								type: formAJAXInfo.method,
								data: formAJAXInfo.formData,
								success: function(AJAXresponse)
											{
												settings.fSuccess(jqSection, frm, AJAXresponse);
											},
											
								error: function(AJAXerror)
										{
											settings.fError(jqSection, frm, AJAXerror)
										}
								
							 })
					
					return false;
				})
}

/**
* On trigger click gets a form page via AJAX, filters all form related content, and displays the form inside a popup layer positioned relatively to the trigger link
* The form is submitted via AJAX. If the AJAX request response contains no form, it is considered a successful submit, and the page refreshes(other successful submit function can be passed as param). Otherwise the form and its related elements is displayed
* @param {Object} settings 
	@param {jQuery Object} popupFormTrigger: the link that trigger the popup
	@param {jQuery Object} dynamicWrapperId: the dyanmically created wrapper around all form related content.
	@param {} dynamicWrapperCssClass: the css class given to the dynamic wrapper 
	@param {} AJAXpageElementsFilter: the jQuery elements identifiers of the elements to be displayed inside the popup
	@param {} popupCloseButtonClass: the css class for the popup closing button
	@param {function} formLoadCallBack: the function called after the form is loaded via AJAX (usefull for re-setting events on certain form elements like date pickers, color pickers, submit link buttons etc)
	@param {function} successCallBack: the function called on successful AJAX request(default it reloads the page)
	@param {function} closeCallBack: the function called on when closing a popup(default is null)
	@param {} closeOnSuccessfulSubmit: flag for closign the popup after a successful submit
*/
function AJAXForm(settings)
{
	this.settings = jQuery.extend({
									popupFormTrigger: null,
									dynamicWrapperId: null,
									dynamicWrapperCssClass: 'AJAXPopupForm',
									AJAXpageElementsFilter: '.notice_error, .notice_success, form',
									popupCloseButtonClass: 'AJAXFormPopupCloseButton',
									formLoadCallBack: function(){},
									successCallBack: function(){location.reload();},
									closeCallBack: null,
									customCloseButton: null,
									closeOnSuccessfulSubmit: true,
									triggerOffsetX: 0,
									triggerOffsetY: 0
								  }, settings);
					
	this.AJAXFormPopupTrigger = this.settings.popupFormTrigger;
	this.AJAXFormWrapper = jQuery('#' + this.settings.dynamicWrapperId);
	this.AJAXForm = null;
	this.AJAXProgressIndicator = null;
	
	this.init = function()
				{
					this.createDynamicElements();
					this.getAJAXForm();
					this.setPopupTriggerEvents();
				}
				
	this.createDynamicElements = function()
									{
										if(this.AJAXFormWrapper.size() == 0)
										{
											this.createFormWrapper();
											this.createPopupCloseButton();
										}
											this.createProgressIndicator();
									}
									
	this.createFormWrapper = function()
								{
										this.AJAXFormWrapper = jQuery('<div></div>');
										this.AJAXFormWrapper
												.attr({
														'class': this.settings.dynamicWrapperCssClass,
														'id': this.settings.dynamicWrapperId
													  })
												.appendTo('body');
								}
								
	this.createPopupCloseButton	= function()
									{
											// create close button
											var closeBtn = jQuery('<a href="#">[X]</a>');
											closeBtn
												.attr({
														'class': this.settings.popupCloseButtonClass,
														'rel': this.settings.dynamicWrapperId,
														'title': 'Close'
													  })
												.click(function()
															{
																ajaxFrm.closePopup();
																return false;
															})
												.appendTo(this.AJAXFormWrapper);
									}
									
	this.createProgressIndicator = function()
									{
										if(this.AJAXProgressIndicator == null)
										{
											this.AJAXProgressIndicator = jQuery('<div></div>');
											this.AJAXProgressIndicator
													.attr('class', 'AJAXProgressIndicator')
													.css('display', 'none')
													.appendTo(this.AJAXFormWrapper)
													.html('<p>processing request...</p>');
										}
									}
									
	this.setPopupTriggerEvents = function()
									{
										this.AJAXFormPopupTrigger
											.click(function()
													{
														ajaxFrm.hideProgressIndicator();
														ajaxFrm.openPopup();
														return false;
													})
									}
										
	this.getAJAXForm = function()
						{
							if (this.AJAXForm == null)
							{
								this.clearPopupContent();
								this.openPopup();
								this.displayProgressIndicator();
								
								jQuery.ajax({
												type: 'get',
												url: this.settings.AJAXpageUrl,
												dataType: 'html',
												success: function(htmlResp)
															{
																ajaxFrm.hideProgressIndicator(); // hide progress indicator
																ajaxFrm.clearPopupContent();
																// build dynamic wrapper to be able to filter the HTML result
																ajaxFrm.filterHTMLresponse(htmlResp);
																ajaxFrm.processAJAXResults();
																
															},
												error: function(xhr)
														{
															ajaxFrm.hideProgressIndicator(); // hide progress indicator
															ajaxFrm.AJAXFormWrapper.find('.notice_ajax_warning').remove().end().append('<div class="notice_ajax_warning">An error has occured while performing your action. Please try again after refreshing the page.</div>');
														}
											})
							}
						}
						
	this.clearPopupContent = function()
								{
									this.AJAXFormWrapper.find(ajaxFrm.settings.AJAXpageElementsFilter).add('.notice_ajax_warning').remove(); // remove current form
								}
						
	this.filterHTMLresponse = function(htmlResp)
								{
									// stripping everything outside the body tags
									var htmlStr = new String(htmlResp);
									var regExFilter = new RegExp("(^<[^\^]*<\/head>$)|(<body>)|(<\/body>[^\^]*<\/html>)", "mig");
									htmlStr = htmlStr.replace(regExFilter, "");
									var tmpWrapper = jQuery('<div style="display:none"></div>');
										tmpWrapper
											.html(htmlStr)
											.appendTo('body')
											.find(ajaxFrm.settings.AJAXpageElementsFilter)
											.appendTo(ajaxFrm.AJAXFormWrapper);
								}
								
	this.processAJAXResults = function()
									{
										this.AJAXForm = this.AJAXFormWrapper.find(this.settings.AJAXpageElementsFilter).filter('form');
										
										if(this.AJAXForm.size() == 0)
											this.AJAXForm = this.AJAXFormWrapper.find(this.settings.AJAXpageElementsFilter).find('form');
										if (this.AJAXForm.size() > 0)  // form displayed, unsuccessful submit
										{
											ajaxFrm.setAJAXFormEvents();
											ajaxFrm.openPopup();
												
											if(ajaxFrm.settings.customCloseButton != null)
											{
												var closeBtn = jQuery(ajaxFrm.settings.customCloseButton);
												this.AJAXForm.find('input:submit').after(closeBtn);
												closeBtn
													.click(function()
															{
																ajaxFrm.closePopup('cancel');
																return false;
															});
											}
											
											if (ajaxFrm.settings.formLoadCallBack != null)
												ajaxFrm.settings.formLoadCallBack(ajaxFrm.AJAXFormWrapper);
										}
										else
										{
											if(ajaxFrm.settings.successCallBack != null)
											{
												ajaxFrm.settings.successCallBack(ajaxFrm.AJAXFormWrapper);
											}
											if (ajaxFrm.settings.closeOnSuccessfulSubmit == true)
											{
												ajaxFrm.closePopup();
											}
										}
									}
								
	this.setAJAXFormEvents = function()
								{
									// prepare form submit
									if (this.AJAXForm != null)
									{
										this.AJAXForm
												.unbind('submit')
												.submit(function()
														{
															var frm = jQuery(this);
															ajaxFrm.clearPopupContent();
															ajaxFrm.displayProgressIndicator();
															jQuery.ajax({
																			type: frm.attr('method'),
																			url: frm.attr('action'),
																			data: frm.serialize(),
																			cache: false,
																			dataType: 'html',
																			success: function(htmlResp)
																						{
																							ajaxFrm.hideProgressIndicator(); // display progress indicator
																							// build dynamic wrapper to be able to filter the HTML result
																							ajaxFrm.filterHTMLresponse(htmlResp);
																							ajaxFrm.processAJAXResults();
																						},
																			error: function(xhr)
																					{
																						ajaxFrm.hideProgressIndicator(); // hide progress indicator
																						ajaxFrm.AJAXFormWrapper.find('.notice_ajax_warning').remove().end().append('<div class="notice_ajax_warning">An error has occured while performing your action. Please try again after refreshing the page.</div>');
																					}
																		})
															return false;
														});
												
										this.AJAXForm.find('input:text, select, textarea').filter(':first').focus();
									}
								}

	this.closePopup = function(flag)
						{
							ajaxFrm.AJAXFormWrapper.css('display', 'none');
							if((ajaxFrm.settings.closeCallBack != null) && (flag != 'cancel'))
								ajaxFrm.settings.closeCallBack();
						}
						
	this.openPopup = function()
						{
							this.AJAXFormWrapper
									.css({
										position: 'absolute',
										left: this.AJAXFormPopupTrigger.offset().left + this.settings.triggerOffsetX + 'px',
										top: this.AJAXFormPopupTrigger.offset().top + this.settings.triggerOffsetY + 'px',
										zIndex: 3000,
										display: 'block'
									 })
						}
						
	this.displayProgressIndicator = function()
									{
										this.AJAXProgressIndicator.css('display', 'block');
									}
									
	this.hideProgressIndicator = function()
									{
										this.AJAXProgressIndicator.css('display', 'none');
									}
									
	var ajaxFrm = this;
	
	this.init();
}