(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),
		routes = [
		          	{pattern: /^#!\/Menu$/, eventName: "loadMenu"},
		          	{pattern: /^#!\/Packages$/, eventName: "loadPackages"},
		          	{pattern: /^#!\/Package\/package_id:(\d+)?$/, eventName: "loadPackage"},
		          	{pattern: /^#!\/Products\/category_id:(\d+)?$/, eventName: "loadProducts"},
		          	{pattern: /^#!\/Checkout$/, eventName: "loadCheckout"},
		          	{pattern: /^#!\/Preview$/, 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("loadEvents");
		}
	}
	pjQ.$(window).on("hashchange", function (e) {
    	onHashChange.call(null);
    });
	
	function Catering(opts) {
		if (!(this instanceof Catering)) {
			return new Catering(opts);
		}
				
		this.reset.call(this);
		this.init.call(this, opts);
		
		return this;
	}
	
	Catering.inObject = function (val, obj) {
		var key;
		for (key in obj) {
			if (obj.hasOwnProperty(key)) {
				if (obj[key] == val) {
					return true;
				}
			}
		}
		return false;
	};
	
	Catering.size = function(obj) {
		var key,
			size = 0;
		for (key in obj) {
			if (obj.hasOwnProperty(key)) {
				size += 1;
			}
		}
		return size;
	};
	
	Catering.prototype = {
		reset: function () {
			this.$container = null;
			this.container = null;
			this.opts = {};
			
			this.category_id = null;
			this.package_id = null;
			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");
		},
		disableSpinner: function () {
			this.$container.find(".pjCsSpinnerBtn").addClass("pjCsSpinnerDisabled");
		},
		enableSpinner: function () {
			this.$container.find(".pjCsSpinnerBtn").removeClass("pjCsSpinnerDisabled");
		},
		disableCartQty: function () {
			this.$container.find(".pjCsCartQty").prop("disabled", true);
		},
		enableCartQty: function () {
			this.$container.find(".pjCsCartQty").prop("disabled", false);
		},
		init: function (opts) {
			var self = this;
			this.opts = opts;
			this.container = document.getElementById("mbContainer_" + this.opts.index);
			this.$container = pjQ.$(this.container);
			
			this.$container.on("click.mb", ".pjMbSelectorLocale", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var locale = pjQ.$(this).data("id");
				var params = {};
				params.locale_id = locale;
				self.opts.locale = locale;
				if(self.opts.session_id != '')
				{
					params.session_id = self.opts.session_id;
				}
				
				pjQ.$.get([self.opts.folder, "index.php?controller=pjFront&action=pjActionLocale"].join(""), params).done(function (data) {					
					if(!hashBang("#!/Menu"))
					{
						self.loadMenu.call(self);
					}
				}).fail(function () {
					log("Deferred is rejected");
				});
				return false;
			}).on("click.mb", ".pjMbMenu", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				if (!hashBang("#!/Menu")) 
				{
					self.loadMenu.call(self);
				}
				return false;
			}).on("click.mb", ".pjMbPackages", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				if (!hashBang("#!/Packages")) 
				{
					self.loadPackages.call(self);
				}
				return false;
			}).on("click.mb", ".pjCsCheckout", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				if (!hashBang("#!/Checkout")) 
				{
					self.loadCheckout.call(self);
				}
				return false;
			}).on("click.mb", ".pjMbCategoryItem", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				hashBang("#!/Products/category_id:" + pjQ.$(this).attr('data-id'));
				return false;
			}).on("click.mb", ".pjMbPackage", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				hashBang("#!/Package/package_id:" + pjQ.$(this).attr('data-id'));
				return false;
			}).on("keydown.mb", ".pjCsQty, .pjCsCartQty", function (e) {
				if (e.shiftKey == true) {
	                e.preventDefault();
	            }
				if ((e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 96 && e.keyCode <= 105) || e.keyCode == 8 || e.keyCode == 9 || e.keyCode == 37 || e.keyCode == 39 || e.keyCode == 46) {
					
	            } else {
	            	e.preventDefault();
	            } 
			}).on("click.mb", ".pjCsBtnOrder", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var product_id = pjQ.$(this).attr('data-id');
				self.checkProductForm.call(self, [product_id]);
				return false;
			}).on("keyup.mb", ".pjCsCartQty", function (e) {
				if (e.shiftKey == true) {
	                e.preventDefault();
	            }
				if ((e.keyCode >= 48 && e.keyCode <= 57) || (e.keyCode >= 96 && e.keyCode <= 105) || e.keyCode == 8 || e.keyCode == 9 || e.keyCode == 37 || e.keyCode == 39 || e.keyCode == 46) {
					var qty = pjQ.$(this).val();
					var type = pjQ.$(this).attr('data-type');
					var id = pjQ.$(this).attr('data-id');
					var size_id = pjQ.$(this).attr("data-size_id") ? $(this).attr("data-size_id") : null;
					setTimeout(function(){
				        self.updateCart.call(self,[type, id, size_id]);
				    },300);
	            } else {
	            	e.preventDefault();
	            } 
				return false;
			}).on("click.mb", ".pjCsCartRemove", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				var type = pjQ.$(this).attr('data-type');
				var id = pjQ.$(this).attr('data-id');
				var size_id = null;
				if (typeof pjQ.$(this).attr('data-size_id') !== typeof undefined && pjQ.$(this).attr('data-size_id') !== false) {
					size_id = pjQ.$(this).attr('data-size_id');
				}
				self.removeCart.call(self, type, id, size_id);
				return false;
			}).on("change.mb", "select[name='payment_method']", function () {
				self.$container.find(".pjCsCCWrap").hide();
				self.$container.find(".pjCsBankWrap").hide();
				switch (pjQ.$("option:selected", this).val()) {
				case 'creditcard':
					self.$container.find(".pjCsCCWrap").show();
					break;
				case 'bank':
					self.$container.find(".pjCsBankWrap").show();
					break;
				}
			}).on("click.mb", ".pjCsCancelPreview", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				if (!hashBang("#!/Checkout")) 
				{
					self.loadCheckout.call(self);
				}
				return false;
			}).on("click.mb", ".pjCsBtnStartOver", function (e) {
				if (e && e.preventDefault) {
					e.preventDefault();
				}
				if (!hashBang("#!/Menu")) 
				{
					self.loadMenu.call(self);
				}
				return false;
			});
			
			pjQ.$(window).on("loadMenu", this.container, function (e) {
				self.loadMenu.call(self);
			}).on("loadPackages", this.container, function (e) {
				self.loadPackages.call(self);
			}).on("loadProducts", this.container, function (e) {
				switch (arguments.length) {
					case 1:
						break;
					case 2:
						self.category_id = arguments[1];
					break;
				}
				self.loadProducts.call(self);
			}).on("loadPackage", this.container, function (e) {
				switch (arguments.length) {
					case 1:
						break;
					case 2:
						self.package_id = arguments[1];
					break;
				}
				self.loadPackage.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.loadMenu.call(this);
			} else {
				onHashChange.call(null);
			}
		},
		removeCart: function(type, id, size_id)
		{
			var self = this,
				index = this.opts.index,
				params ={};
			if(self.opts.session_id != '')
			{
				params.session_id = self.opts.session_id;
			}
			params.type = type;
			params.id = id;
			if(size_id != null)
			{
				params.size_id = size_id;
			}
			self.disableButtons.call(self);
			self.disableSpinner.call(self);
			pjQ.$.get([self.opts.folder, "index.php?controller=pjFront&action=pjActionRemoveCart"].join(""), params).done(function (data) {
				if (data.code != undefined && data.status == 'ERR') {
					if (!hashBang("#!/Checkout")) 
					{
						self.loadCheckout.call(self);
					}	
				}else{
					pjQ.$('#pjCsCartContainer_' + self.opts.index).html(data);
					pjQ.$('#pjCsCartAmount_' + self.opts.index).html("(" + pjQ.$('#pjCsSubtotal').html() + ")");
					self.bindCheckout.call(self);
				}
				
				self.enableButtons.call(self);
				self.enableSpinner.call(self);
			}).fail(function () {
				self.enableButtons.call(self);
				self.enableSpinner.call(self);
			});
		},
		updateCart: function(type, id, size_id, qty)
		{
			var self = this,
				index = this.opts.index,
				params ={};
			if(self.opts.session_id != '')
			{
				params.session_id = self.opts.session_id;
			}
			params.type = type;
			params.id = id;
			if(size_id != null)
			{
				params.size_id = size_id;
			}
			params.qty = qty;
			self.disableButtons.call(self);
			self.disableSpinner.call(self);
			pjQ.$.get([self.opts.folder, "index.php?controller=pjFront&action=pjActionUpdateCart"].join(""), params).done(function (data) {
				
				if (data.code != undefined && data.status == 'ERR') {

				}else{
					pjQ.$('#pjCsCartContainer_' + self.opts.index).html(data);
					pjQ.$('#pjCsCartAmount_' + self.opts.index).html("(" + pjQ.$('#pjCsSubtotal').html() + ")");
					self.bindCheckout.call(self);
				}
				
				self.enableButtons.call(self);
				self.enableSpinner.call(self);
			}).fail(function () {
				self.enableButtons.call(self);
				self.enableSpinner.call(self);
			});
		},
		checkProductForm: function(product_id)
		{
			var self = this,
				index = this.opts.index,
				params ={};
			
			var $frm = pjQ.$('#pjCsProductForm_' + product_id);
			
			if($frm.length > 0)
			{
				var valid = false;
				var $order_msg = pjQ.$('#pjCsOrderMsg_' + product_id);
				$frm.find('.pjCsQty').each(function(){
					if(parseInt(pjQ.$(this).val(),10) > 0)
					{
						valid = true;
					}
				});
				if(valid  == true)
				{
					self.disableButtons.call(self);
					self.disableSpinner.call(self);
					var session_str = '';
					if(self.opts.session_id != '')
					{
						session_str += "&session_id=" + self.opts.session_id;
					}
					pjQ.$.post([self.opts.folder, "index.php?controller=pjFront&action=pjActionAddCart", session_str].join(""), $frm.serialize()).done(function (data) {
						self.enableButtons.call(self);
						self.enableSpinner.call(self);
						
						if(data.status == 'OK')
						{
							var added_to_cart_text = $order_msg.attr('data-added');
							added_to_cart_text = added_to_cart_text.replace("{STAG}", '<a href="#" class="pjCsCheckout">');
							added_to_cart_text = added_to_cart_text.replace("{ETAG}", '<a/>');
							$order_msg.html(added_to_cart_text);
							$order_msg.attr('data-type', 'added');
							
							pjQ.$('#pjCsCartAmount_' + self.opts.index).html("("+data.subtotal+")");
							
							setTimeout(function(){
								$order_msg.html("");
							}, 2000);
						}
						
					}).fail(function () {
						self.enableButtons.call(self);
						self.enableSpinner.call(self);
					});
				}else{
					self.enableButtons.call(self);
					self.enableSpinner.call(self);
					
					var enter_quantity_text = $order_msg.attr('data-enter');
					$order_msg.html(enter_quantity_text);
					$order_msg.attr('data-type', 'enter');
					
					setTimeout(function(){
						$order_msg.html("");
					}, 2000);
				}
			}
		},
		loadMenu: function () {
			var self = this,
				index = this.opts.index,
				params ={};
			
			params.theme = self.opts.theme;
			params.locale = self.opts.locale;
			params.hide = self.opts.hide;
			params.index = self.opts.index;
			if(self.opts.session_id != '')
			{
				params.session_id = self.opts.session_id;
			}
			
			pjQ.$.get([this.opts.folder, "index.php?controller=pjFront&action=pjActionMenu"].join(""), params).done(function (data) {
				self.$container.html(data);
			}).fail(function () {
				self.enableButtons.call(self);
			});
		},
		loadPackages: function () {
			var self = this,
				index = this.opts.index,
				params ={};
			
			params.theme = self.opts.theme;
			params.locale = self.opts.locale;
			params.hide = self.opts.hide;
			params.index = self.opts.index;
			if(self.opts.session_id != '')
			{
				params.session_id = self.opts.session_id;
			}
			
			pjQ.$.get([this.opts.folder, "index.php?controller=pjFront&action=pjActionPackages"].join(""), params).done(function (data) {
				self.$container.html(data);
			}).fail(function () {
				self.enableButtons.call(self);
			});
		},
		loadProducts: function () {
			var self = this,
				index = this.opts.index,
				params = {};
			
			params.theme = self.opts.theme;
			params.locale = self.opts.locale;
			params.hide = self.opts.hide;
			params.index = self.opts.index;
			if(self.opts.session_id != '')
			{
				params.session_id = self.opts.session_id;
			}
			if (self.category_id !== null) {
				params.cid = self.category_id;
			}
			pjQ.$.get([this.opts.folder, "index.php?controller=pjFront&action=pjActionProducts"].join(""), params).done(function (data) {
				self.$container.html(data);
				self.bindProducts.call(self);
			}).fail(function () {
				self.enableButtons.call(self);
			});
		},
		bindProducts: function(){
			var self = this,
				index = this.opts.index,
				params = {};
			
			if (pjQ.$('.pjCsSpinner').length) {
				pjQ.$('.pjCsSpinner').on('click', '.pjCsSpinnerBtn', function(e) {
					if (e && e.preventDefault) {
						e.preventDefault();
					}
					if(!pjQ.$(this).hasClass('pjCsSpinnerDisabled'))
					{
						var spinnerBtnUpClass = 'pjCsSpinnerBtnUp';
						var spinnerBtnDownClass = 'pjCsSpinnerBtnDown';
						var $currentSpinnerBtn = pjQ.$(this);
						var $currentSpinner = $currentSpinnerBtn.parents('.pjCsSpinner');
						var $currentSpinnerInput = $currentSpinner.find('.form-control');
						var $currentSpinnerInputInitialValue = $currentSpinnerInput.val() == '' ? 0 : parseInt($currentSpinnerInput.val());
						var $currentSpinnerInputMinimum = $currentSpinnerInput.attr('data-min');
	
						if ($currentSpinnerBtn.hasClass(spinnerBtnDownClass)) {
							$currentSpinnerInput.val($currentSpinnerInputInitialValue --- 1);
						} else if ($currentSpinnerBtn.hasClass(spinnerBtnUpClass)) {
							$currentSpinnerInput.val($currentSpinnerInputInitialValue +++ 1);
						};
	
						if ((parseInt($currentSpinnerInput.val())) <= (parseInt($currentSpinnerInputMinimum))) {
							$currentSpinnerInput.val($currentSpinnerInputMinimum)
						};
						
						$currentSpinnerInput.attr('value', $currentSpinnerInput.val());
						
						var product_id = $currentSpinnerInput.attr('data-id');
						var $order_msg = pjQ.$('#pjCsOrderMsg_' + product_id);
						var $frm = pjQ.$('#pjCsProductForm_' + product_id);
						if($frm.length > 0)
						{
							var valid = false;
							$frm.find('.pjCsQty').each(function(){
								if(parseInt(pjQ.$(this).val(), 10) > 0)
								{
									valid = true;
								}
							});
							if(valid == true && $order_msg.attr('data-type') == 'enter')
							{
								$order_msg.html("");
							}
						}
					}
					
				});
			};
			
		},
		loadPackage: function () {
			var self = this,
				index = this.opts.index,
				params ={};
			
			params.theme = self.opts.theme;
			params.locale = self.opts.locale;
			params.hide = self.opts.hide;
			params.index = self.opts.index;
			if(self.opts.session_id != ''){
				params.session_id = self.opts.session_id;
			}
			if (self.package_id !== null) {
				params.package_id = self.package_id;
			}
			pjQ.$.get([this.opts.folder, "index.php?controller=pjFront&action=pjActionPackage"].join(""), params).done(function (data) {
				self.$container.html(data);
				self.bindPackage.call(self);
			}).fail(function () {
				self.enableButtons.call(self);
			});
		},
		bindPackage: function(){
			var self = this,
				index = this.opts.index,
				params = {};
			
			if (pjQ.$('.pjCsSpinner').length) {
				pjQ.$('.pjCsSpinner').on('click', '.pjCsSpinnerBtn', function(e) {
					if (e && e.preventDefault) {
						e.preventDefault();
					}
					if(!pjQ.$(this).hasClass('pjCsSpinnerDisabled'))
					{
						var spinnerBtnUpClass = 'pjCsSpinnerBtnUp';
						var spinnerBtnDownClass = 'pjCsSpinnerBtnDown';
						var $currentSpinnerBtn = pjQ.$(this);
						var $currentSpinner = $currentSpinnerBtn.parents('.pjCsSpinner');
						var $currentSpinnerInput = $currentSpinner.find('.form-control');
						var $currentSpinnerInputInitialValue = $currentSpinnerInput.val() == '' ? 0 : parseInt($currentSpinnerInput.val());
						var $currentSpinnerInputMinimum = $currentSpinnerInput.attr('data-min');
	
						if ($currentSpinnerBtn.hasClass(spinnerBtnDownClass)) {
							$currentSpinnerInput.val($currentSpinnerInputInitialValue --- 1);
						} else if ($currentSpinnerBtn.hasClass(spinnerBtnUpClass)) {
							$currentSpinnerInput.val($currentSpinnerInputInitialValue +++ 1);
						};
	
						if ((parseInt($currentSpinnerInput.val())) <= (parseInt($currentSpinnerInputMinimum))) {
							$currentSpinnerInput.val($currentSpinnerInputMinimum)
						};
	
						$currentSpinnerInput.attr('value', $currentSpinnerInput.val());
						
						var package_id = $currentSpinnerInput.attr('data-id');
						var $order_msg = pjQ.$('#pjCsOrderMsg_' + package_id);
						var $frm = pjQ.$('#pjCsProductForm_' + package_id);
						if($frm.length > 0)
						{
							var valid = false;
							$frm.find('.pjCsQty').each(function(){
								if(parseInt(pjQ.$(this).val(), 10) > 0)
								{
									valid = true;
								}
							});
							if(valid == true && $order_msg.attr('data-type') == 'enter')
							{
								$order_msg.html("");
							}
						}
					}
					
				});
			};
			
		},
		loadCheckout: function () {
			var self = this,
				index = this.opts.index,
				params ={};
			
			params.theme = self.opts.theme;
			params.locale = self.opts.locale;
			params.hide = self.opts.hide;
			params.index = self.opts.index;
			if(self.opts.session_id != '')
			{
				params.session_id = self.opts.session_id;
			}
			
			pjQ.$.get([this.opts.folder, "index.php?controller=pjFront&action=pjActionCheckout"].join(""), params).done(function (data) {
				self.$container.html(data);
				self.bindCheckout.call(self);
			}).fail(function () {
				self.enableButtons.call(self);
			});
		},
		bindCheckout: function(){
			var self = this,
				index = this.opts.index,
				params = {};
			
			if (pjQ.$('.pjCsSpinner').length) {
				pjQ.$('.pjCsSpinner').on('click', '.pjCsSpinnerBtn', function(e) {
					if (e && e.preventDefault) {
						e.preventDefault();
					}
					if(!pjQ.$(this).hasClass('pjCsSpinnerDisabled'))
					{
						var spinnerBtnUpClass = 'pjCsSpinnerBtnUp';
						var spinnerBtnDownClass = 'pjCsSpinnerBtnDown';
						var $currentSpinnerBtn = pjQ.$(this);
						var $currentSpinner = $currentSpinnerBtn.parents('.pjCsSpinner');
						var $currentSpinnerInput = $currentSpinner.find('.form-control');
						var $currentSpinnerInputInitialValue = $currentSpinnerInput.val() == '' ? 0 : parseInt($currentSpinnerInput.val());
						var $currentSpinnerInputMinimum = $currentSpinnerInput.attr('data-min');
	
						if ($currentSpinnerBtn.hasClass(spinnerBtnDownClass)) {
							$currentSpinnerInput.val($currentSpinnerInputInitialValue --- 1);
						} else if ($currentSpinnerBtn.hasClass(spinnerBtnUpClass)) {
							$currentSpinnerInput.val($currentSpinnerInputInitialValue +++ 1);
						};
	
						if ((parseInt($currentSpinnerInput.val())) <= (parseInt($currentSpinnerInputMinimum))) {
							$currentSpinnerInput.val($currentSpinnerInputMinimum)
						};
	
						$currentSpinnerInput.attr('value', $currentSpinnerInput.val());
						
						var qty = $currentSpinnerInput.val();
						var type = $currentSpinnerInput.attr('data-type');
						var id = $currentSpinnerInput.attr('data-id');
						var size_id = null;
						if (typeof $currentSpinnerInput.attr('data-size_id') !== typeof undefined && $currentSpinnerInput.attr('data-size_id') !== false) {
							size_id = $currentSpinnerInput.attr('data-size_id');
						}
						self.updateCart.call(self, type, id, size_id, qty);
					}
					
				});
			};
			
			var $frmCheckout = pjQ.$('#pjCsCheckoutForm_' + self.opts.index);
			
			if($frmCheckout.length > 0)
			{
				pjQ.$('.modal-dialog').css("z-index", "9999"); 
				
				if (pjQ.$('.pjCsDatePicker').length) 
				{
					moment.locale('en', {
						week: { dow: self.opts.week_start },
						months : pjQ.$('#pjCsCalendarLocale').data('months').split("_"),
				        weekdaysMin : pjQ.$('#pjCsCalendarLocale').data('days').split("_")
					});
					var currentDate = new Date();
					pjQ.$('.pjCsDatePicker').datetimepicker({
						format: self.opts.momentDateFormat.toUpperCase(),
						locale: moment.locale('en'),
						allowInputToggle: true,
						ignoreReadonly: true,
						minDate: new Date(currentDate.getFullYear(), currentDate.getMonth(), currentDate.getDate())
					});
				}
				pjQ.$('.pjCsTimePicker').datetimepicker({
					format: self.opts.time_format,
					ignoreReadonly: true,
					allowInputToggle: true
				});
				pjQ.$('.pjCsTimePicker').on('dp.change', function (e) {
					$frmCheckout.find('input[name="delivery_hour"]').val(e.date.hour());
					$frmCheckout.find('input[name="delivery_minute"]').val(e.date.minute());
				});
				
				if (validate) 
				{
					var remote_url = self.opts.folder + "index.php?controller=pjFront&action=pjActionCheckCaptcha";
					var checkout_url = self.opts.folder + "index.php?controller=pjFront&action=pjActionCheckout";
					if(self.opts.session_id != '')
					{
						 remote_url = self.opts.folder + "index.php?controller=pjFront&action=pjActionCheckCaptcha&session_id=" + self.opts.session_id;
						 checkout_url = self.opts.folder + "index.php?controller=pjFront&action=pjActionCheckout&session_id=" + self.opts.session_id;
					}
					$frmCheckout.validate({
						rules: {
							"captcha": {
								remote: remote_url
							}
						},
						onkeyup: false,
						errorElement: 'li',
						errorPlacement: function (error, element) {
							if(element.attr('name') == 'terms' || element.attr('name') == 'delivery_date' || element.attr('name') == 'delivery_time')
							{
								error.appendTo(element.parent().next().find('ul'));
							}else if(element.attr('name') == 'captcha'){
								error.appendTo(element.parent().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.parent().parent().parent().removeClass('has-success').addClass('has-error');
							}else if(element.attr('name') == 'terms' || element.attr('name') == 'delivery_date' || element.attr('name') == 'delivery_time'){
								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') == 'captcha')
							{
								element.parent().parent().parent().removeClass('has-error').addClass('has-success');
							}else if(element.attr('name') == 'terms' || element.attr('name') == 'delivery_date' || element.attr('name') == 'delivery_time'){
								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);
							pjQ.$.post(checkout_url, $frmCheckout.serialize()).done(function (data) {
								if (data.status == "OK") {
									if (!hashBang("#!/Preview")) 
									{
										self.loadPreview.call(self);
									}
								}
							}).fail(function () {
								self.enableButtons.call(self);
							});
							return false;
						}
					});
				}
			}
		},
		loadPreview: function () {
			var self = this,
				index = this.opts.index,
				params ={};
			
			params.theme = self.opts.theme;
			params.locale = self.opts.locale;
			params.hide = self.opts.hide;
			params.index = self.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"].join(""), params).done(function (data) {
				if (data.code != undefined && data.status == 'ERR') {
					if (!hashBang("#!/Menu")) 
					{
						self.loadMenu.call(self);
					}
				}else{
					self.$container.html(data);
					self.bindPreview.call(self);
				}
			}).fail(function () {
				self.enableButtons.call(self);
			});
		},
		bindPreview: function(){
			var self = this,
				index = this.opts.index;
		
			if (validate) 
			{
				var save_order_url = self.opts.folder + "index.php?controller=pjFront&action=pjActionSaveOrder";
				if(self.opts.session_id != '')
				{
					 save_order_url = self.opts.folder + "index.php?controller=pjFront&action=pjActionSaveOrder&session_id=" + self.opts.session_id;
				}
				var $form = pjQ.$('#pjCsPreviewForm_'+ self.opts.index);
				$form.validate({
					
					submitHandler: function (form) {
						self.disableButtons.call(self);
						var $form = pjQ.$(form);
						pjQ.$.post(save_order_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;
					}
				});
			}
		},
		getPaymentForm: function(obj){
			var self = this,
				index = this.opts.index,
				params ={};
			
			params.theme = self.opts.theme;
			params.locale = self.opts.locale;
			params.hide = self.opts.hide;
			params.index = self.opts.index;
			if(self.opts.session_id != '')
			{
				params.session_id = self.opts.session_id;
			}
			params.order_id = obj.order_id;
			params.payment_method = obj.payment;
			
			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='csPaypal']").trigger('submit');
						break;
					case 'authorize':
						self.$container.find("form[name='csAuthorize']").trigger('submit');
						break;
					case 'creditcard':
					case 'bank':
					case 'cash':
						break;
				}
			}).fail(function () {
				log("Deferred is rejected");
			});
		}
	};
	
	window.Catering = Catering;	
})(window);