YAHOO.namespace('istore.app');

YAHOO.istore.app.ShoppingCart = function (id, config) {
	return this.init(id, config);
}

YAHOO.istore.app.ShoppingCart.prototype = {
	
	tax_price : 0,
	
	shipping_price : 0,
	
	onLastItemRemoveHandler : function (e, args) {
		this.removeCart();
		this.onLastItemRemoveEvt.fire();
	},
	
	removeCart : function () {
		
		var duration = 0.7;
		
		var table = this.element.getElementsByTagName('table')[0];
		
		var anim = new YAHOO.util.Anim(this.element, {height: {to: 0}, opacity: {to: 0}}, duration);
		
		anim.onComplete.subscribe(
			function () {
				
				// remove table from DOM
				table.parentNode.removeChild(table);
				
				// remove presum block from DOM
				if (presum = YAHOO.util.Dom.getElementsByClassName('presum', 'div', this.element)[0]) {
					presum.parentNode.removeChild(presum);
				}
				
				// remove summary block from DOM
				if (summary = YAHOO.util.Dom.getElementsByClassName('summary', 'div', this.element)[0]) {
					summary.parentNode.removeChild(summary);
				}
				
				var msg = YAHOO.util.Dom.get('shopping-cart-msg-empty');
				var msgCont = msg.getElementsByTagName('div')[0];
				new YAHOO.util.Anim(msg, {height: {to: msgCont.offsetHeight}, opacity: {to: 1}}, 0.5).animate();
			}
		);
		
		anim.animate();
		
	},
	
	onTaxAndShippingChangeHandler : function (e, args) {
		
		var price = args[0]
		var tax = args[1]
		var shipping = args[2]
		var total = args[3]
		
		this.updateSummary(price, tax, shipping, total);
		
	},
	
	updateSummary : function (price, tax, shipping, total) {
		
		if (el = YAHOO.util.Dom.get('cart-subtotal')) {
			el.innerHTML = YAHOO.extension.funclib.formatCurrency(price);
		}
		
		if (el = YAHOO.util.Dom.get('cart-tax')) {
			el.innerHTML = YAHOO.extension.funclib.formatCurrency(tax);
		}
		
		if (el = YAHOO.util.Dom.get('cart-shipping')) {
			el.innerHTML = /*'$' + */YAHOO.extension.funclib.formatCurrency(shipping);
		}
		
		if (el = YAHOO.util.Dom.get('cart-summary-total')) {
			el.innerHTML = YAHOO.extension.funclib.formatCurrency(total);
		}
		
	},
	
	updateHandler : function () {
		
		
		// ajax callback handlers
		var ajaxCallback = {
			scope: this,
			success: function(o) {
				
				var root = o.responseXML.documentElement;
				var status = root.getElementsByTagName('status')[0].firstChild ? root.getElementsByTagName('status')[0].firstChild.nodeValue : '';
				var opCode = root.getElementsByTagName('opcode')[0].firstChild ? root.getElementsByTagName('opcode')[0].firstChild.nodeValue : '';
				var opText = root.getElementsByTagName('optext')[0].firstChild ? root.getElementsByTagName('optext')[0].firstChild.nodeValue : '';
				var qty = root.getElementsByTagName('qty')[0].firstChild ? root.getElementsByTagName('qty')[0].firstChild.nodeValue : '';
				var price = root.getElementsByTagName('price')[0].firstChild ? root.getElementsByTagName('price')[0].firstChild.nodeValue : '';
				var tax = root.getElementsByTagName('tax')[0].firstChild ? root.getElementsByTagName('tax')[0].firstChild.nodeValue : '';
				var shipping = root.getElementsByTagName('shipping')[0].firstChild ? root.getElementsByTagName('shipping')[0].firstChild.nodeValue : '';
				var total = root.getElementsByTagName('total')[0].firstChild ? root.getElementsByTagName('total')[0].firstChild.nodeValue : '';
				
				if (status == 'ok') {
					
					this.updateSummary(price, tax, shipping, total);
					
				}
				
			},
			failure: function(o) {
			}
		}
		
		var isBuyerAuthorized = !!parseInt(YAHOO.util.Dom.get('cart-is-buyer-authorized').value);
		
		var mode = isBuyerAuthorized ? 1 : 0;
		
		if (el = document.getElementsByName('is_changes')[0]) {
			if (parseInt(el.value)) {
				mode = 2;
			}
		}
		
		var connObj = YAHOO.util.Connect.asyncRequest('POST', 'https://' + window.location.host + '/ajax/cart/info', ajaxCallback, 'cart_info_mode=' + mode);
		
	},
	
		
	init : function(id, config) {
		
		// shopping cart element
		this.element = YAHOO.util.Dom.get(id);
		
		this.items = [];
		
		/* items */
		var els = YAHOO.util.Dom.getElementsByClassName('item', 'tr', this.element);
		
		if (els.length > 0) {
			for (var i = 0, l = els.length; i < l; i++) {
				
				this.items[i] = new YAHOO.istore.app.ShoppingCartItem(
					els[i].id,
					{
						// config
					}
				);
				
				this.items[i].onQtyChangeEvt.subscribe(this.updateHandler, this, true);
				this.items[i].onItemRemoveEvt.subscribe(this.updateHandler, this, true);
				this.items[i].onLastItemRemoveEvt.subscribe(this.onLastItemRemoveHandler, this, true);
				
			}
		}
		
		this.onLastItemRemoveEvt = new YAHOO.util.CustomEvent('on last item remove event');
		
	}
	
};


YAHOO.istore.app.ShoppingCartItem = function(id, config) {
	this.init(id, config);
}

YAHOO.istore.app.ShoppingCartItem.prototype = {
	
	removeRowHandler : function () {
		
		// if it was the last item
		// delete whole shopping cart and display "empty" message
		if (YAHOO.util.Dom.getElementsByClassName('item', 'tr', this.element.parent).length == 1) {
			
			this.onLastItemRemoveEvt.fire(this.itemId);
			
		// remove row otherwise
		} else {
			
			// remove item row
			this.removeRow(this.element);
			this.onItemRemoveEvt.fire(this.itemId);
			
			// if it was the last item in the block
			if (YAHOO.util.Dom.getElementsByClassName('item-block-' + this.blockId, 'tr', this.element.parent).length == 1) {
				
				// find subtitle
				var rowSubtitle = YAHOO.util.Dom.get('cart-row-subtitle-' + this.blockId);
				if (rowSubtitle) {
					// and remove it
					this.removeRow(rowSubtitle);
				}
				
			}
			
		}
		
	},
	
	
	removeRow : function(row) {
		
		var attributes = {opacity: {to: 0}, height: {to: 0}, paddingTop: {to: 0}, paddingBottom: {to: 0}};
		var duration = 0.4;
		
		for (var i = 0; i < row.cells.length; i++) {
			
			var div = row.cells[i].getElementsByTagName('div')[0];
			
			YAHOO.util.Dom.setStyle(div, 'overflow', 'hidden');
			
			var anim = new YAHOO.util.Anim(div, attributes, duration);
			if (i == 0) {
				anim.onComplete.subscribe(
					function () {
						// delete row from DOM
						row.parentNode.removeChild(row);
					}
				);
			}
			anim.animate();
			
		}
		
	},
	
	
	btnRemoveClickHandler : function () {
		
		var oThis = this;
		
		var callback = function () {
			
			// ajax callback handlers
			var callback = {
				scope: oThis,
				success: function(o) {
					
					var root = o.responseXML.documentElement;
					var status = root.getElementsByTagName('status')[0].firstChild ? root.getElementsByTagName('status')[0].firstChild.nodeValue : '';
					var opCode = root.getElementsByTagName('opcode')[0].firstChild ? root.getElementsByTagName('opcode')[0].firstChild.nodeValue : '';
					var opText = root.getElementsByTagName('optext')[0].firstChild ? root.getElementsByTagName('optext')[0].firstChild.nodeValue : '';
					
					if (status == 'ok') {
						
						var me = this;
						
						this.hideRowAjaxLoader(function () {me.removeRowHandler()});
						
						// track event in google analytics
						// pageTracker._trackPageview('/event/cart/remove/' + oThis.vendor + '/' + oThis.prodId);
						
					}
					
				},
				failure: function(o) {
					this.hideRowAjaxLoader(row);
					this.enhanceRow(row);
				}
			}
			
			var connObj = YAHOO.util.Connect.asyncRequest('GET', 'https://' + window.location.host + '/ajax/cart/remove/' + oThis.itemId, callback);
			
		}
		
		this.showRowAjaxLoader();
		this.fadeRow(callback);
		
	},
	
	
	showRowAjaxLoader : function (callback) {
		
		var duration = 0.5;
		
		YAHOO.util.Dom.setStyle(this.ajaxLoader, 'opacity', 0);
		YAHOO.util.Dom.setStyle(this.ajaxLoader, 'visibility', 'visible');
		
		// IE bugfix animated gif freeze
		this.ajaxLoader.src = this.ajaxLoader.src;
		
		var anim = new YAHOO.util.Anim(this.ajaxLoader, {opacity: {to: 1}}, duration);
		if (callback) {
			anim.onComplete.subscribe(callback);
		}
		anim.animate();
		
	},
	
	
	hideRowAjaxLoader : function (callback) {
		
		var duration = 0.5;
		
		var anim = new YAHOO.util.Anim(this.ajaxLoader, {opacity: {to: 0}}, duration);
		if (callback) {
			anim.onComplete.subscribe(callback);
		}
		anim.animate();
		
	},
	
	
	fadeRow : function (callback) {
		
		var duration = 0.5;
		
		for (var i = 0; i < this.element.cells.length; i++) {
			var anim = new YAHOO.util.Anim(this.element.cells[i].getElementsByTagName('div')[0], {opacity: {to: 0.1}}, duration);
			if (i == 0 && callback) {
				anim.onComplete.subscribe(callback);
			}
			anim.animate();
		}
		
	},
	
	
	enhanceRow : function (callback) {
		
		var duration = 0.5;
		
		for (var i = 0; i < this.element.cells.length; i++) {
			var anim = new YAHOO.util.Anim(this.element.cells[i].getElementsByTagName('div')[0], {opacity: {to: 1}}, duration);
			if (i == 0 && callback) {
				anim.onComplete.subscribe(callback);
			}
			anim.animate();
		}
		
	},
	
	
	openProdOverlay : function () {
		
		var me = this;
		
		var briefviewId = 'brief-view-' + this.itemId;
		
		var briefview = YAHOO.istore.app.panelmanager.find(briefviewId);
		
		if (!briefview) {
			
			var btnUpdateClickHandler = function (e, args) {
				
				var id = args[0];
				var vendor = args[1];
				var qty = args[2];
				var options = args[3];
				var callback = args[4];
				
				// ajax url
				var url = 'https://' + window.location.host + '/ajax/cart/update/' + id + '?qty=' + qty;
				var optionsStr = '';
				
				if (options.length > 0) {
					
					for (var i = 0, l = options.length; o = options[i], i < l; i++) {
						if (!(o.type == 'text' && o.getValue() == '')) {
							optionsStr += YAHOO.util.Dom.get('bv-item-option-title-' + id + '-' + o.id).innerHTML + ' ' + o.getValueText() + ', ';
						}
						url += '&' + o.element.name + '=' + o.getValue();
					}
					
					optionsStr = optionsStr.substr(0, optionsStr.length - 2);
				}
				
				
				var ajaxCallback = {
					scope: briefview,
					success: function(o) {
						
						// process xml response
						// root - root node
						// status - status name representation
						// opCode - operation num code
						// opText - operation response text 
						
						var root = o.responseXML.documentElement;
						var status = root.getElementsByTagName('status')[0].firstChild ? root.getElementsByTagName('status')[0].firstChild.nodeValue : '';
						var opCode = root.getElementsByTagName('opcode')[0].firstChild ? root.getElementsByTagName('opcode')[0].firstChild.nodeValue : '';
						var opText = root.getElementsByTagName('optext')[0].firstChild ? root.getElementsByTagName('optext')[0].firstChild.nodeValue : '';
						var price = root.getElementsByTagName('price')[0].firstChild ? root.getElementsByTagName('price')[0].firstChild.nodeValue : '';
						var totalPrice = root.getElementsByTagName('total_price')[0].firstChild ? root.getElementsByTagName('total_price')[0].firstChild.nodeValue : '';
						
						// item updated
						if (status == 'ok') {
							
							YAHOO.util.Dom.get('cart-item-price-' + id).innerHTML = YAHOO.extension.funclib.formatCurrency(price);
							YAHOO.util.Dom.get('cart-item-total-' + id).innerHTML = YAHOO.extension.funclib.formatCurrency(totalPrice);
							YAHOO.util.Dom.get('cart-item-opts-' + id).innerHTML = optionsStr;
							
							this.setPrice(price);
							
							me.qtyChanger.cfg.setProperty('qty', qty);
							me.onQtyChangeEvt.fire(me.itemId, qty);
							
							if (callback && callback.success) {
								callback.success();
							}
							
						} else {
							if (callback && callback.failure) {
								
								switch (opCode) {
									case '205':
										callback.submitFailedText = 'Product with ' + (options.length > 1 ? 'these options' : 'this option') + ' is already in your cart';
									break;
								}
								
								callback.failure();
							}
						}
						
					},
					failure: function(o) {
						
						if (callback && callback.failed) {
							callback.failed();
						}
						
					}
				}
				
				// invoke ajax request
				var connObj = YAHOO.util.Connect.asyncRequest('GET', url, ajaxCallback);
				
			}
			
			// create brief view instance
			briefview = new YAHOO.istore.app.BriefView(
				briefviewId,
				{
					width: '420px',
 					constraintoviewport: true,
					preloader: true,
					
					prodId: this.itemId,
					vendor: this.vendor,
					ajaxUrl: '/ajax/cart/briefview/' + this.vendor + '/' + this.itemId,
					onSubmitHandler: btnUpdateClickHandler,
					/*
					onQtyChangeHandler: function (e, args) {
						me.qtyChanger.cfg.setProperty('qty', args[0]);
						me.handleValueChangeState(e, args);
					},
					*/
					submitSuccessText: 'Updated successfully',
					submitFailedText: 'Failed to update'
				}
			);
			
			// if qty changed in table view
			me.qtyChanger.onChangeEvt.subscribe(function (e, args) {
				// update brief view qty changer
				this.qtyChanger.cfg.setProperty('qty', args[0]);
			}, briefview, true);
			
			briefview.render(document.body);
			
			YAHOO.istore.app.panelmanager.register(briefview);
		}
		
		briefview.center();
		briefview.show();
		
	},
	
	
	init : function (id, config) {
		
		var oThis = this;
		
		// item row element
		this.element = YAHOO.util.Dom.get(id);
		
		// item identifier
		this.itemId = id.substr(id.lastIndexOf('-') + 1);
		
		// block id
		this.blockId = YAHOO.util.Dom.get('cart-item-block-' + this.itemId).value;
		
		// vendor name
		this.vendor = YAHOO.util.Dom.get('cart-item-vendor-' + this.itemId).value;
		
		// product id
		this.prodId = YAHOO.util.Dom.get('cart-item-prod_id-' + this.itemId).value;
		
		this.qtyAvailable = YAHOO.util.Dom.get('cart-item-qty-available-' + this.itemId).value;
		
		// on quantity change custom event
		this.onQtyChangeEvt = new YAHOO.util.CustomEvent('on quantity change event');
		
		// on item remove change custom event
		this.onItemRemoveEvt = new YAHOO.util.CustomEvent('on item remove event');
		
		// on last item remove change custom event
		this.onLastItemRemoveEvt = new YAHOO.util.CustomEvent('on last item remove event');
		
		// ajax loader
		this.ajaxLoader = YAHOO.util.Dom.getElementsByClassName('ajax', 'img', this.element)[0];
		
		/* qyu changer values change state handler */
		this.handleValueChangeState = function (e, args) {
			
			// copy qty changer instance into temporary variable
			var me = this;
			
			var qty = args[0]; // this.cfg.getProperty('qty');
			
			// disable qty changer element
			var qtyChanger = this.disable;
			
			// me.disable();
			
			// ajax callback handlers
			var callback = {
				scope: oThis,
				success: function(o) {
					
					var root = o.responseXML.documentElement;
					var status = root.getElementsByTagName('status')[0].firstChild ? root.getElementsByTagName('status')[0].firstChild.nodeValue : '';
					var opCode = root.getElementsByTagName('opcode')[0].firstChild ? root.getElementsByTagName('opcode')[0].firstChild.nodeValue : '';
					var opText = root.getElementsByTagName('optext')[0].firstChild ? root.getElementsByTagName('optext')[0].firstChild.nodeValue : '';
					var totalPrice = root.getElementsByTagName('total_price')[0].firstChild ? root.getElementsByTagName('total_price')[0].firstChild.nodeValue : '';
					
					if (status == 'ok') {
						
						YAHOO.util.Dom.get('cart-item-total-' + this.itemId).innerHTML = YAHOO.extension.funclib.formatCurrency(totalPrice);
						
						this.onQtyChangeEvt.fire(this.itemId, qty);
					}
					
					// me.enable();
				},
				failure: function(o) {
					// me.enable();
				}
			}
			
			var connObj = YAHOO.util.Connect.asyncRequest('GET', 'https://' + window.location.host + '/ajax/cart/update/' + oThis.itemId + '?qty=' + qty, callback);
			
		}
		
		// creat quantity changer instance
		this.qtyChanger = new YAHOO.istore.app.qtyChanger('cart-item-qty-' + this.itemId,
			{
				onChangeHandler : oThis.handleValueChangeState,
				limit: this.qtyAvailable
			}
		);
		
		
		YAHOO.util.Event.addListener('cart-btn-changeoptions-' + this.itemId, 'click', this.openProdOverlay, this, true);
		YAHOO.util.Event.addListener('cart-btn-remove-' + this.itemId, 'click', this.btnRemoveClickHandler, this, true);
	}
	
}


	
YAHOO.istore.app.ShoppingCartZip = function(id, config) {
	this.init(id, config);
}

YAHOO.istore.app.ShoppingCartZip.MODE_CART = 1;

YAHOO.istore.app.ShoppingCartZip.MODE_PRODUCT = 3;

YAHOO.istore.app.ShoppingCartZip.prototype = {
	
	doCalculate: function () {
		
		var oThis = this;
		var zip = this.zipInput.value;
		
		if (!YAHOO.extension.funclib.isZip(zip)) {
			
			msgName = 'ol-zip-incorrect-zip';
			
			if (!(msg = YAHOO.istore.app.Msg.prototype.messages[msgName])) {
				msg = new YAHOO.istore.app.Msg('Should be five digits', 
				{
					name : msgName,
					type : 'err',
					context : this.zipInput,
					visible : false
				});
			}
			
			msg.show();
			
			return false;
		}
		
		this.btnSubmit.disable();
		this.ajaxLoader.show();
		
		var callback = {
			success : function () {
				oThis.ajaxLoader.hide();
				oThis.btnSubmit.enable();
			},
			failure : function () {
				oThis.ajaxLoader.hide();
				oThis.btnSubmit.enable();
			}
		}
		
		this.setCalculateParam('zip', zip);
		this.doSubmit(callback);
		
	},
	
	doSubmit: function (callback) {
		
		var msg, anim;
		
		var showErrMsg = function () {
			
			msgName = 'ol-zip-update-failed';
			
			if (!(msg = YAHOO.istore.app.Msg.prototype.messages[msgName])) {
				msg = new YAHOO.istore.app.Msg(
					'Failed to calculate shipping', 
					{
						name : msgName,
						type : 'err',
						context : 'cart-btn-zip-calculate'
					}
				);
			}
			
			msg.show();
			
		}
		
		// ajax callback handlers
		var ajaxCallback = {
			scope: this,
			success: function(o) {
				
				var root = o.responseXML.documentElement;
				var status = root.getElementsByTagName('status')[0].firstChild ? root.getElementsByTagName('status')[0].firstChild.nodeValue : '';
				var opCode = root.getElementsByTagName('opcode')[0].firstChild ? root.getElementsByTagName('opcode')[0].firstChild.nodeValue : '';
				var opText = root.getElementsByTagName('optext')[0].firstChild ? root.getElementsByTagName('optext')[0].firstChild.nodeValue : '';
				var price = root.getElementsByTagName('price')[0].firstChild ? root.getElementsByTagName('price')[0].firstChild.nodeValue : '';
				var tax = root.getElementsByTagName('tax')[0].firstChild ? root.getElementsByTagName('tax')[0].firstChild.nodeValue : '';
				var shipping = root.getElementsByTagName('shipping')[0].firstChild ? root.getElementsByTagName('shipping')[0].firstChild.nodeValue : '';
				var total = root.getElementsByTagName('total')[0].firstChild ? root.getElementsByTagName('total')[0].firstChild.nodeValue : '';
				
				if (status == 'ok') {
					
					price = price - 0;
					tax = tax - 0;
					shipping = shipping - 0;
					total = total - 0;
					
					this.onCalculateEvt.fire(price, tax, shipping, total);
					
					// if callback is set we call 'em
					if (callback && callback.success) {
						callback.success();
					}
					
				} else {
					
					showErrMsg();
					if (callback && callback.failure) {
						callback.failure();
					}
					
				}
				
			},
			failure: function(o) {
				
				showErrMsg();
				if (callback && callback.failure) {
					callback.failure();
				}
				
			}
		}
		
		// form post params string
		var params = '';
		for (key in this.params) params += key + '=' + this.params[key] + '&';
		
		var connObj = YAHOO.util.Connect.asyncRequest('POST', '/ajax/cart/info', ajaxCallback, params);
		
	},
	
	formSubmitHandler: function () {
		if (this.onBeforeCalculate.fire()) {
			this.doCalculate();
		}
	},
	
	setCalculateParam: function (key, value) {
		this.params[key] = value;
	},
	
	getBtnSubmit: function () {
		return this.btnSubmit;
	},
	
	init : function(id, config) {
		
		this.element = document.getElementById(id);
		
		this.zipInput = document.getElementById('cart-input-zip');
		
		this.mode = config.mode || YAHOO.istore.app.ShoppingCartZip.MODE_CART;
		
		this.params = {};
		
		this.setCalculateParam('cart_info_mode', this.mode);
		
		// submit btn
		this.btnSubmit = new YAHOO.istore.app.Button(
			YAHOO.util.Dom.getElementsByClassName('btn-calculate', 'span', this.element)[0]
		);
		
		// ajax loader icon
		this.ajaxLoader = new YAHOO.istore.app.AjaxLoader(
			YAHOO.util.Dom.getElementsByClassName('ajax-loader', 'img', this.element)[0]
		);
		
		// custom events
		this.onBeforeCalculate = new YAHOO.util.CustomEvent('on before calculate event');
		this.onCalculateEvt = new YAHOO.util.CustomEvent('on calculate event');
		
		YAHOO.util.Event.addListener(this.element, 'submit', this.formSubmitHandler, this, true);
		// YAHOO.util.Event.addListener(this.btnSubmit.element, 'click', this.btnSubmitClickHandler, this, true);
		
	}
	
}