(function (window, undefined){
	"use strict";
	pjQ.$.ajaxSetup({
		xhrFields: {
			withCredentials: true
		}
	});
	var document = window.document,
		validate = (pjQ.$.fn.validate !== undefined),
		routes = [
		          	{pattern: /^#!\/loadServices$/, eventName: "loadServices"},
		          	{pattern: /^#!\/loadDateTime$/, eventName: "loadDateTime"},
		          	{pattern: /^#!\/loadCheckout$/, eventName: "loadCheckout"},
		          	{pattern: /^#!\/loadPreview$/, eventName: "loadPreview"},
		         ];
	
	function log() {
		if (window.console && window.console.log) {
			for (var x in arguments) {
				if (arguments.hasOwnProperty(x)) {
					window.console.log(arguments[x]);
				}
			}
		}
	}
	
	function assert() {
		if (window && window.console && window.console.assert) {
			window.console.assert.apply(window.console, arguments);
		}
	}
	
	function hashBang(value) {
		if (value !== undefined && value.match(/^#!\//) !== null) {
			if (window.location.hash == value) {
				return false;
			}
			window.location.hash = value;
			return true;
		}
		
		return false;
	}
	
	function onHashChange() {
		var i, iCnt, m;
		for (i = 0, iCnt = routes.length; i < iCnt; i++) {
			m = window.location.hash.match(routes[i].pattern);
			if (m !== null) {
				pjQ.$(window).trigger(routes[i].eventName, m.slice(1));
				break;
			}
		}
		if (m === null) {
			pjQ.$(window).trigger("loadServices");
		}
	}
	pjQ.$(window).on("hashchange", function (e) {
    	onHashChange.call(null);
    });
	
	function CleaningBusiness(opts) {
		if (!(this instanceof CleaningBusiness)) {
			return new CleaningBusiness(opts);
		}
				
		this.reset.call(this);
		this.init.call(this, opts);
		
		return this;
	}
	
	CleaningBusiness.inObject = function (val, obj) {
		var key;
		for (key in obj) {
			if (obj.hasOwnProperty(key)) {
				if (obj[key] == val) {
					return true;
				}
			}
		}
		return false;
	};
	
	CleaningBusiness.size = function(obj) {
		var key,
			size = 0;
		for (key in obj) {
			if (obj.hasOwnProperty(key)) {
				size += 1;
			}
		}
		return size;
	};
	
	CleaningBusiness.prototype = {
		reset: function () {
			this.$container = null;			
			this.container = null;
			this.opts = {};
			
			return this;
		},
		
		disableButtons: function () {
			this.$container.find(".btn").each(function (i, el) {
				pjQ.$(el).attr("disabled", "disabled");
			});
		},
		enableButtons: function () {
			this.$container.find(".btn").removeAttr("disabled");
		},
		
		init: function (opts) {
			var self = this;
			this.opts = opts;
			this.container = document.getElementById("pjCbsContainer_" + self.opts.index);
						
			self.$container = pjQ.$(self.container);
			
			this.$container.on("click.cbs", ".pjCbsMenuItem", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var load = pjQ.$(this).attr('data-load');
				if (!hashBang("#!/" + load)) 
				{
					pjQ.$(window).trigger(load);
				}
				return false;
			}).on("click.cbs", ".pjCbsLocale", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				self.opts.locale = pjQ.$(this).data("id");
				var params = {};
				if(self.opts.session_id != '')
				{
					params.session_id = self.opts.session_id;
				}
				
				params.locale_id = self.opts.locale;
				params.index = self.opts.index;
				
				self.disableButtons.call(self);
				pjQ.$.get([self.opts.folder, "index.php?controller=pjFront&action=pjActionLocale"].join(""), params).done(function (data) {
					if (!hashBang("#!/loadServices")) {
						pjQ.$(window).trigger("loadServices");
					}
				}).fail(function () {
					self.enableButtons.call(self);
				});
				return false;
			}).on("change.cbs", "select[name='payment_method']", function () {
				self.$container.find(".pjCbsCcWrap").hide();
				self.$container.find(".pjCbsBankWrap").hide();
				switch (pjQ.$("option:selected", this).val()) {
				case 'creditcard':
					self.$container.find(".pjCbsCcWrap").show();
					break;
				case 'bank':
					self.$container.find(".pjCbsBankWrap").show();
					break;
				}
			}).on("click.nc", ".pjCbsBtnStartOver", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				if (!hashBang("#!/loadServices")) 
				{
					self.loadServices.call(self);
				}
				return false;
			}).on("change.cbs", ".pjCcCustomCheckbox input, .pjCcCustomRadio input", function (e) {
				var input = this;
				var checkedClass = 'pjCcCustomInputChecked';
				var disabledClass = 'pjCcCustomInputDisabled';
				if(input.type === 'radio') {
					if(!pjQ.$(input).prop('disabled'))
					{
						var name = input.name;
						pjQ.$(input.ownerDocument).find('[name=' + name + ']').each(function() {
							var radioInput = this;
							pjQ.$(radioInput).parent().toggleClass(checkedClass, radioInput.checked);
						});
						if(pjQ.$('#frmDateTimeForm_'+ self.opts.index).length > 0 && name == 'how_often')
						{
							var $selectDateTitle = pjQ.$('#pjCbsDateTitle_' + self.opts.index);
							var title1 = $selectDateTitle.attr('data-one');
							var title2 = $selectDateTitle.attr('data-two');
							if(input.value == 'once')
							{
								$selectDateTitle.html(title1);
							}else{
								$selectDateTitle.html(title2);
							}
						}
					}
				} else {
					pjQ.$(input).parent().toggleClass(checkedClass, input.checked);
				};
				if(pjQ.$('#frmServicesForm_'+ self.opts.index).length > 0)
				{
					self.addServices.call(self);
					self.validateServices.call(self);
				}
				if(pjQ.$('#frmDateTimeForm_'+ self.opts.index).length > 0)
				{
					self.addDateTime.call(self);
					self.validateDateTime.call(self);
				}
				return false;
			}).on("disable.cbs", ".pjCcCustomCheckbox input, .pjCcCustomRadio input", function (e) {
				var input = this;
				var disabledClass = 'pjCcCustomInputDisabled';
				input.disabled = true;
				pjQ.$(input).parent().addClass(disabledClass);
				return false;
			}).on("enable.cbs", ".pjCcCustomCheckbox input, .pjCcCustomRadio input", function (e) {
				var input = this;
				var disabledClass = 'pjCcCustomInputDisabled';
				input.disabled = false;
				pjQ.$(input).parent().removeClass(disabledClass);
			}).on("change.cbs", "input[type=radio][name=cleaning_materials]", function (e) {
				var $pjCcCleaningMaterialsPrice = pjQ.$('.pjCcCleaningMaterialsPrice');
				if (this.id === 'pjCcCleaningMaterialsNo') {
					$pjCcCleaningMaterialsPrice.stop(true, true).show('slow');
				} else {
					$pjCcCleaningMaterialsPrice.stop(true, true).hide('slow');
				};
				self.addServices.call(self);
				return false;
			}).on("change.cbs", "#pjCcTimeOfDay", function (e) {
				self.addDateTime.call(self);
				return false;
			});
			
			pjQ.$(window).on("loadServices", this.$container, function (e) {
				self.loadServices.call(self);
			}).on("loadDateTime", this.$container, function (e) {
				self.loadDateTime.call(self);
			}).on("loadCheckout", this.$container, function (e) {
				self.loadCheckout.call(self);
			}).on("loadPreview", this.$container, function (e) {
				self.loadPreview.call(self);
			});
			
			if (window.location.hash.length === 0) {
				this.loadServices.call(this);
			} else {
				onHashChange.call(null);
			}
		},
		validateServices: function()
		{
			var self = this;
			var valid = false;
			pjQ.$('.pjCbsRoomRadio').each(function(){
				if(pjQ.$(this).is(':checked'))
				{
					valid = true;
				}
			});
			var $pjCcServiceErrorMsg = pjQ.$('.pjCcServiceErrorMsg');
			if(valid == false)
			{
				$pjCcServiceErrorMsg.stop(true, true).show('slow');
			}else{
				$pjCcServiceErrorMsg.stop(true, true).hide('slow');
			}
			return valid;
		},
		validateDateTime: function()
		{
			var self = this;
			var valid = false;
			var valid_often = false;
			var valid_date = false;
			pjQ.$('.pjCbsRoomRadio').each(function(){
				if(pjQ.$(this).is(':checked'))
				{
					valid_often = true;
				}
			});
			if(pjQ.$('#pjCbsDate_' + self.opts.index).val() != '')
			{
				valid_date = true;
			}
			var $pjCcHowOftenErrorMsg = pjQ.$('.pjCcHowOftenErrorMsg');
			var $pjCcDateErrorMsg = pjQ.$('.pjCcDateErrorMsg');
			if(valid_often == false)
			{
				$pjCcHowOftenErrorMsg.stop(true, true).show('slow');
			}else{
				$pjCcHowOftenErrorMsg.stop(true, true).hide('slow');
			}
			if(valid_date == false)
			{
				$pjCcDateErrorMsg.stop(true, true).show('slow');
			}else{
				$pjCcDateErrorMsg.stop(true, true).hide('slow');
			}
			if(valid_often == true && valid_date == true)
			{
				valid = true;
			}
			return valid;
		},
		addServices: function(){
			var self = this;
			var ajax_url = [self.opts.folder, "index.php?controller=pjFront&action=pjActionAddServices"].join("");
			if(self.opts.session_id != '')
			{
				ajax_url = [self.opts.folder, "index.php?controller=pjFront&action=pjActionAddServices", "&session_id=", self.opts.session_id].join("");
			}
			self.disableButtons.call(self);
			var $form = pjQ.$('#frmServicesForm_'+ self.opts.index);
			pjQ.$.post(ajax_url, $form.serialize()).done(function (data) {
				pjQ.$('#pjCbsYourBooking_' + self.opts.index).html(data);
				self.enableButtons.call(self);
			}).fail(function () {
				self.enableButtons.call(self);
			});
		},
		addDateTime: function(){
			var self = this;
			var ajax_url = [self.opts.folder, "index.php?controller=pjFront&action=pjActionAddDateTime"].join("");
			if(self.opts.session_id != '')
			{
				ajax_url = [self.opts.folder, "index.php?controller=pjFront&action=pjActionAddDateTime", "&session_id=", self.opts.session_id].join("");
			}
			self.disableButtons.call(self);
			var $form = pjQ.$('#frmDateTimeForm_'+ self.opts.index);
			pjQ.$.post(ajax_url, $form.serialize()).done(function (data) {
				pjQ.$('#pjCbsYourBooking_' + self.opts.index).html(data);
				self.enableButtons.call(self);
			}).fail(function () {
				self.enableButtons.call(self);
			});
		},
		loadServices: function () {
			var self = this,
				index = this.opts.index,
				params = {};
			if(self.opts.session_id != '')
			{
				params.session_id = self.opts.session_id;
			}
			params.locale = self.opts.locale;
			params.index = self.opts.index;
			
			pjQ.$.get([this.opts.folder, "index.php?controller=pjFront&action=pjActionServices"].join(""), params).done(function (data) {
				self.$container.html(data);
				self.bindServices.call(self);
			}).fail(function () {
				
			});
		},
		bindServices: function(){
			var self = this,
				index = this.opts.index;
		
			pjQ.$('.modal-dialog').css("z-index", "9999"); 
			
			if (validate) 
			{
				var $form = pjQ.$('#frmServicesForm_'+ self.opts.index);
				$form.validate({
					onkeyup: false,
					errorElement: 'li',
					submitHandler: function (form) {
						if(self.validateServices.call(self) == true)
						{
							self.disableButtons.call(self);
							if (!hashBang("#!/loadDateTime")) 
							{
								self.loadDateTime.call(self);
							}
						}
						return false;
					}
				});
			}
			
			if (pjQ.$('.pjCcCustomRadio, .pjCcCustomCheckbox').length) {
				var checkedClass = 'pjCcCustomInputChecked';
				var inputSelector = '.pjCcCustomCheckbox input, .pjCcCustomRadio input';

				pjQ.$(inputSelector).each(function() {
					var input = this;

					pjQ.$(input).parent().toggleClass(checkedClass, input.checked);
				});
			};
		},
		loadDateTime: function () {
			var self = this,
				index = this.opts.index,
				params = {};
			if(self.opts.session_id != '')
			{
				params.session_id = self.opts.session_id;
			}
			params.locale = self.opts.locale;
			params.index = self.opts.index;
			
			pjQ.$.get([this.opts.folder, "index.php?controller=pjFront&action=pjActionDateTime"].join(""), params).done(function (data) {
				if (data.code != undefined && data.status == 'ERR') {
					if (!hashBang("#!/loadServices")) 
					{
						self.loadServices.call(self);
					}
				}else{
					self.$container.html(data);
					self.bindDateTime.call(self);
				}
			}).fail(function () {
				
			});
		},
		bindDateTime: function(){
			var self = this,
				index = this.opts.index;
		
			if (validate) 
			{
				var $form = pjQ.$('#frmDateTimeForm_'+ self.opts.index);
				$form.validate({
					onkeyup: false,
					errorElement: 'li',
					submitHandler: function (form) {
						if(self.validateDateTime.call(self) == true)
						{
							self.disableButtons.call(self);
							if (!hashBang("#!/loadCheckout")) 
							{
								self.loadCheckout.call(self);
							}
						}
						return false;
					}
				});
			}
			if (pjQ.$('.pjCcCustomRadio, .pjCcCustomCheckbox').length) {
				var checkedClass = 'pjCcCustomInputChecked';
				var inputSelector = '.pjCcCustomCheckbox input, .pjCcCustomRadio input';

				pjQ.$(inputSelector).each(function() {
					var input = this;

					pjQ.$(input).parent().toggleClass(checkedClass, input.checked);
				});
			};
			if (pjQ.$('.pjCcDatePicker').length) 
			{
				moment.locale('en', {
					week: { dow: self.opts.week_start },
					months : pjQ.$('#pjCbsCalendarLocale').data('months').split("_"),
			        weekdaysMin : pjQ.$('#pjCbsCalendarLocale').data('days').split("_")
				});
				var currentDate = new Date();
				
				pjQ.$('.pjCcDatePicker').datetimepicker({
					format: self.opts.momentDateFormat.toUpperCase(),
					locale: moment.locale('en'),
					allowInputToggle: true,
					minDate: new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate() + self.opts.days_before),
					ignoreReadonly: true,
					useCurrent: true
				});
				pjQ.$('.pjCcDatePicker').on('dp.change', function(e) {
					self.addDateTime.call(self);
					self.validateDateTime.call(self);
				});
			}
		},
		loadCheckout: function () {
			var self = this,
				index = this.opts.index,
				params = {};

			if(self.opts.session_id != '')
			{
				params.session_id = self.opts.session_id;
			}
			params.locale = self.opts.locale;
			params.index = self.opts.index;
			
			pjQ.$.get([this.opts.folder, "index.php?controller=pjFront&action=pjActionCheckout"].join(""), params).done(function (data) {
				if (data.code != undefined && data.status == 'ERR') {
					if (!hashBang("#!/loadServices")) 
					{
						self.loadServices.call(self);
					}
				}else{
					self.$container.html(data);
					self.bindCheckout.call(self);
				}
			}).fail(function () {
				
			});
		},
		bindCheckout: function(){
			var self = this,
				index = this.opts.index;
		
			pjQ.$('.modal-dialog').css("z-index", "9999"); 
			
			if (pjQ.$('.pjCcCustomRadio, .pjCcCustomCheckbox').length) {
				var checkedClass = 'pjCcCustomInputChecked';
				var inputSelector = '.pjCcCustomCheckbox input, .pjCcCustomRadio input';

				pjQ.$(inputSelector).each(function() {
					var input = this;

					pjQ.$(input).parent().toggleClass(checkedClass, input.checked);
				});
			};
			if (validate) 
			{
				var captcha_url = self.opts.folder + "index.php?controller=pjFront&action=pjActionCheckCaptcha";
				if(self.opts.session_id != '')
				{
					captcha_url = self.opts.folder + "index.php?controller=pjFront&action=pjActionCheckCaptcha&session_id=" + self.opts.session_id;
				}
				var $form = pjQ.$('#pjCbsCheckoutForm_'+ self.opts.index);
				$form.validate({
					rules: {
						"captcha": {
							remote: captcha_url
						}
					},
					onkeyup: false,
					errorElement: 'li',
					errorPlacement: function (error, element) {
						if(element.attr('name') == 'terms')
						{
							error.appendTo(element.parent().next().find('ul'));
						}else{
							error.appendTo(element.next().find('ul'));
						}
					},
		            highlight: function(ele, errorClass, validClass) {
		            	var element = pjQ.$(ele);
		            	if(element.attr('name') == 'terms')
						{
							element.parent().parent().removeClass('has-success').addClass('has-error');
						}else{
							element.parent().removeClass('has-success').addClass('has-error');
						}
		            },
		            unhighlight: function(ele, errorClass, validClass) {
		            	var element = pjQ.$(ele);
		            	if(element.attr('name') == 'terms')
						{
							element.parent().parent().removeClass('has-error').addClass('has-success');
						}else{
							element.parent().removeClass('has-error').addClass('has-success');
						}
		            },
					submitHandler: function (form) {
						self.disableButtons.call(self);
						var $form = pjQ.$(form);
						var ajax_url = [self.opts.folder, "index.php?controller=pjFront&action=pjActionCheckout"].join("");
						if(self.opts.session_id != '')
						{
							ajax_url += "&session_id=" + self.opts.session_id
						}
						pjQ.$.post(ajax_url, $form.serialize()).done(function (data) {
							if (data.status == "OK") {
								if (!hashBang("#!/loadPreview")) 
								{
									self.loadPreview.call(self);
								}
							}
						}).fail(function () {
							self.enableButtons.call(self);
						});
						return false;
					}
				});
			}
		},
		loadPreview: function () {
			var self = this,
				index = this.opts.index,
				params = { 
							"locale": this.opts.locale,
							"index": this.opts.index
						 };

			if(self.opts.session_id != '')
			{
				params.session_id = self.opts.session_id;
			}
			pjQ.$.get([this.opts.folder, "index.php?controller=pjFront&action=pjActionPreview", "&session_id=", self.opts.session_id].join(""), params).done(function (data) {
				if (data.code != undefined && data.status == 'ERR') {
					if (!hashBang("#!/loadSearch")) 
					{
						self.loadSearch.call(self);
					}
				}else{
					self.$container.html(data);
					self.bindPreview.call(self);
				}
			}).fail(function () {
				
			});
		},
		bindPreview: function(){
			var self = this,
				index = this.opts.index;
		
			if (pjQ.$('.pjCcCustomRadio, .pjCcCustomCheckbox').length) {
				var checkedClass = 'pjCcCustomInputChecked';
				var inputSelector = '.pjCcCustomCheckbox input, .pjCcCustomRadio input';

				pjQ.$(inputSelector).each(function() {
					var input = this;

					pjQ.$(input).parent().toggleClass(checkedClass, input.checked);
				});
			};
			if (validate) 
			{
				var $form = pjQ.$('#pjCbsPreviewForm_'+ self.opts.index);
				$form.validate({
					submitHandler: function (form) {
						self.disableButtons.call(self);
						var $form = pjQ.$(form);
						var ajax_url = [self.opts.folder, "index.php?controller=pjFront&action=pjActionSaveEnquiry"].join("");
						if(self.opts.session_id != '')
						{
							ajax_url += '&session_id=' + self.opts.session_id;
						}
						pjQ.$.post(ajax_url, $form.serialize()).done(function (data) {
							if (data.code == "200") {
								self.getPaymentForm.call(self, data);
							} else if (data.code == "119") {
								self.enableButtons.call(self);
							}
						}).fail(function () {
							self.enableButtons.call(self);
						});
						return false;
						return false;
					}
				});
			}
		},
		getPaymentForm: function(obj){
			var self = this,
				index = this.opts.index;
			var	params = { 
					"locale": this.opts.locale,
					"index": this.opts.index,
					"enquiry_id": obj.enquiry_id, 
					"payment_method": obj.payment,
				 };
			if(self.opts.session_id != '')
			{
				params.session_id = self.opts.session_id;
			}
			pjQ.$.get([this.opts.folder, "index.php?controller=pjFront&action=pjActionGetPaymentForm"].join(""), params).done(function (data) {
				self.$container.html(data);
				switch (obj.payment) {
					case 'paypal':
						self.$container.find("form[name='cbsPaypal']").trigger('submit');
						break;
					case 'authorize':
						self.$container.find("form[name='cbsAuthorize']").trigger('submit');
						break;
					case 'creditcard':
					case 'bank':
					case 'cash':
						break;
				}
			}).fail(function () {
				log("Deferred is rejected");
			});
		}
	};
	
	window.CleaningBusiness = CleaningBusiness;	
})(window);