(function($) {
	var Minicart;
	
	window.Minicart = Minicart = function(elem, model, data, options) {
		var defModel, defOptions, defData, mid;
		
		defModel = {
			classNames:{
				caption:'minicart-caption',
				list:'minicart-item-list',
				item:'minicart-item',
				itemThumbnail:'minicart-item-thumbnail',
				itemPrice:'minicart-item-price',
				itemName:'minicart-item-name',
				itemId:'minicart-item-id',
				deleteBtn:'minicart-delete-item-btn',
				subTotal:'minicart-subtotal',
				footer:'minicart-footer',
				checkoutBtn:'minicart-checkout-btn',
				itemInfo:'minicart-info',
				emptyList:'minicart-empty'
			},
			templates:{
				languages:{
					fr:{
						body:'<div class="$captionClass">Votre panier d\'achat :</div>' 
								+ '$items'
								+ '$subTotal',
						footer:'<div class="$footerClass">'
								+     '<a class="$checkoutBtnClass" href="$checkoutUrl">Passer à la caisse</a>'
								+       ' Sécuritaire 128 bit SSL <img src="$secureIcon" alt="">'
								+ '</div>',				
						item:'<li class="$itemClass"><span class="$itemThumbnailClass"><img src="$thumbnail" alt=""></span> <span class="$itemInfoClass"><span class="$itemNameClass">$name</span> <span class="$itemPriceClass">$price</span></span><input class="$itemIdClass" type="hidden" value="$id"><button class="$deleteBtnClass" type="button"><img src="$deleteIcon" alt=""></button></li>',
						emptyList:'<div class="$emptyListClass">Il n\'y a aucun item dans le panier</div>',
						items:'<ul class="$listClass">$items</ul>',
						subTotal:'<div class="$subTotalClass">Sous-total : $subTotal</div>'
					},
					en:{
						body:'<div class="$captionClass">Your shopping cart :</div>' 
								+ '$items'
								+ '$subTotal',
						footer:'<div class="$footerClass">'
								+     '<a class="$checkoutBtnClass" href="$checkoutUrl">Checkout</a>'
								+       ' Safe 128 bit SSL <img src="$secureIcon" alt="">'
								+ '</div>',	
						item:'<li class="$itemClass"><span class="$itemThumbnailClass"><img src="$thumbnail" alt=""></span> <span class="$itemInfoClass"><span class="$itemNameClass">$name</span> <span class="$itemPriceClass">$price</span></span><input class="$itemIdClass" type="hidden" value="$id"><button class="$deleteBtnClass" type="button"><img src="$deleteIcon" alt=""></button></li>',
						emptyList:'<div class="$emptyListClass">Your shopping cart is empty</div>',
						items:'<ul class="$listClass">$items</ul>',
						subTotal:'<div class="$subTotalClass">Subtotal : $subTotal</div>'
					}
				}
			},
			urls:{
				checkout:'',
				clearCartItems:'view.php',
				getCartItems:'view.php',
				addCartItem:'add.php',
				deleteCartItem:'remove.php'
				/*clearCartItems:'minicart-service.php?call=clear-cart-items',*/
				/*getCartItems:'minicart-service.php?call=get-cart-items',*/
				/*addCartItem:'minicart-service.php?call=add-cart-item',*/
				/*deleteCartItem:'minicart-service.php?call=delete-cart-item'*/
			},
			images:{
				secureIcon:"lib/Minicart/themes/default/images/security-icon.png",
				deleteIcon:"lib/Minicart/themes/default/images/delete-icon.png"
			}
		};
		
		defOptions = {
			uriBase:'',
			merchantId:false,
			lang:'fr'
		};
		
		defData = {
			items:[],
			subTotal:0
		};
		
		this.model = $.extend(defModel, model);
		this.options = $.extend(defOptions, options);
		this.data = $.extend(defData, data);
		this.eventModel = $({});
		
		this.elem = $(elem);
		
		this.model.templates = this.model.templates.languages[this.options.lang];
		
		if (this.data.items instanceof Array && this.data.items.length) {
			this.elem.html(this.getHtml());
		}
	};
	Minicart.prototype = {
		onAddItem: function(callback) {
			this.eventModel.bind('addItem', callback);
		},
		
		onDeleteItem: function(callback) {
			this.eventModel.bind('deleteItem', callback);
		},
		
		baseUrl: function(url) {
			this.options.baseUrl = url;
		},
		getUrl: function(name) {
			if (this.model.urls[name] !== 'undefined') {
				return this.model.urls[name];
			}
			return false;
		},
		eval: function(template, params) {
			var parts = template.split('$$');
			var part, i = 0, index, match;
			
			while (part = parts[i]) {
				index = part.search(/\$[a-zA-Z_][a-zA-Z0-9_]*/);
				while (index > -1) {
					match = part.match(/\$([a-zA-Z_][a-zA-Z0-9_]*)/);
					part = part.slice(0, index) 
						+ (
							(typeof params !== 'undefined' && typeof params[match[1]] !== 'undefined') 
						    ? params[match[1]] : ''
						  ) 
						+ part.slice(index+match[0].length);
					index = part.search(/\$[a-zA-Z_][a-zA-Z0-9_]*/);
				}
				parts[i] = part;
				i++;
			}
			return parts.join('$');
		},
		
		clearItems: function() {
			var minicart = this, xhr;
			 
			xhr = $.ajaxSetup({
				error:function(xhr, status, error) {
					minicart.ajaxError(xhr, status, error);	
				}
			});
			
			$.getJSON(this.getUrl('clearCartItems'), {}, function(data) {
				if (!data.error && data.result) {
					minicart.update();
				} else {
					minicart.ajaxError(xhr, xhr.status, data.error);	
				}
			});
		},
		
		addItem: function(productId) {
			/*
			var minicart = this, xhr, params, url;
			 
			xhr = $.ajaxSetup({
				error:function(xhr, status, error) {
					minicart.ajaxError(xhr, status, error);	
				}
			});
			
			url = this.getUrl('addCartItem');
			
			params = {
				pid:productId,
				qty:1
			};
			
			$.getJSON(url, params, function(data) {
				if (!data.error && data.result) {
					minicart.updateAddItem(productId, data.result, {ajaxURL:url, ajaxParams:params});
				} else {
					minicart.ajaxError(xhr, xhr.status, data.error);	
				}
			});
			*/
		},
		
		deleteItem: function(pos, productId) {
			var minicart = this, xhr, params, url, i, product;
			 
			xhr = $.ajaxSetup({
				error:function(xhr, status, error) {
					minicart.ajaxError(xhr, status, error);	
				}
			});
			
			url = this.getUrl('deleteCartItem');
			
			params = {
				'mid'                    : this.options.merchantId,
				'update_x'               : '0'              
			};
			
			for (i = 0; i < this.data.items.length; i++) {
				product = this.data.items[i];
				
				if (product.productId == productId) {
					params['new_qty['+product.productId+']'] = this.data.items[i].quantity - 1;
				} else {
					params['new_qty['+product.productId+']'] = this.data.items[i].quantity;
				}
			}
			
			$.post(url, params, function(data) {
				minicart.update();
				
				evtData = {
					eventSource:this,
					pos:pos,
					productId:productId,
					ajaxURL:url,
					ajaxParams:params
				};
				
				event = jQuery.Event("deleteItem");
				event.evtData = evtData;
				
				minicart.eventModel.data('eventData', data);
				minicart.eventModel.trigger(event);
			});
			
			/*
			params = {
			};
			
			$.post(url, {'mid':this.options.merchantId, 'new_qty['+productId+']':1, 'update_x':'0'}, function(data) {
				minicart.update();
				
				evtData = {
					eventSource:this,
					pos:pos,
					productId:productId,
					ajaxURL:url,
					ajaxParams:params
				};
				
				event = jQuery.Event("deleteItem");
				event.evtData = evtData;
				
				minicart.eventModel.data('eventData', data);
				minicart.eventModel.trigger(event);
			});
			*/
			
			/*
			params = {
				pid:productId,
				pos:pos
			};
			
			$.getJSON(url, params, function(data) {
				var event, evtData;
				
				if (!data.error && data.result) {
					minicart.update();
					
					evtData = {
						eventSource:this,
						pos:pos,
						productId:productId,
						ajaxURL:url,
						ajaxParams:params
					};
					
					event = jQuery.Event("deleteItem");
					event.evtData = evtData;
					
					minicart.eventModel.data('eventData', data);
					minicart.eventModel.trigger(event);
					
				} else {
					minicart.ajaxError(xhr, xhr.status, data.error);	
				}
			});
			*/
		},
		
		update: function(callback) {
			this.getItems(callback);
		},
		
		updateAddItem: function(productId, result , eventData) {
			if (!result) {
				return false;
			}
			 
			this.update(function(error) {
				var i, item, found, className, data, event, models;
				
				if (error) {
					return false;
				}
				
				models = [];
				for (i=0; i<this.data.items.length; i++) {
					item = this.data.items[i];
					
					for (j=0; j<item.quantity; j++) {
						models.push(item);
					}
				}
				found = false;
				for (i = models.length - 1; i >= 0; i--) {
					item = models[i];
					if (item.productId == productId) {
						found = item;
						break;
					}
				}
				
				if (found) {
					className = '.'+this.model.classNames.item+':eq('+i+')';
					found = $(className, this.elem);
					
					data = {
						addedElement:found,
						eventSource:this,
						productId:productId,
						ajaxURL:eventData.ajaxURL,
						ajaxParams:eventData.ajaxParams
					};
					
					event = jQuery.Event("addItem");
					event.evtData = data;
					
					minicart.eventModel.trigger(event);
				}
			});
		},
		
		getItems: function(callback) {
			var minicart = this, xhr;
			
			xhr = $.ajaxSetup({
				error:function(xhr, status, error) {
					minicart.ajaxError(xhr, status, error);	
				}
			});
			
			$.get(this.getUrl('getCartItems'), {}, function(result) {
				var data = {
					items:[], 
					subTotal:$(result).find('tr.subtotal td').eq(3).text()
				};
				$(result).find('tr.detail').each(function (i) {
					var parts, keyval, img, j, attrs;
					var cols = $('td', this);
					var id = false;
					$.each(cols.eq(6).find('a').attr('href').split('?')[1].split('&'), function (){
						var keyval = this.split('=');
						if (keyval[0] == 'pid') {
							id = keyval[1];
							return false;
						}
					});
					
					parts = cols.eq(1).find('img').attr('src').split('?');
					img = parts[0];
					if (parts[1]) {
						parts = parts[1].split('&');
					} else {
						parts = [];
					}
					attrs = {};
					for (j = 0; j < parts.length; j++) {
						keyval = parts[j].split('=');
						attrs[keyval[0]] = keyval[1];
					}
					attrs.height = 50;
					attrs.width = 50;
					img += '?' + $.param(attrs);
					
					data.items.push({
						imageSrc:  img,
						name:      cols.eq(2).text(),
						price:     cols.eq(3).find("br + *").remove().end().text(),
						quantity:  cols.eq(4).find('input').val(),
						productId: id
					});
				});
				minicart.updateGetItems(data);
				if (typeof callback === 'function') {
					callback.call(minicart, false);
				}
				/*
				if (!data.error) {
					minicart.updateGetItems(data.result);
					if (typeof callback === 'function') {
						callback.call(minicart, false);
					}
				} else {
					minicart.ajaxError(xhr, xhr.status, data.error);
					if (typeof callback === 'function') {
						callback.call(minicart, true);
					}	
				}
				*/
			});
		},
		
		updateGetItems: function(data) {
			var items, className, checkoutBtn;
			if (data) {
				this.data = data;
			} else {
				this.data = {
					items:[],
					subTotal:0
				};
			}
			
			this.elem.html(this.getHtml());
			
			className = '.'+this.model.classNames.item;
			items = $(className, this.elem);
			
			this.setEvents('item', items);
			
			className = '.'+this.model.classNames.checkoutBtn;
			checkoutBtn = $(className, this.elem);
			
			this.setEvents('checkoutBtn', checkoutBtn);
		},
		
		ajaxError: function(xhr, status, error) {
			console.log('Erreur Ajax !', xhr);
			console.log(status, error);
			//alert('Une erreur est survenue. S\'il vous plait, essayez d\'actualiser la page.');
		},
		
		setEvents: function(type, elems) {
			var minicart = this, models, i, item, j;
			elems = $(elems);
			switch (type) {
				case 'item':
					models = [];
					for (i=0; i<this.data.items.length; i++) {
						item = this.data.items[i];
						
						for (j=0; j<item.quantity; j++) {
							models.push(item);
						}
					}
					
					$.each(elems, function(i) {
						var deleteBtn, className;
						
						className = "."+minicart.model.classNames.deleteBtn;
						deleteBtn = $(className, this);
						
						deleteBtn.click(function() {
							var productId, event, data;
							
							productId = models[i].productId;
							
							data = {
								eventSource:this,
								pos:i,
								productId:productId
							};
							
							event = jQuery.Event("beforeDeleteItem");
							event.evtData = data;
							
							minicart.eventModel.trigger(event);
							
							if (event.isDefaultPrevented()) {
								return false;
							}
							minicart.deleteItem(i, productId);
						});
					});
					break;
				
				case 'checkoutBtn':
					elems.click(function() {
						window.location = minicart.getUrl('checkout');
					})
			}
		},
		
		getHtml: function(name, index, count) {
			var params, html, i, minicart = this;
			switch (name) {
				case 'body':
					params = {
						items:'',
						subTotal:'',
						itemClass:this.model.classNames.item,
						captionClass:this.model.classNames.caption,
						listClass:this.model.classNames.list,
						totalSectionClass:this.model.classNames.totalSection
					};
					return this.eval(this.model.templates.body, params);
					
				case 'footer':
					params = {
						footerClass:this.model.classNames.footer,
						checkoutBtnClass:this.model.classNames.checkoutBtn,
						checkoutUrl:this.getUrl('checkout'),
						secureIcon:this.model.images.secureIcon
					};
					
					if (this.options.lang == "fr") {
						if ($("body").hasClass("btn_checkout_a")) {
							this.model.templates.footer = '<div class="$footerClass">'
								+     '<a class="$checkoutBtnClass" href="$checkoutUrl"><img src="http://www.bijouxdefantaisie.com/_lib/Minicart/themes/bijouxbijoux/images/button-checkout-variant-b.png" alt="Acheter maintenant" /></a>'
								+       ' Sécuritaire 128 bit SSL <img src="$secureIcon" alt="">'
								+ '</div>';
							
						} else if ($("body").hasClass("btn_checkout_b")) {
							this.model.templates.footer = '<div class="$footerClass">'
								+     '<a class="$checkoutBtnClass" href="$checkoutUrl"><img src="http://www.bijouxdefantaisie.com/_lib/Minicart/themes/bijouxbijoux/images/button-checkout-variant-f.png" alt="Acheter maintenant" /></a>'
								+       ' Sécuritaire 128 bit SSL <img src="$secureIcon" alt="">'
								+ '</div>';
						} else if ($("body").hasClass("btn_checkout_c")) {
							this.model.templates.footer = '<div class="$footerClass">'
								+     '<a class="$checkoutBtnClass" href="$checkoutUrl"><img src="http://www.bijouxdefantaisie.com/_lib/Minicart/themes/bijouxbijoux/images/button-checkout-variant-c.png" alt="Acheter maintenant" /></a>'
								+       ' Sécuritaire 128 bit SSL <img src="$secureIcon" alt="">'
								+ '</div>';
						} else if ($("body").hasClass("btn_checkout_d")) {
							this.model.templates.footer = '<div class="$footerClass">'
								+     '<a class="$checkoutBtnClass" href="$checkoutUrl"><img src="http://www.bijouxdefantaisie.com/_lib/Minicart/themes/bijouxbijoux/images/button-checkout-variant-d.png" alt="Passer à la caisse" /></a>'
								+       ' Sécuritaire 128 bit SSL <img src="$secureIcon" alt="">'
								+ '</div>';
						} else if ($("body").hasClass("btn_checkout_e")) {
							this.model.templates.footer = '<div class="$footerClass">'
								+     '<a class="$checkoutBtnClass" href="$checkoutUrl"><img src="http://www.bijouxdefantaisie.com/_lib/Minicart/themes/bijouxbijoux/images/button-checkout-variant-e.png" alt="Passer à la caisse" /></a>'
								+       ' Sécuritaire 128 bit SSL <img src="$secureIcon" alt="">'
								+ '</div>';
						} else if ($("body").hasClass("btn_checkout_f")) {
						} else if ($("body").hasClass("btn_checkout_g")) {
							this.model.templates.footer = '<div class="$footerClass">'
								+     '<a class="$checkoutBtnClass" href="$checkoutUrl"><img src="http://www.bijouxdefantaisie.com/_lib/Minicart/themes/bijouxbijoux/images/button-checkout-variant-g.png" alt="Acheter maintenant" /></a>'
								+       ' Sécuritaire 128 bit SSL <img src="$secureIcon" alt="">'
								+ '</div>';
						}
					}
					
					return this.eval(this.model.templates.footer, params);
					
				case 'subTotal':
					params = {
						subTotalClass:this.model.classNames.subTotal,
						subTotal:this.data.subTotal
					};
					return minicart.eval(this.model.templates.subTotal, params);
				
				case 'emptyList':
					params = {
						emptyListClass:this.model.classNames.emptyList
					};
					return minicart.eval(this.model.templates.emptyList, params);
					
				
				case 'items':
					params = {
						thumbnail:'',
						name:'',
						price:'',
						id:'',
						itemClass:this.model.classNames.item,
						itemThumbnailClass:this.model.classNames.itemThumbnail,
						itemInfoClass:this.model.classNames.itemInfo,
						itemNameClass:this.model.classNames.itemName,
						itemPriceClass:this.model.classNames.itemPrice,
						itemIdClass:this.model.classNames.itemId,
						deleteBtnClass:this.model.classNames.deleteBtn,
						deleteIcon:this.model.images.deleteIcon
					};
					html = '';
					$.each(this.data.items, function(i) {
						var quantity, i;
						quantity = typeof this.quantity !== 'undefined' ? parseInt(this.quantity) : 0;
						
						for (i=0; i<quantity; i++) {
							params.thumbnail = typeof this.imageSrc !== 'undefined' ? this.imageSrc : '';
							params.name = typeof this.name !== 'undefined' ? this.name : '';
							params.price = typeof this.price !== 'undefined' ? this.price : '';
							params.id = typeof this.productId !== 'undefined' ? this.productId : '';
							html += minicart.eval(minicart.model.templates.item, params);
						}
					});
					
					if (html !== '') {
						params = {
							listClass:this.model.classNames.list,
							items:html
						};
						html = minicart.eval(this.model.templates.items, params);
					}
					
					return html;
					
				default:
					var footer = '';
					var items = this.getHtml('items');
					var subTotal = '';
					if (items !== '') {
						subTotal = this.getHtml('subTotal');
						footer = this.getHtml('footer');
					} else {
						items = this.getHtml('emptyList');
					}
					params = {
						items:items,
						subTotal:subTotal,
						itemClass:this.model.classNames.item,
						captionClass:this.model.classNames.caption,
						listClass:this.model.classNames.list,
						totalSectionClass:this.model.classNames.totalSection,
						footerClass:this.model.classNames.footer,
						checkoutBtnClass:this.model.classNames.checkoutBtn,
						checkoutUrl:this.getUrl('checkout'),
						secureIcon:this.model.images.secureIcon
					};
					return this.eval(this.model.templates.body, params)+footer;
			}
		}
	};
})(jQuery);
