function isIE()
{
	return $.browser.msie
}

/** cs libray, last update: January 26th, 2010 */
jQuery.fn.center = function (absolute) {
	var absolute = absolute;
    return this.each(function () {
        var t = jQuery(this);
	if (jQuery.browser.msie)
		if (jQuery.browser.version < 7)
			absolute = true;
        t.css({
            position:    absolute ? 'absolute' : 'fixed', 
            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()
            });
        }
	
	if(t.height() > jQuery(window).height())
		t.css({
					marginTop: '0px',
					top: '10px',
					position: 'absolute'
				  });
	
    });
};

jQuery.fn.centerDown = function (absolute) {
	var absolute = absolute;
    return this.each(function () {
        var t = jQuery(this);
	if (jQuery.browser.msie)
		if (jQuery.browser.version < 7)
			absolute = true;
        t.css({
            position:    absolute ? 'absolute' : 'fixed', 
            left:        '50%', 
            top:        '340px'
        }).css({
            marginLeft:    '-' + (t.outerWidth() / 2) + 'px', 
            marginTop:    '-10px'
        });

        if (absolute) {
            t.css({
                marginTop:    '350px', 
                marginLeft:    parseInt(t.css('marginLeft'), 10) + jQuery(window).scrollLeft()
            });
        }
	
	if(t.height() > jQuery(window).height())
		t.css({
					marginTop: '0px',
					top: '10px',
					position: 'absolute'
				  });
	
    });
};

jQuery.fn.centerDownHigh = function (px) {
    return this.each(function () {
        var t = jQuery(this);

        t.css({
            position:    'absolute', 
            left:        '50%', 
            top:        px + 'px'
        }).css({
            marginLeft:    '-' + (t.outerWidth() / 2) + 'px', 
            marginTop:    '-10px'
        });

            t.css({
                marginTop:    px + 'px', 
                marginLeft:    parseInt(t.css('marginLeft'), 10) + jQuery(window).scrollLeft()
            });
	
	if(t.height() > jQuery(window).height())
		t.css({
					marginTop: '0px',
					top: '10px',
					position: 'absolute'
				  });
	
    });
};

/**
* 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},
									fBeforeSubmit: 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
		.submit(function()
				{
					var frm  = jQuery(this);
					settings.fBeforeSubmit(frm);
					
					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 {} 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, .notice_warning, form',
									popupCloseButtonClass: 'AJAXFormPopupCloseButton',
									formLoadCallBack: function(){},
									successCallBack: function(){location.reload();},
									closeOnSuccessfulSubmit: true,
									fBeforeSubmit: function(){return false},
									center: true,
									centerDown: false,
									centerDownHigh: false,
									open: false,
									offsetX: 0,
									offsetY: 0,
									type: 'get',
									data: null
								  }, 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();
				if (this.settings.open == true)
					this.openPopup()
				else
					this.setPopupTriggerEvents();
			}
				
	this.createDynamicElements = function()
					{
						if(this.AJAXFormWrapper.size() == 0)
						{
							this.createFormWrapper();
							this.createPopupCloseButton();
						}
							this.createProgressIndicator();
					}
									
	this.createFormWrapper = function()
				{
						this.AJAXFormWrapper = jQuery('<div></div>');
						if(isIE())
							this.AJAXFormWrapper.addClass('ie');
						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>');
							if(isIE())
								this.AJAXProgressIndicator.addClass('ie');
							this.AJAXProgressIndicator
									.attr('class', 'AJAXProgressIndicator')
									.css('display', 'none')
									.text('processing request...')
									.appendTo(this.AJAXFormWrapper);
						}
					}
									
	this.setPopupTriggerEvents = function()
					{
						if (this.AJAXFormPopupTrigger != null) {
						this.AJAXFormPopupTrigger
							.click(function()
									{
										ajaxFrm.openPopup();
										return false;
									})
						}
					}
										
	this.getAJAXForm = function()
			{
				if (this.AJAXForm == null)
				{
					this.clearPopupContent();
					this.openPopup();
					this.displayProgressIndicator();
					jQuery.ajax({
							type: this.settings.type,
							data: this.settings.data,
							url: this.settings.AJAXpageUrl,
							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(err)
								{
									//console.log(err);
								}
						})
				}
			}
						
	this.clearPopupContent = function()
								{
									this.AJAXFormWrapper.find(ajaxFrm.settings.AJAXpageElementsFilter).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);
										tmpWrapper.remove();
								}
								
	this.processAJAXResults = function()
									{
										this.AJAXForm = this.AJAXFormWrapper.find(this.settings.AJAXpageElementsFilter).filter('form');
										if(this.AJAXForm.size() == 0)
											this.AJAXForm = this.AJAXFormWrapper.find('form');
																				
										if (this.AJAXForm.size() > 0) // form displayed, unsuccessful submit
										{
											ajaxFrm.setAJAXFormEvents();
											ajaxFrm.openPopup();
											if (ajaxFrm.settings.formLoadCallBack != null)
												ajaxFrm.settings.formLoadCallBack(ajaxFrm.AJAXFormWrapper, ajaxFrm.AJAXFormPopupTrigger, ajaxFrm);
										}
										else
										{
											if(ajaxFrm.settings.successCallBack != null)
												ajaxFrm.settings.successCallBack(ajaxFrm.AJAXFormWrapper, ajaxFrm.AJAXFormPopupTrigger, ajaxFrm);
											
											if (ajaxFrm.settings.closeOnSuccessfulSubmit == true)
											{
												ajaxFrm.closePopup();
											}
										}
									}
								
	this.setAJAXFormEvents = function()
				{
					// prepare form submit
					if (this.AJAXForm != null)
					{	
						this.fixIE6Checkboxes();
						this.AJAXForm
								.submit(function()
										{
											var frm = jQuery(this);
											frm.find('input[removeOnSubmit=true]').remove(); // clear any dynamically created helper fields
											ajaxFrm.settings.fBeforeSubmit(frm);
											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();																										
																		}
														})
											return false;
										})	
					}
				}
				
	this.fixIE6Checkboxes = function()
				{
					if ((jQuery.browser.msie) && (Math.floor(jQuery.browser.version) == 6)){
						var frm = this.AJAXForm;
						this.AJAXForm.find('input:checkbox')
							.each(function()
								{
									var chk = jQuery(this);
									var chkName = chk.attr('name');
									chk.attr({
											name: 'chk_' + chkName,
											reField: chkName,
											removeOnSubmit: true
										 })
									    .click(function()
											{
												var chk = jQuery(this);
												var form = chk.parents('form:first');
												var reField = form.find('input[name=' + chk.attr('reField') + ']');
												if(chk.attr('checked') == true)
													reField.val(chk.val()).attr('removeOnSubmit', false)
												else
													reField.val('').attr('removeOnSubmit', true);
											});
									
									var reField = jQuery('<input type="hidden" name="' + chkName + '" />');
									frm.append(reField);
									
									if(chk.attr('checked') == true)
										reField.val(chk.val()).attr('removeOnSubmit', false)
									else
										reField.val('').attr('removeOnSubmit', true);
								})
					}
				}
	

	this.closePopup = function()
						{
							this.AJAXFormWrapper.css('display', 'none');
						}
						
	this.openPopup = function()
						{
							this.AJAXFormWrapper
									.css({
										position: 'absolute',
										zIndex: 3000
									 });

							if (this.settings.center == true)
								this.AJAXFormWrapper.center();
							else if (this.settings.centerDown == true)
								this.AJAXFormWrapper.centerDown();
							else if (this.settings.centerDownHigh == true)
								this.AJAXFormWrapper.centerDownHigh(125);
							else
								this.AJAXFormWrapper
										.css({
											left: this.AJAXFormPopupTrigger.offset().left + this.settings.offsetX + 'px',
											top: this.AJAXFormPopupTrigger.offset().top + this.settings.offsetY + 'px'
										 });
							 	
							this.AJAXFormWrapper.css('display', 'block');
						}
						
	this.displayProgressIndicator = function()
									{
										this.AJAXProgressIndicator.css('display', 'block');
									}
									
	this.hideProgressIndicator = function()
									{
										this.AJAXProgressIndicator.css('display', 'none');
									}
									
	var ajaxFrm = this;
	
	this.init();
}


// field character counter
jQuery.fn.extend({
			 count: function()
					{						
						$(this).each(function()
						{
							var target = jQuery(this);
							var counterWrapper = jQuery('<small class="counterWrapper"></small>');
							target.after(counterWrapper);
							
							target.extend({
									update: function()
											{
												var counter = {
														chars: 0
														};
														
														//<small>140 characters max</small>
														
												var targetContent = new String(target.val());
												
												var maxChars = parseInt(target.attr('max'));
												
												if (targetContent != '')
												{
													counter['chars'] = targetContent.length;
												}
												
												if(isNaN(maxChars))
													counterWrapper.html('[chars: ' + counter.chars + ']')
												else
												{
													var diff = maxChars - counter.chars;
													if(diff == maxChars){
														var html = '<span>' + counter.chars + '/' + maxChars + ' characters</span>'
													}
													else if(diff >= 0){
														var html = '<span>' + counter.chars + '/' + maxChars + ' characters</span>'
													}
													else{
														var html = '<span style="color: red; background: #FFF; padding: 1px 3px;">' + counter.chars + '/' + maxChars + ' characters</span>';
													}
													counterWrapper.html(html)
												}
													
											}
									  })
							
							target.keyup(target.update);
							target.change(target.update);
							target.click(target.update);
							target.update();
						})
					}
})
