jQuery.fn.center = function (absolute) {
    return this.each(function () {
        var t = jQuery(this);
	var pos = absolute ? 'absolute' : 'fixed';
	if (($.browser.msie) && (parseInt($.browser.version ) < 7)) 
		pos = 'absolute';
		
        t.css({
            position:    pos, 
            left:        '50%', 
            top:        '50%'
        }).css({
            marginLeft:    '-' + (t.outerWidth() / 2) + 'px', 
            marginTop:    '-' + (t.outerHeight() / 2) + 'px'
        });

        if (absolute) {
            t.css({
                marginTop:    parseInt(t.css('marginTop'), 10) + jQuery(window).scrollTop(), 
                marginLeft:    parseInt(t.css('marginLeft'), 10) + jQuery(window).scrollLeft()
            });
        }
    });
};

/** cs libray, last update: January 8th, 2010

/**
* 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(jqSection, frm, AJAXresponse){return false}, 
					fPending: function(jqSection, frm){return false}, 
					fError: function(jqSection, frm, AJAXerror){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 {} AJAXpageElementsWrapper: the jQuery selecter of the wrapper of 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 closing the popup after a successful submit
*/
function AJAXForm(settings)
{
	this.settings = jQuery.extend({
					popupFormTrigger: null,
					dynamicWrapperId: null,
					dynamicWrapperCssClass: 'AJAXPopupForm',
					AJAXpageElementsWrapper: '.PopupContent',
					popupCloseButtonClass: 'AJAXFormPopupCloseButton',
					formLoadCallBack: function(){},
					successCallBack: function(){location.reload();},
					closeCallBack: null,
					customCloseButton: null,
					closeOnSuccessfulSubmit: true,
					triggerOffsetX: 0,
					triggerOffsetY: 0,
					width: 500,
					height: 400,
					waitMessage: 'processing your request. please wait...',
					mainContainer: 'body',
					type: 'overlay' // overlay, embedded
				  }, 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
								  });
					if(this.settings.type == 'overlay')
						this.AJAXFormWrapper.css({
										//left: this.AJAXFormPopupTrigger.offset().left + this.settings.triggerOffsetX + 'px',
										//top: this.AJAXFormPopupTrigger.offset().top + this.settings.triggerOffsetY + 'px',
										width: this.settings.width + 'px',
										height: (this.settings.height=='auto')?'auto':(this.settings.height + 'px')
									     });
					this.AJAXFormWrapper.appendTo(this.settings.mainContainer);

					if(this.settings.type == 'overlay')
					{
						this.AJAXFormWrapper.center();
	
						this.AJAXFormWrapper.resize(function(){
											var popup = jQuery(this);
											var cntWrapper = popup.find(ajaxFrm.settings.AJAXpageElementsWrapper);
											cntWrapper.parents('.jScrollPaneContainer')
												.css({
													height: popup.height() + 'px',
													width: popup.width() + 'px'
												     });
											cntWrapper.jScrollPane();
										     });
					}
				}
								
	this.createPopupCloseButton = function()
						{
							// create close button
							var closeBtn = jQuery('<a href="#">[X]</a>');
							closeBtn
								.attr({
										'class': this.settings.popupCloseButtonClass,
										'rel': this.settings.dynamicWrapperId,
										'title': 'Inchide'
									  })
								.click(function()
											{
												ajaxFrm.closePopup();
												return false;
											})
								.appendTo(this.AJAXFormWrapper);
						}
									
	this.createProgressIndicator = function()
					{
						if(this.AJAXProgressIndicator == null)
						{
							var waitMessage = '<p>' + this.settings.waitMessage + '</p>'
							this.AJAXFormWrapper.find('.AJAXProgressIndicator').remove();
							this.AJAXProgressIndicator = jQuery('<div></div>');
							this.AJAXProgressIndicator
									.attr('class', 'AJAXProgressIndicator')
									.css('display', 'none')
									.appendTo(this.AJAXFormWrapper)
									.html(waitMessage);
						}
					}
									
	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.AJAXpageElementsWrapper + ', .notice_ajax_warning, .jScrollPaneContainer').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');
						var cntWrapper = tmpWrapper.find(ajaxFrm.settings.AJAXpageElementsWrapper);
						cntWrapper.appendTo(ajaxFrm.AJAXFormWrapper);
						if(ajaxFrm.settings.type == 'overlay')
						{
							if(ajaxFrm.settings.height != 'auto')
							{
								cntWrapper.css({
										height: ajaxFrm.AJAXFormWrapper.height() + 'px',
										width: ajaxFrm.AJAXFormWrapper.width() + 'px',
										overflow: 'auto'
									       });
								cntWrapper.jScrollPane();
							}
						}
						tmpWrapper.remove();
					}
								
	this.processAJAXResults = function()
					{
						this.AJAXForm = this.AJAXFormWrapper.find(this.settings.AJAXpageElementsWrapper).filter('form');
						
						if(this.AJAXForm.size() == 0)
							this.AJAXForm = this.AJAXFormWrapper.find(this.settings.AJAXpageElementsWrapper).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(ajaxFrm.AJAXFormWrapper);
				}
						
	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();
}