/*!
 * Equipment Rent v1.0
 * https://phpjabbers.com/equipment-rent/
 * 
 * Copyright 2013, StivaSoft Ltd.
 * 
 * Date: Tue Aug 13 10:31:05 2013 +0300
 */
(function (window, undefined){
	"use strict";
	pjQ.$.ajaxSetup({
		xhrFields: {
			withCredentials: true
		}
	});
	var document = window.document,
		validate = (pjQ.$.fn.validate !== undefined),
		datepicker = (pjQ.$.fn.datepicker !== undefined),
		dialog = (pjQ.$.fn.dialog !== undefined),
		spinner = (pjQ.$.fn.spinner !== undefined),
		$dialogTerms,
		routes = [
		    {pattern: /^#!\/Booking\/([A-Z]{2}\d{10})$/, eventName: "loadBooking"},
		    {pattern: /^#!\/Cart$/, eventName: "loadCart"},
		    {pattern: /^#!\/Checkout$/, eventName: "loadCheckout"},
		    {pattern: /^#!\/Item\/(\d+)$/, eventName: "loadItem"},
		    {pattern: /^#!\/Item\/.*-(\d+)\.html$/, eventName: "loadItem"},
		    {pattern: /^#!\/Items$/, eventName: "loadItems"},
		    {pattern: /^#!\/Items\/date_from:([\d\-\.\/]+)?\/hour_from:(\d+)?\/minute_from:(\d+)?\/date_to:([\d\-\.\/]+)?\/hour_to:(\d+)?\/minute_to:(\d+)?\/category:(\d+)?\/page:(\d+)?$/, eventName: "loadItems"},
		    {pattern: /^#!\/Preview$/, eventName: "loadPreview"},
		    {pattern: /^#!\/Package\/(\d+)$/, eventName: "loadPackage"},
		    {pattern: /^#!\/Package\/.*-(\d+)\.html$/, eventName: "loadPackage"},
		    {pattern: /^#!\/Packages$/, eventName: "loadPackages"},
		    {pattern: /^#!\/Packages\/date_from:([\d\-\.\/]+)?\/hour_from:(\w+)?\/minute_from:(\w+)?\/date_to:([\d\-\.\/]+)?\/hour_to:(\w+)?\/minute_to:(\w+)?\/page:(\d+)?$/, eventName: "loadPackages"}
		];
	
	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 = unescape(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("loadItems");
		}
	}
	
	pjQ.$(window).on("hashchange", function (e) {
    	onHashChange.call(null);
    });
	
	function EquipmentRent(options) {
		if (!(this instanceof EquipmentRent)) {
			return new EquipmentRent(options);
		}
				
		this.reset.call(this);
		this.init.call(this, options);
		
		return this;
	}
	
	EquipmentRent.prototype = {
		_daysOff: function (date) {
			var isDateOff = this._datesOff(date),
				isDateOn = this._datesOn(date);
			if (isDateOff[0] && !isDateOn[0]) {
				for (var i = 0, iCnt = this.options.daysOff.length; i < iCnt; i++) {
					if (this.options.daysOff[i] === date.getDay()) {
						return [false];
					}
				}
				return [true];
			} else {
				return isDateOff[0] ? isDateOff: isDateOn;
			}
		},
		_datesOff: function (date) {
			var d, i, iCnt, dt;
			for (i = 0, iCnt = this.options.datesOff.length; i < iCnt; i++) {
				dt = this.options.datesOff[i].split("-");
				d = new Date(parseInt(dt[0], 10), parseInt(dt[1], 10) - 1, parseInt(dt[2], 10));
				if (d.getTime() === date.getTime()) {
					return [false];
				}
			}
			return [true];
		},
		_datesOn: function (date) {
			var d, i, iCnt, dt;
			for (i = 0, iCnt = this.options.datesOn.length; i < iCnt; i++) {
				dt = this.options.datesOn[i].split("-");
				d = new Date(parseInt(dt[0], 10), parseInt(dt[1], 10) - 1, parseInt(dt[2], 10));
				if (d.getTime() === date.getTime()) {
					return [true];
				}
			}
			return [false];
		},
		reset: function () {
			this.$container = null;
			this.container = null;
			this.filter = null;
			this.page = 1;
			this.category_id = null;
			this.date_from = null;
			this.date_to = null;
			this.hour_from = null;
			this.hour_to = null;
			this.minute_from = null;
			this.minute_to = null;
			this.item_id = null;
			this.package_id = null;
			this.booking_uuid = null;
			this.options = {};
			
			return this;
		},
		disableButtons: function () {
			this.$container.find(".erSelectorButton").attr("disabled", "disabled");
		},
		enableButtons: function () {
			this.$container.find(".erSelectorButton").removeAttr("disabled");
		},
		addToCart: function (qs) {
			var self = this;
			this.disableButtons.call(this);
			pjQ.$.post([this.options.folder, "index.php?controller=pjFrontEnd&action=pjActionAddToCart"].join(""), qs).done(function (data) {
				hashBang("#!/Cart");
			}).fail(function () {
				self.enableButtons.call(self);
			});
		},
		removeFromCart: function (id, type) {
			var self = this;
			this.disableButtons.call(this);
			pjQ.$.post([this.options.folder, "index.php?controller=pjFrontEnd&action=pjActionRemoveFromCart"].join(""), {
				"id": id,
				"type": type
			}).done(function (data) {
				self.loadCart.call(self);
			}).fail(function () {
				self.enableButtons.call(self);
			});
		},
		emptyCart: function () {
			var self = this;
			this.disableButtons.call(this);
			pjQ.$.post([this.options.folder, "index.php?controller=pjFrontEnd&action=pjActionEmptyCart"].join("")).done(function (data) {
				self.loadCart.call(self);
			}).fail(function () {
				self.enableButtons.call(self);
			});
		},
		updateCart: function () {
			var self = this;
			this.disableButtons.call(this);
			pjQ.$.post([this.options.folder, "index.php?controller=pjFrontEnd&action=pjActionUpdateCart"].join(""), 
					this.$container.find("select[name^='qty['], input[name='forth'], input[name='back']").serialize()).done(function (data) {
				self.loadCart.call(self);
			}).fail(function () {
				self.enableButtons.call(self);
			});
		},
		clearDateTime: function (type) {
			this.date_from = null;
			this.date_to = null;
			this.hour_from = null;
			this.hour_to = null;
			this.minute_from = null;
			this.minute_to = null;
			if (type == "items") {
				this.$container.find(".erSelectorItems").eq(0).trigger("click");
			} else {
				this.$container.find(".erSelectorPackages").eq(0).trigger("click");
			}
			
			return this;
		},
		onLoadForm: function (selector) {
			var $form = this.$container.find(selector);
			if ($form.length > 0) {
				this.filter = $form.find(":input[name$='_from'], :input[name$='_to']").serialize();
			}
			
			$form.validate({
				rules: {
					hour_from: "required",
					hour_to: "required",
					minute_from: "required",
					minute_to: "required"
				}
			});
			
			return this;
		},
		onSubmitFilterForm: function (form) {
			var i, iCnt,
				obj = {},
				a = pjQ.$(form).serializeArray();
			for (i = 0, iCnt = a.length; i < iCnt; i++) {
				obj[a[i].name] = a[i].value;
			}
			if (!hashBang([
				      "#!/", (obj.filter === "items" ? "Items" : "Packages"),
				      "/date_from:", encodeURIComponent(obj.date_from),
			          "/hour_from:", encodeURIComponent(obj.hour_from),
			          "/minute_from:", encodeURIComponent(obj.minute_from),
			          "/date_to:", encodeURIComponent(obj.date_to),
			          "/hour_to:", encodeURIComponent(obj.hour_to),
			          "/minute_to:", encodeURIComponent(obj.minute_to),
			          (obj.filter === "items" ? "/category:" + (self.category_id && self.category_id !== undefined ? encodeURIComponent(self.category_id) : "") : ""),
			          "/page:1"
			    ].join(""))) {
				log("Window location hash have the same value.");
			}

			return this;
		},
		onSubmitAvailabilityForm: function (form, filter) {
			var self = this,
				$form = pjQ.$(form),
				i, iCnt,
				obj = {},
				a = $form.serializeArray();
			for (i = 0, iCnt = a.length; i < iCnt; i++) {
				obj[a[i].name] = a[i].value;
			}
			this.date_from = obj.date_from;
			this.date_to = obj.date_to;
			this.hour_from = obj.hour_from;
			this.hour_to = obj.hour_to;
			this.minute_from = obj.minute_from;
			this.minute_to = obj.minute_to;
			if (this.date_from === undefined || this.date_to === undefined || this.hour_from === undefined || this.hour_to === undefined || this.minute_from === undefined || this.minute_to === undefined) {
				
				pjQ.$('.modal-dialog').css("z-index", "9999"); 
				pjQ.$('#pjErWrongPeriodModal').modal('show');
				
				return false;
			}
			var ajax_url = [this.options.folder, "index.php?controller=pjFrontEnd&action=pjActionCheckAvailability"].join("");
			if(self.options.session_id != "")
			{
				ajax_url = [this.options.folder, "index.php?controller=pjFrontEnd&action=pjActionCheckAvailability", "&session_id=", self.options.session_id].join("");
			}
			pjQ.$.post(ajax_url, $form.serialize()).done(function (data) {
				$form.hide();
				self.$container.find(".erSelectorAvailabilityBox").html(data).show();
				if (filter !== undefined) {
					if ($form.find("input[name='item_id']").length > 0) {
						self.loadItem.call(self);
					} else {
						self.loadPackage.call(self);
					}
				}
			}).fail(function () {
				log("Deferred is rejected");
			});
			
			return this;
		},
		init: function (opts) {
			var self = this;
			this.options = opts;
			
			this.container = document.getElementById("erContainer_" + this.options.index);
			this.$container = pjQ.$(this.container);
			
			pjQ.$("html").attr('dir',self.options.direction);
			
			this.$container.on("click.er", ".pjErSelectorLocale", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var locale = pjQ.$(this).data("id");
				var dir = pjQ.$(this).data("dir");
				self.options.direction = dir;
				self.options.locale = locale;
				pjQ.$(this).addClass("erLocaleFocus").parent().parent().find("a.erSelectorLocale").not(this).removeClass("erLocaleFocus");
				
				var ajax_url = [self.options.folder, "index.php?controller=pjFront&action=pjActionLocale"].join("");
				if(self.options.session_id != "")
				{
					ajax_url = [self.options.folder, "index.php?controller=pjFront&action=pjActionLocale", "&session_id=", self.options.session_id].join("");
				}
				pjQ.$.get(ajax_url, {
					"locale_id": locale
				}).done(function (data) {
					pjQ.$("html").attr('dir',dir);
					if(!hashBang(["#!/Items/date_from:", (self.date_from && self.date_from !== undefined ? encodeURIComponent(self.date_from) : ""),
					          "/hour_from:", (self.hour_from && self.hour_from !== undefined ? encodeURIComponent(self.hour_from) : ""),
					          "/minute_from:", (self.minute_from && self.minute_from !== undefined ? encodeURIComponent(self.minute_from) : ""),
					          "/date_to:", (self.date_to && self.date_to !== undefined ? encodeURIComponent(self.date_to) : ""),
					          "/hour_to:", (self.hour_to && self.hour_to !== undefined ? encodeURIComponent(self.hour_to) : ""),
					          "/minute_to:", (self.minute_to && self.minute_to !== undefined ? encodeURIComponent(self.minute_to) : ""),
					          "/category:", (self.category_id && self.category_id !== undefined ? encodeURIComponent(self.category_id) : ""),
					          "/page:", (self.page && self.page !== undefined ? encodeURIComponent(self.page) : 1)].join("")))
					{
						self.loadItems.call(self);
					}
				}).fail(function () {
					log("Deferred is rejected");
				});
				return false;
			}).on("click.er", ".erSelectorItem", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var item_id = pjQ.$(this).data("id");
				var slug = pjQ.$(this).data("slug");
				if(slug != '')
				{
					hashBang("#!/Item/" + slug);
				}else{
					hashBang("#!/Item/" + encodeURIComponent(item_id));
				}
				return false;
			}).on("click.er", ".erSelectorItems", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				hashBang(["#!/Items/date_from:", (self.date_from && self.date_from !== undefined ? encodeURIComponent(self.date_from) : ""),
				          "/hour_from:", (self.hour_from && self.hour_from !== undefined ? encodeURIComponent(self.hour_from) : ""),
				          "/minute_from:", (self.minute_from && self.minute_from !== undefined ? encodeURIComponent(self.minute_from) : ""),
				          "/date_to:", (self.date_to && self.date_to !== undefined ? encodeURIComponent(self.date_to) : ""),
				          "/hour_to:", (self.hour_to && self.hour_to !== undefined ? encodeURIComponent(self.hour_to) : ""),
				          "/minute_to:", (self.minute_to && self.minute_to !== undefined ? encodeURIComponent(self.minute_to) : ""),
				          "/category:", (self.category_id && self.category_id !== undefined ? encodeURIComponent(self.category_id) : ""),
				          "/page:", (self.page && self.page !== undefined ? encodeURIComponent(self.page) : 1)].join(""));
				return false;
			}).on("click.er", ".erSelectorItemsPage", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var page = pjQ.$(this).data("page");
				hashBang(["#!/Items/date_from:", (self.date_from && self.date_from !== undefined ? encodeURIComponent(self.date_from) : ""),
				          "/hour_from:", (self.hour_from && self.hour_from !== undefined ? encodeURIComponent(self.hour_from) : ""),
				          "/minute_from:", (self.minute_from && self.minute_from !== undefined ? encodeURIComponent(self.minute_from) : ""),
				          "/date_to:", (self.date_to && self.date_to !== undefined ? encodeURIComponent(self.date_to) : ""),
				          "/hour_to:", (self.hour_to && self.hour_to !== undefined ? encodeURIComponent(self.hour_to) : ""),
				          "/minute_to:", (self.minute_to && self.minute_to !== undefined ? encodeURIComponent(self.minute_to) : ""),
				          "/category:", (self.category_id && self.category_id !== undefined ? encodeURIComponent(self.category_id) : ""), 
				          "/page:", (page && page !== undefined ? encodeURIComponent(page) : 1)].join(""));
				return false;
			}).on("click.er", ".erSelectorPackage", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var package_id = pjQ.$(this).data("id");
				var slug = pjQ.$(this).data("slug");
				if(slug != '')
				{
					hashBang("#!/Package/" + slug);
				}else{
					hashBang("#!/Package/" + encodeURIComponent(package_id));
				}
				return false;
			}).on("click.er", ".erSelectorPackages", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				hashBang(["#!/Packages/date_from:", (self.date_from && self.date_from !== undefined ? encodeURIComponent(self.date_from) : ""),
				          "/hour_from:", (self.hour_from && self.hour_from !== undefined ? encodeURIComponent(self.hour_from) : ""),
				          "/minute_from:", (self.minute_from && self.minute_from !== undefined ? encodeURIComponent(self.minute_from) : ""),
				          "/date_to:", (self.date_to && self.date_to !== undefined ? encodeURIComponent(self.date_to) : ""),
				          "/hour_to:", (self.hour_to && self.hour_to !== undefined ? encodeURIComponent(self.hour_to) : ""),
				          "/minute_to:", (self.minute_to && self.minute_to !== undefined ? encodeURIComponent(self.minute_to) : ""),
				          "/page:", (self.page && self.page !== undefined ? encodeURIComponent(self.page) : 1)].join(""));
				return false;
			}).on("click.er", ".erSelectorPackagesPage", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var page = pjQ.$(this).data("page");
				hashBang(["#!/Packages/date_from:", (self.date_from && self.date_from !== undefined ? encodeURIComponent(self.date_from) : ""),
				          "/hour_from:", (self.hour_from && self.hour_from !== undefined ? encodeURIComponent(self.hour_from) : ""),
				          "/minute_from:", (self.minute_from && self.minute_from !== undefined ? encodeURIComponent(self.minute_from) : ""),
				          "/date_to:", (self.date_to && self.date_to !== undefined ? encodeURIComponent(self.date_to) : ""),
				          "/hour_to:", (self.hour_to && self.hour_to !== undefined ? encodeURIComponent(self.hour_to) : ""),
				          "/minute_to:", (self.minute_to && self.minute_to !== undefined ? encodeURIComponent(self.minute_to) : ""),
				          "/page:", (page && page !== undefined ? encodeURIComponent(page) : 1)].join(""));
				return false;
			}).on("change.er", ".erSelectorCategoryId", function (e) {
				var category_id = pjQ.$("option:selected", this).val();
				hashBang([
				      "#!/Items/date_from:", (self.date_from && self.date_from !== undefined ? encodeURIComponent(self.date_from) : ""),
			          "/hour_from:", (self.hour_from && self.hour_from !== undefined ? encodeURIComponent(self.hour_from) : ""),
			          "/minute_from:", (self.minute_from && self.minute_from !== undefined ? encodeURIComponent(self.minute_from) : ""),
			          "/date_to:", (self.date_to && self.date_to !== undefined ? encodeURIComponent(self.date_to) : ""),
			          "/hour_to:", (self.hour_to && self.hour_to !== undefined ? encodeURIComponent(self.hour_to) : ""),
			          "/minute_to:", (self.minute_to && self.minute_to !== undefined ? encodeURIComponent(self.minute_to) : ""),
			          "/category:", encodeURIComponent(category_id), 
			          "/page:1"
			    ].join(""));
			
			}).on("click.er", ".erSelectorClearDateTime", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var $this = pjQ.$(this),
					type = $this.data("type"),
					basket = $this.data("basket");

				if (parseInt(basket, 10) > 0) {
					
					pjQ.$('#pjErClearTimeModal').find('.modal-body').html(self.options.fields.clear_body);
					pjQ.$('.pjErClearTimeConfirm').attr('data-type', type);
					pjQ.$('.modal-dialog').css("z-index", "9999"); 
					pjQ.$('#pjErClearTimeModal').modal('show');
					
					pjQ.$('.pjErClearTimeConfirm').unbind().click(function(e){
						pjQ.$('#pjErClearTimeModal').modal('hide');
						pjQ.$('#pjErWrongPeriodModal').modal('hide');
						self.clearDateTime.call(self, type);
					});
					
					return false;
				}
				
				self.clearDateTime.call(self, type);
				return false;
				
			}).on("change.er", "select[name^='hour_']", function (e) {
				
				self.onChangeHour.call(self, this);
			}).on("change.er", "select[name='minute_from']", function (e) {
				
				self.validateMinute.call(self);
			}).on("click.er", ".erSelectorSearchToggle", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var $this = pjQ.$(this),
					$sWrapper = self.$container.find(".erSelectorSearchWrapper")
				if ($sWrapper.is(":visible")) {
					$this.removeClass("erPaginatorFocus");
					$sWrapper.slideUp();
				} else {
					$this.addClass("erPaginatorFocus");
					$sWrapper.slideDown();
				}
				return false;
				
			}).on("submit.er", ".erSelectorBuyNowForm", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				self.addToCart.call(self, pjQ.$(this).serialize());
				return false;
			}).on("click.er", ".erSelectorItemThumb", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var $this = pjQ.$(this),
					src = $this.data("src");
				if (src !== undefined && src.length > 0) {
					$this.parent().parent().prev().find(".erSelectorItemPic").attr("src", src);
				}
				return false;
			}).on("click.er", ".erSelectorCart", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				hashBang("#!/Cart");
				return false;
			}).on("click", ".pjErBtnCalendarTrigger", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var $dp = pjQ.$(this).siblings("input[type='text']");
				if ($dp.hasClass("hasDatepicker")) {
					$dp.datepicker("show");
				} else {
					$dp.trigger("focusin").datepicker("show");
				}
			}).on("focusin.er", ".erSelectorDatepick", function () {
				if (datepicker) {
					var $this = pjQ.$(this),
						dOpts = {
							dateFormat: $this.data("dformat"),
							firstDay: $this.data("fday"),
							minDate: 0,
							constrainInput: true
						};
					$this.datepicker(pjQ.$.extend(dOpts, {
						beforeShow: function (input, ui) {
							var dt,
								$chain,
								name = ui.input.attr("name");
							
							if (name == "date_from") {
								$chain = ui.input.closest("form").find("input[name='date_to']");
								dt = $chain.datepicker(dOpts).datepicker("getDate");
								if (dt != null) {
									
								}
							} else if (name == "date_to") {
								$chain = ui.input.closest("form").find("input[name='date_from']");
								dt = $chain.datepicker(dOpts).datepicker("getDate");
								if (dt != null) {
									ui.input.datepicker("option", "minDate", $chain.val());
								}
							}
							pjQ.$('#ui-datepicker-div').addClass("pjErjQueryUI");
						},
						beforeShowDay: function (date) {
							return self._daysOff.call(self, date);
						},
						onSelect: function (dateText, ui) {
							var dt, $chain,
								selectedDate = ui.input.datepicker(dOpts).datepicker("getDate"),
								name = ui.input.attr("name"),
								iso = [ui.selectedYear, ((ui.selectedMonth + 1).toString().length === 1 ? "0" + (ui.selectedMonth + 1): ui.selectedMonth + 1), (ui.selectedDay.toString().length === 1 ? "0" + ui.selectedDay : ui.selectedDay)].join("-");

							if (name == "date_from") {
								$chain = ui.input.closest("form").find("input[name='date_to']");
								dt = $chain.datepicker(dOpts).datepicker("getDate");
								if (selectedDate > dt) {
									$chain.datepicker("option", "minDate", dateText);
									self.onChangeDate.call(self, $chain, iso);
								}
							}
							self.onChangeDate.call(self, ui.input, iso);
						}
					}));
				}
			}).on("submit.er", ".erSelectorAvailabilityForm", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				
				var form = this,
					$form = pjQ.$(form),
					filter = $form.find(":input[name$='_from'], :input[name$='_to']").serialize(),
					basket = $form.data("basket");

				if (parseInt(basket, 10) > 0 && filter !== self.filter) {
					
					pjQ.$('#pjErClearTimeModal').find('.modal-body').html(self.options.fields.clear_body);
					pjQ.$('.modal-dialog').css("z-index", "9999"); 
					pjQ.$('#pjErClearTimeModal').modal('show');
					pjQ.$('.pjErClearTimeConfirm').unbind().click(function(e){
						pjQ.$('#pjErClearTimeModal').modal('hide');
						pjQ.$('#pjErWrongPeriodModal').modal('hide');
						self.onSubmitAvailabilityForm.call(self, form, filter);
					});

					return false;
				}
				
				self.onSubmitAvailabilityForm.call(self, form);
				return false;
			}).on("click.er", ".erSelectorChangeDates", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var $this = pjQ.$(this);
				$this.closest(".erSelectorAvailabilityBox").hide();
				self.$container.find(".erSelectorAvailabilityForm").show();
				return false;
			}).on("submit.er", ".erSelectorFilterForm", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var form = this,
					$form = pjQ.$(form),
					filter = $form.find(":input[name$='_from'], :input[name$='_to']").serialize(),
					basket = $form.data("basket");
				
				if (parseInt(basket, 10) > 0 && filter !== self.filter) {
					pjQ.$('#pjErClearTimeModal').find('.modal-body').html(self.options.fields.clear_body);
					pjQ.$('.modal-dialog').css("z-index", "9999"); 
					pjQ.$('#pjErClearTimeModal').modal('show');
					
					pjQ.$('.pjErClearTimeConfirm').unbind().click(function(e){
						pjQ.$('#pjErClearTimeModal').modal('hide');
						pjQ.$('#pjErWrongPeriodModal').modal('hide');
						self.onSubmitFilterForm.call(self, form);
					});
					return false;
				}
				
				self.onSubmitFilterForm.call(self, form);
				return false;
				
			// Cart (Basket)
			}).on("click.er", ".erSelectorContinueShopping", function (e) {
				hashBang(["#!/Items/date_from:", (self.date_from && self.date_from !== undefined ? encodeURIComponent(self.date_from) : ""),
				          "/hour_from:", (self.hour_from && self.hour_from !== undefined ? encodeURIComponent(self.hour_from) : ""),
				          "/minute_from:", (self.minute_from && self.minute_from !== undefined ? encodeURIComponent(self.minute_from) : ""),
				          "/date_to:", (self.date_to && self.date_to !== undefined ? encodeURIComponent(self.date_to) : ""),
				          "/hour_to:", (self.hour_to && self.hour_to !== undefined ? encodeURIComponent(self.hour_to) : ""),
				          "/minute_to:", (self.minute_to && self.minute_to !== undefined ? encodeURIComponent(self.minute_to) : ""),
				          "/category:", (self.category_id && self.category_id !== undefined ? encodeURIComponent(self.category_id) : ""),
				          "/page:", (self.page && self.page !== undefined ? encodeURIComponent(self.page) : 1)].join(""));
			}).on("change.er", "input[name='forth'], input[name='back']", function () {
				
				/*var price = parseFloat(self.$container.find("input[name='forth']:checked").data("price")) +
					parseFloat(self.$container.find("input[name='back']:checked").data("price"));
				
				self.$container.find(".erSelectorDelivery").html(price.toFixed(2));*/
				self.updateCart.call(self);
				
			}).on("change.er", ".pjErCartItems", function (e) {
				self.updateCart.call(self);
			}).on("click.er", ".erSelectorEmptyCart", function (e) {
				self.emptyCart.call(self);
			}).on("click.er", ".erSelectorUpdateCart", function (e) {
				self.updateCart.call(self);
			}).on("click.er", ".erSelectorRemoveFromCart", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var $this = pjQ.$(this);
				self.removeFromCart.call(self, $this.data("id"), $this.data("type"));
				return false;
			}).on("click.er", ".erSelectorCheckout", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				hashBang("#!/Checkout");
				return false;
			}).on("click.er", ".erSelectorPreview", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				hashBang("#!/Preview");
				return false;
			}).on("change.er", "select[name='payment_method']", function () {
				self.$container.find(".erSelectorCCard").hide();
				self.$container.find(".erSelectorBank").hide();
				switch (pjQ.$(this).find("option:selected").val()) {
				case 'creditcard':
					self.$container.find(".erSelectorCCard").show();
					break;
				case 'bank':
					self.$container.find(".erSelectorBank").show();
					break;
				}
			}).on("click.ts", ".erSelectorPayConditions", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				if ($dialogTerms.length > 0 && dialog) {
					$dialogTerms.dialog("open");
				}
				return false;
			}).on("change.er", ".pjErQtySelector", function () {
				var $form = pjQ.$(this).closest('form');
				var ajax_url = [self.options.folder, "index.php?controller=pjFrontEnd&action=pjActionUpdatePrice"].join("");
				if(self.options.session_id != "")
				{
					ajax_url = [self.options.folder, "index.php?controller=pjFrontEnd&action=pjActionUpdatePrice", "&session_id=", self.options.session_id].join("");
				}
				pjQ.$.post(ajax_url, $form.serialize()).done(function (data) {
					pjQ.$('#pjErTotalPriceLabel').html(data.price);
				}).fail(function () {
					self.enableButtons.call(self);
				});
			}).on("click.er", "#pjErCaptchaImage_" + self.options.index, function (e) {
				var $captchaField = pjQ.$('#pjErCaptcha_' + self.options.index);
				$captchaField.val("").removeData("previousValue");
				pjQ.$(this).attr("src", pjQ.$(this).attr("src").replace(/(&rand=)\d+/g, '\$1' + Math.ceil(Math.random() * 99999)));
				return false;
			});
			
			//Custom events
			pjQ.$(window).on("loadCart", this.container, function (e) {
				self.loadCart.call(self);
			}).on("loadItem", this.container, function (e, item_id) {
				self.item_id = item_id;
				self.loadItem.call(self);
			}).on("loadItems", this.container, function (e, date_from, hour_from, minute_from, date_to, hour_to, minute_to, category_id, page) {
				self.date_from = date_from;
				self.hour_from = hour_from;
				self.minute_from = minute_from;
				self.date_to = date_to;
				self.hour_to = hour_to;
				self.minute_to = minute_to;
				self.category_id = category_id;
				self.page = page;
				self.loadItems.call(self);
			}).on("loadPackage", this.container, function (e, package_id) {
				self.package_id = package_id;
				self.loadPackage.call(self);
			}).on("loadPackages", this.container, function (e, date_from, hour_from, minute_from, date_to, hour_to, minute_to, page) {
				self.date_from = date_from;
				self.hour_from = hour_from;
				self.minute_from = minute_from;
				self.date_to = date_to;
				self.hour_to = hour_to;
				self.minute_to = minute_to;
				self.page = page;
				self.loadPackages.call(self);
			}).on("loadCheckout", this.container, function (e) {
				self.loadCheckout.call(self);
			}).on("loadPreview", this.container, function (e) {
				self.loadPreview.call(self);
			}).on("loadBooking", this.container, function (e, booking_uuid) {
				self.booking_uuid = booking_uuid;
				self.loadBooking.call(self);
			});
			
			if (window.location.hash.length === 0) {
				this.loadItems.call(this);
			} else {
				onHashChange.call(null);
			}
						
			return this;
		},
		validateHour: function()
		{
			var self = this;
			var $frm = pjQ.$('.erSelectorAvailabilityForm');
			var $date_from = $frm.find('input[name="date_from"]'),
				$hour_from = $frm.find('select[name="hour_from"]'),
				$date_to = $frm.find('input[name="date_to"]'),
				$hour_to = $frm.find('select[name="hour_to"]');
			var df = $date_from.val(),
				hf = $hour_from.val(),
				dt = $date_to.val(),
				ht = $hour_to.val();
			var today = $date_from.attr('data-today');
			if(df == dt)
			{
				if(parseInt(hf, 10) > parseInt(ht, 10))
				{
					$hour_to.val(hf);
					
					var index = $hour_to.find('option:selected').index();
					$hour_to.find('option:lt(' + index + ')').prop("disabled", true);
				    
					self.onChangeHour.call(self, $hour_to);
				}else if(parseInt(hf, 10) <= parseInt(ht, 10)){
					var tmp_val = $hour_to.find('option:selected').val();
					$hour_to.val(hf);
					var index = $hour_to.find('option:selected').index();
					$hour_to.find('option:lt(' + index + ')').prop("disabled", true);
					$hour_to.find('option:eq(' + index + ')').prop("disabled", false);
					$hour_to.find('option:gt(' + index + ')').prop("disabled", false);
					
					$hour_to.val(tmp_val);
				}
			}
		},
		validateMinute: function()
		{
			var self = this;
			var $frm = pjQ.$('.erSelectorAvailabilityForm');
			var $date_from = $frm.find('input[name="date_from"]'),
				$hour_from = $frm.find('select[name="hour_from"]'),
				$minute_from = $frm.find('select[name="minute_from"]'),
				$date_to = $frm.find('input[name="date_to"]'),
				$hour_to = $frm.find('select[name="hour_to"]'),
				$minute_to = $frm.find('select[name="minute_to"]');
			var df = $date_from.val(),
				hf = $hour_from.val(),
				mf = $minute_from.val(),
				dt = $date_to.val(),
				ht = $hour_to.val(),
				mt = $minute_to.val();
			if(df == dt)
			{
				if(parseInt(hf, 10) == parseInt(ht, 10) && parseInt(mf, 10) > parseInt(mt, 10))
				{
					$minute_to.val(mf);
					
					var index = $minute_to.find('option:selected').index();
					$minute_to.find('option:lt(' + index + ')').prop("disabled", true);
				}else if(parseInt(hf, 10) == parseInt(ht, 10) && parseInt(mf, 10) <= parseInt(mt, 10)){
					var index = $minute_to.find('option:selected').index();
					$minute_to.find('option:lt(' + index + ')').prop("disabled", true);
				}
			}
		},
		onChangeDate: function($input, iso) {
			var self = this;
			var start = /^date_from$/.test($input.attr("name"));

			$input.data("iso", iso);
			var ajax_url = [this.options.folder, "index.php?controller=pjFrontEnd&action=pjActionGetTime"].join("");
			if(self.options.session_id != "")
			{
				ajax_url = [this.options.folder, "index.php?controller=pjFrontEnd&action=pjActionGetTime", "&session_id=", self.options.session_id].join("");
			}
			pjQ.$.get(ajax_url, {
				"index": this.options.index,
				"iso_date": iso,
				"change": "date",
				"start": (start ? 1 : 0)
			}).done(function (data) {
				$input.parent().siblings(".pjErItemTime").html(data);
				if(iso == $input.attr('data-today'))
				{
					self.validateHour.call(self);
				}
			});
		},
		onChangeHour: function(el) {
			var self = this;
			var $hour = pjQ.$(el),
				selectedHour = parseInt($hour.find("option:selected").val(), 10),
				name = $hour.attr("name"),
				start = /^hour_from$/.test(name);
			
			var ajax_url = [this.options.folder, "index.php?controller=pjFrontEnd&action=pjActionGetTime"].join("");
			if(self.options.session_id != "")
			{
				ajax_url = [this.options.folder, "index.php?controller=pjFrontEnd&action=pjActionGetTime", "&session_id=", self.options.session_id].join("");
			}
			pjQ.$.get(ajax_url, {
				"index": this.options.index,
				"iso_date": $hour.closest(".erItemRow").find(".erSelectorDatepick").data("iso"),
				"change": "hour",
				"hour": selectedHour,
				"start": (start ? 1 : 0)
			}).done(function (data) {
				$hour.parent().siblings(".pjErItemMinute").html(data);
				if(start)
				{
					self.validateHour.call(self);
				}
			});
		},
		loadBooking: function () {
			var self = this;
			var ajax_url = [this.options.folder, "index.php?controller=pjFrontPublic&action=pjActionBooking"].join("");
			if(self.options.session_id != "")
			{
				ajax_url = [this.options.folder, "index.php?controller=pjFrontPublic&action=pjActionBooking", "&session_id=", self.options.session_id].join("");
			}
			pjQ.$.get(ajax_url, {
				"index": this.options.index,
				"booking_uuid": this.booking_uuid
			}).done(function (data) {
				self.$container.html(data);
				
				var $paypal = self.$container.find("form[name='erPaypal']"),
					$authorize = self.$container.find("form[name='erAuthorize']");
				
				if ($paypal.length > 0) {
					window.setTimeout(function () {
						$paypal.trigger('submit');
					}, 3000);
				} else if ($authorize.length > 0) {
					window.setTimeout(function () {
						$authorize.trigger('submit');
					}, 3000);
				}
			});
			
			return this;
		},
		loadCart: function () {
			var self = this;
			var ajax_url = [this.options.folder, "index.php?controller=pjFrontPublic&action=pjActionCart&index=", this.options.index].join("");
			if(self.options.session_id != "")
			{
				ajax_url = [this.options.folder, "index.php?controller=pjFrontPublic&action=pjActionCart&index=", this.options.index, "&session_id=", self.options.session_id].join("");
			}
			pjQ.$.get(ajax_url).done(function (data) {
				self.$container.html(data);
				self.onLoadForm.call(self, ".erSelectorFilterForm");
				
				if (spinner) {
					self.$container.find(".erSelectorSpinner").each(function(i) {
						var $this = pjQ.$(this);
						$this.spinner({
							min: 1,
							max: $this.data("max"),
							stop: function (event, ui ) {
								self.updateCart.call(self);
							}
						});
					});
				}
				
				if (validate) {
					self.$container.find(".erSelectorCartForm").validate({
						onkeyup: false,
						onclick: false,
						onfocusout: false,
						errorClass: "erError",
						validClass: "erValid",
						submitHandler: function (form) {
							self.disableButtons.call(self);
							var $form = pjQ.$(form);
							var ajax_url = [self.options.folder, "index.php?controller=pjFrontPublic&action=pjActionCart"].join("");
							if(self.options.session_id != "")
							{
								ajax_url = [self.options.folder, "index.php?controller=pjFrontPublic&action=pjActionCart", "&session_id=", self.options.session_id].join("");
							}
							pjQ.$.post(ajax_url, $form.serialize()).done(function (data) {
								if (data.status == "OK") {
									hashBang("#!/Checkout");
								} else if (data.status == "ERR") {
									self.enableButtons.call(self);
								}
							}).fail(function () {
								self.enableButtons.call(self);
							});
							return false;
						}
					});
				}
			});
		},
		loadCheckout: function () {
			var self = this;
			this.disableButtons.call(this);
			
			var ajax_url = [this.options.folder, "index.php?controller=pjFrontPublic&action=pjActionCheckout&index=", this.options.index].join("");
			if(self.options.session_id != "")
			{
				ajax_url = [this.options.folder, "index.php?controller=pjFrontPublic&action=pjActionCheckout&index=", this.options.index, "&session_id=", self.options.session_id].join("");
			}
			pjQ.$.get(ajax_url).done(function (data) {
				self.$container.html(data);
				pjQ.$('.modal-dialog').css("z-index", "9999"); 
				if (validate) {
					pjQ.jQuery.validator.addClassRules("erRequired", {
						required: true
					});
					self.$container.find(".erSelectorCheckoutForm").validate({
						rules: {
							"captcha" : {
								remote: self.options.folder + "index.php?controller=pjFrontEnd&action=pjActionCheckCaptcha",
								required: true,
								minlength: 6,
								maxlength: 6
							}
						},
						onkeyup: false,
						errorElement: 'li',
						errorPlacement: function (error, element) {
							if(element.attr('name') == 'terms' || element.attr('name') == 'captcha')
							{
								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') == 'captcha' || element.attr('name') == 'terms' )
							{
								element.parent().parent().parent().addClass('has-error');
							}else{
								element.parent().addClass('has-error');
							}
			            },
			            unhighlight: function(ele, errorClass, validClass) {
			            	var element = pjQ.$(ele);
			            	if(element.attr('name') == 'captcha' || element.attr('name') == 'terms')
							{
								element.parent().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.options.folder, "index.php?controller=pjFrontPublic&action=pjActionCheckout"].join("");
							if(self.options.session_id != "")
							{
								ajax_url = [self.options.folder, "index.php?controller=pjFrontPublic&action=pjActionCheckout", "&session_id=", self.options.session_id].join("");
							}
							pjQ.$.post(ajax_url, $form.serialize()).done(function (data) {
								if (data.status == "OK") {
									hashBang("#!/Preview");
								} else if (data.status == "ERR") {
									self.enableButtons.call(self);
								}
							}).fail(function () {
								self.enableButtons.call(self);
							});
							return false;
						}
					});
				}
				
			}).fail(function () {
				self.enableButtons.call(self);
			});
		},
		loadItem: function () {
			var self = this;
			
			var ajax_url = "index.php?controller=pjFrontPublic&action=pjActionItem";
			if(self.options.session_id != "")
			{
				ajax_url = "index.php?controller=pjFrontPublic&action=pjActionItem&session_id=" + self.options.session_id;
			}
			pjQ.$.get([self.options.folder, ajax_url, "&id=", self.item_id, 
			           "&index=", self.options.index,
			           "&date_from=", self.date_from, 
			           "&date_to=", self.date_to].join("")).done(function (data) {
				self.$container.html(data);
				self.onLoadForm.call(self, ".erSelectorFilterForm");
				self.validateHour.call(self);
				self.validateMinute.call(self);
				if (self.date_from !== null && self.date_to !== null && self.date_from !== undefined && self.date_to !== undefined) {
					pjQ.$(".erSelectorAvailabilityForm").trigger("submit");
				}
			});
		},
		loadItems: function () {
			var self = this;
			var ajax_url = [this.options.folder, "index.php?controller=pjFrontPublic&action=pjActionItems", "&index=", this.options.index].join("");
			if(self.options.session_id != "")
			{
				ajax_url = [this.options.folder, "index.php?controller=pjFrontPublic&action=pjActionItems", "&index=", this.options.index, "&session_id=", self.options.session_id].join("");
			}
			pjQ.$.get(ajax_url, {
				"date_from": this.date_from,
				"date_to": this.date_to,
				"hour_from": this.hour_from,
				"hour_to": this.hour_to,
				"minute_from": this.minute_from,
				"minute_to": this.minute_to,
				"category_id": this.category_id,
				"page": this.page
			}).done(function (data) {
				self.$container.html(data);
				self.onLoadForm.call(self, ".erSelectorFilterForm");
			});
		},
		loadPackage: function () {
			var self = this;
			var ajax_url = "index.php?controller=pjFrontPublic&action=pjActionPackage";
			if(self.options.session_id != "")
			{
				ajax_url = "index.php?controller=pjFrontPublic&action=pjActionPackage&session_id=" + self.options.session_id;
			}
			pjQ.$.get([self.options.folder, ajax_url, "&id=", self.package_id, 
			           "&index=", self.options.index,
			           "&date_from=", self.date_from, 
			           "&date_to=", self.date_to].join("")).done(function (data) {
				self.$container.html(data);
				self.onLoadForm.call(self, ".erSelectorFilterForm");
				self.validateHour.call(self);
				self.validateMinute.call(self);
				if (self.date_from !== null && self.date_to !== null && self.date_from !== undefined && self.date_to !== undefined) {
					pjQ.$(".erSelectorAvailabilityForm").trigger("submit");
				}
			});
		},
		loadPackages: function () {
			var self = this;
			var ajax_url = [this.options.folder, "index.php?controller=pjFrontPublic&action=pjActionPackages&index=", this.options.index].join("");
			if(self.options.session_id != "")
			{
				ajax_url = [this.options.folder, "index.php?controller=pjFrontPublic&action=pjActionPackages", "&index=", this.options.index, "&session_id=", self.options.session_id].join("");
			}
			pjQ.$.get(ajax_url, {
				"date_from": this.date_from,
				"date_to": this.date_to,
				"hour_from": this.hour_from,
				"hour_to": this.hour_to,
				"minute_from": this.minute_from,
				"minute_to": this.minute_to,
				"page": this.page
			}).done(function (data) {
				self.$container.html(data);
				self.onLoadForm.call(self, ".erSelectorFilterForm");
			});
		},
		loadPreview: function () {
			var self = this;
			
			var ajax_url = [this.options.folder, "index.php?controller=pjFrontPublic&action=pjActionPreview&index=", this.options.index].join("");
			var remote_url = [self.options.folder, "index.php?controller=pjFrontEnd&action=pjActionValidateCart"].join("");
			var post_url = [self.options.folder, "index.php?controller=pjFrontEnd&action=pjActionProcessOrder"].join("");
			if(self.options.session_id != "")
			{
				ajax_url = [this.options.folder, "index.php?controller=pjFrontPublic&action=pjActionPreview", "&index=", this.options.index, "&session_id=", self.options.session_id].join("");
				remote_url = [self.options.folder, "index.php?controller=pjFrontEnd&action=pjActionValidateCart", "&session_id=", self.options.session_id].join("");
				post_url = [self.options.folder, "index.php?controller=pjFrontEnd&action=pjActionProcessOrder", "&session_id=", self.options.session_id].join("");
			}
			pjQ.$.get(ajax_url).done(function (data) {
				self.$container.html(data);
				
				if (validate) {
					self.$container.find(".erSelectorPreviewForm").validate({
						rules: {
							er_validate: {
								remote: remote_url
							}
						},
						messages: {
							er_validate: {
								remote: "Some of the items in your basket is not available."
							}
						},
						onkeyup: false,
						onclick: false,
						onfocusout: false,
						ignore: ".erIgnore",
						errorClass: "erError",
						validClass: "erValid",
						wrapper: "em",
						errorPlacement: function (error, element) {
							error.insertAfter(element.parent());
						},
						submitHandler: function (form) {
							self.disableButtons.call(self);
							var $form = pjQ.$(form);
							pjQ.$.post(post_url, $form.serialize()).done(function (data) {
								if (data.status == "OK") {
									hashBang("#!/Booking/" + data.booking_uuid);
								} else if (data.status == "ERR") {
									self.enableButtons.call(self);
								}
							}).fail(function () {
								self.enableButtons.call(self);
							});
							return false;
						}
					});
				}
			});
		}
	};
	
	// expose
	window.EquipmentRent = EquipmentRent;	
})(window);