//setup the namespace
if (typeof crumbs == "undefined" || !crumbs) {
    var crumbs = {};
}

crumbs.Cart = Class.create({
	initialize: function(element, template) {
		this.elementId = element;
		this.element = $(element);
		this.cartItems = null;
		this.onCartChange = null;  // event/function fired when cart changes (add, remove, update)
		this.cookieJar = null;

		this.initCartItems();
		this.initCookieJar();
		this.initCollapsableLists();
		this.initOrderInfoPopup();

		/*
		this.dragOptions = {
					onHover: this.dragHover,
					hoverclass:'target_hover',
					onDrop: this.dragDrop  };
		this.droppable = Droppables.add(this.element.parentNode, this.dragOptions);
		*/

		this.eventAddToCartSuccess = this.addToCartSuccess.bindAsEventListener(this);
		this.eventAddToCartFailure = this.addToCartFailure.bindAsEventListener(this);

		this.addCartItemListeners();
		
		this.addTemplate = new Template($('cart_add_modal_template').innerHTML);
		this.updateTemplate = new Template($('cart_update_modal_template').innerHTML);
		
		//if (!navigator.appVersion.match('MSIE 6.')) {  // this seems to work in IE6
			this.initialOffset = this.element.cumulativeOffset();
			//this.initialOffset = this.element.positionedOffset();
			this.eventScrollResize = this.monitorScrollLocation.bindAsEventListener(this);
			Event.observe(window, 'scroll', this.eventScrollResize);
	    	Event.observe(window, 'resize', this.eventScrollResize);
		//}
	},

	onCartRecreate: function () {
		this.addCartItemListeners();
		this.initCollapsableLists();
		this.initOrderInfoPopup();
	},

	initCartItems: function () {
		if(!cartProducts) 
			return false;
		this.setCartItems(cartProducts);
		return true;
	},

	setCartItems: function (cartItems) {
		this.cartItems = cartItems;
	},
	
	initCookieJar: function() {
		this.cookieJar = new CookieJar({expires: 3600});
	},

	initCollapsableLists: function () {
		var closers = this.element.select("span.collapser");
		for (var i = 0; i < closers.length; i++) {
			Event.observe(closers[i], "click", this.expandCollapseList.bindAsEventListener(this));
			if(this.cookieJar.get('list_'+closers[i].getAttribute("opens"))==1) {
				$(closers[i].getAttribute("opens")).addClassName("open");
				closers[i].addClassName("open");
			}
		}
	},

	expandCollapseList: function (event) {
		var closer = Event.element(event);
		var list = $(closer.getAttribute("opens"));
		if (list) {
			if (list.hasClassName("open")) {
				list.removeClassName("open");
				closer.removeClassName("open");
				this.cookieJar.put('list_'+closer.getAttribute("opens"), 0);
			}
			else {
				list.addClassName("open");
				closer.addClassName("open");
				this.cookieJar.put('list_'+closer.getAttribute("opens"), 1);
			}
		}
	},

	initDetailsPopup: function () {
		if(!this.detailsPop) {
			this.detailsPop = new Window('mini-cart-toolbar', {className: "product-popup", width:540, height:55, zIndex: 1000, resizable: false, minimizable: false, maximizable: false, draggable:false, showEffect:Effect.Appear, hideEffect: Effect.Fade});
		}
	},

	initOrderInfoPopup: function () {
		var content = $("cart_orderinfo_modal");
		if (!this.orderInfoPop)  
			this.orderInfoPop = new Window('orderinfo-toolbar', {className: "orderinfo-popup", width:460, height:65, zIndex: 1000, resizable: false, minimizable: false, maximizable: false, draggable:false, showEffect:Effect.Appear, hideEffect: Effect.Fade, destroyOnClose: false});
		this.orderInfoPop.getContent().innerHTML = content.innerHTML;

		var orderInfoLink = $("cart_orderinfo_text");
		if (orderInfoLink) {
			Event.observe(orderInfoLink.id, "click", this.openOrderInfoPopup.bindAsEventListener(this));			
		}
	},

	openOrderInfoPopup: function (event) {
		var width = 460;
		var xPos = Event.pointerX(event);
		if (xPos + width > document.viewport.getWidth())
			xPos = document.viewport.getWidth() - width - 100;
		this.orderInfoPop.setLocation(Event.pointerY(event), xPos);
		this.orderInfoPop.show();
		this.findCloseBtn(this.orderInfoPop.getId());
	},

	getContents: function () {
		return this.element.innerHTML;
	},
	dragHover: function(dragElm, dropElm, evt) {
	},
	dragDrop: function(dragElm, dropElm, evt) {
		var products = screenManager.getCatalog().getProducts();
		var product = products[parseInt(dragElm.getAttribute('index'))];
		//scoping issues cause this style to be necessary
		var cart = screenManager.getCart();
		cart.fillDetailsPop(product.properties);
		cart.detailsPop.setLocation(Event.pointerY(evt), Event.pointerX(evt));
		cart.detailsPop.show();
		cart.findCloseBtn(cart.detailsPop.getId());

		screenManager.trackEvent("Mini-Cart", "Product Dragged", product.properties.name);
		//clear inline styles added by Window
		$('mini-cart-toolbar_content').writeAttribute('style', '');
	},

	fillDetailsPop: function(detailsObj) {
		this.initDetailsPopup();
		this.detailsPop.getContent().innerHTML= this.addTemplate.evaluate(detailsObj);

		var assProdSelect = $("associated-product-" + detailsObj.id);
		if (assProdSelect)
			Event.observe(assProdSelect, "change", this.assProdSelectChange);

		var addButtonArr = Element.select(this.detailsPop.getContent(), ".add");
		this.eventAddDropToCart = this.addDropToCart.bindAsEventListener(this);
		Event.observe(addButtonArr[0], "click", this.eventAddDropToCart);
		var imgs = this.detailsPop.getContent().getElementsByTagName("img");
		for(var i=0; i<imgs.length; i++) {
			imgs[i].src = imgs[i].getAttribute("mysrc");
		}

		var inputs = this.detailsPop.getContent().select("input.amount");
		Event.observe(inputs[0], "keypress", this.addInputKeyPress.bindAsEventListener(this));
	},

	fillUpdatePop: function (origDetailsObj) {
		var detailsObj = Object.clone(origDetailsObj);
		this.initDetailsPopup();
		
		if(detailsObj.type=="bundle") {
			var newname = detailsObj.name + " - <span>" + detailsObj.bundle.join(", ") + "</span>";
			detailsObj.name = newname;
		}
		this.detailsPop.getContent().innerHTML = this.updateTemplate.evaluate(detailsObj);

		var updateLinks = this.detailsPop.getContent().select(".actions a.update");
		Event.observe(updateLinks[0], "click", this.updateCart.bindAsEventListener(this));
		var removeLinks = this.detailsPop.getContent().select(".actions a.remove");
		Event.observe(removeLinks[0], "click", this.removeFromCart.bindAsEventListener(this));

		var imgs = this.detailsPop.getContent().getElementsByTagName("img");
		for(var i=0; i<imgs.length; i++) {
			imgs[i].src = imgs[i].getAttribute("mysrc");
		}
	},

	addInputKeyPress: function (event) {
		if (event.keyCode == Event.KEY_RETURN) {
			this.addDropToCart(null);
		}
	},

	assProdSelectChange: function (event) {
		var id = this.id.substr(this.id.lastIndexOf("-") + 1);
		var span = $("price-" + id);
		span.innerHTML = this.options[this.selectedIndex].getAttribute("price");
	},

	addCartItemListeners: function () {
		var itemLinks = this.element.select("a.item-open");
		for (var i = 0; i < itemLinks.length; i++) {
			Event.observe(itemLinks[i], "click", this.openUpdateModal.bindAsEventListener(this));
		}
	},

	openUpdateModal: function (event) {
		var index = Event.element(event).getAttribute('index');
		if (this.cartItems && this.cartItems[index]) {
			var item = this.cartItems[index];
			this.fillUpdatePop(item);
			this.detailsPop.setLocation(Event.pointerY(event), Event.pointerX(event));
			this.detailsPop.show();
			this.findCloseBtn(this.detailsPop.getId());

			//clear inline styles added by Window
			$('mini-cart-toolbar_content').writeAttribute('style', '');		
		}
	},

	updateCart: function (event) {
		var forms = this.detailsPop.getContent().getElementsByTagName("form");
		var form = forms[0];
		var formValues = Form.serialize(form);
		
		var url = "/checkout/cartasync/update";
		var options = {
			method: 'post',
			onSuccess: this.eventAddToCartSuccess,
			onFailure: this.eventAddToCartFailure,
			postBody: formValues
		};
		Effect.Fade(this.element, { to: "0.1" });

		this.ajaxRequest = new Ajax.Request(url, options);
		this.detailsPop.hide();
	},

	removeFromCart: function (event) {
		var elm = Event.element(event);
		var url = elm.getAttribute("url");
		url = url.replace(/\/cart\//, "/cartasync/");

		var options = {
			method: 'get',
			onSuccess: this.eventAddToCartSuccess,
			onFailure: this.eventAddToCartFailure
		};
		Effect.Fade(this.element, { to: 0.1 });
		this.ajaxRequest = new Ajax.Request(url, options);
		this.detailsPop.hide();
	},

	addDropToCart: function(event) {
		//var elm = Event.element(event);
		var forms = this.detailsPop.getContent().getElementsByTagName("form");
		var form = forms[0];
		this.addToCart(form);
		this.detailsPop.hide();
		screenManager.trackEvent("Mini-Cart", "Add to Cart");
	},
	
	addProductModalToCart: function(form) {
		this.addToCart(form);
	},
	
	addToCart: function(form) {
		var url = "/checkout/cartasync/add";
		var formValues = Form.serialize(form);
		var options = {
			method: 'post',
			onSuccess: this.eventAddToCartSuccess,
			onFailure: this.eventAddToCartFailure,
			postBody: formValues
		};
		Effect.Fade(this.element, { to: "0.1" });

		this.ajaxRequest = new Ajax.Request(url, options);
	},
	
	addManyToCart: function(products) {
		var url = "/checkout/cartasync/addmany?products=";
		for(var i=0; i<6; i++ ) {
			var quant = $("sixpack_quantity").value;
			if(isNaN(quant)) quant = 1;
			for(var j=0; j<quant; j++) {
				var product = products[i]
				url += product.properties.signature_id+",";
			}
		}
		
		this.eventAddManyToCartSuccess = this.addManyToCartSuccess.bindAsEventListener(this);
		this.eventAddManyToCartFailure = this.addManyToCartFailure.bindAsEventListener(this);
		var options = {
			method: 'get',
			onSuccess: this.eventAddManyToCartSuccess,
			onFailure: this.eventAddManyToCartFailure
		};

		this.ajaxRequest = new Ajax.Request(url, options);
	},
	
	addBundleToCart: function(products) {
		var url = "/checkout/cartasync/addbundle?products=";
		//only look at the first six. I don't know how you'd get here with anything else, but OK.
		for(var i=0; i<6; i++ ) {
			var product = products[i]
			url += product.properties.signature_id;
			if(i!=5)
				url += ",";
		}
		var quant = $("sixpack_quantity").value;
		if(isNaN(quant)) quant = 1;
		url += "&qty="+quant;
		
		this.eventAddManyToCartSuccess = this.addManyToCartSuccess.bindAsEventListener(this);
		this.eventAddManyToCartFailure = this.addManyToCartFailure.bindAsEventListener(this);
		var options = {
			method: 'get',
			onSuccess: this.eventAddManyToCartSuccess,
			onFailure: this.eventAddManyToCartFailure
		};

		this.ajaxRequest = new Ajax.Request(url, options);
	},

	addToCartSuccess: function(transport) {
		this.element.parentNode.innerHTML = transport.responseText;
		this.element = $(this.elementId);
		this.evalHtml(this.element.parentNode);
		this.onCartRecreate();

		if (Object.isFunction(this.onCartChange))
			this.onCartChange();

		Effect.Appear(this.element);
		this.monitorScrollLocation();
	},

	addToCartFailure: function(transport) {
		//alert('An error occurred:'+transport.responseText);
		Effect.Appear(this.element);
		this.monitorScrollLocation();
	},

	addManyToCartSuccess: function(transport) {
		this.addToCartSuccess(transport);
		
		screenManager.getSixpack().modal.clearProducts();
		screenManager.getSixpack().modal.window.hide();
	},

	addManyToCartFailure: function(transport) {
		this.addToCartFailure(transport);
	},
	
	target: function () {
		//this.element.addClassName("target");
	},

	registerCartChangeCallback: function (callback) {
		if (Object.isFunction(callback)) {
			this.onCartChange = callback;
		}
	},

	unregisterCartChangeCallback: function () {
		this.onCartChange = null;
	},

	/**
	 * Executes the javascript in script tags within the element 'el'.
	 */
	evalHtml: function (el)
	{
		var scripts = el.getElementsByTagName("script");
		for (i = 0; i < scripts.length; i++) {
			eval(scripts[i].innerHTML.toString());
		}
	},
	
	/**
	 * Container movement moved up to this.element.parentNode to keep it
	 * from bouncing after the cart contents are updated
	 **/
	monitorScrollLocation: function (event) {
        var s = $(this.element.parentNode).cumulativeScrollOffset();
        if((this.initialOffset[1])<(s[1]+15)) { 
        	new Effect.Move(this.element.parentNode, { x: 0, y: s[1]-this.initialOffset[1]+15, mode:'absolute', duration: 0.3});
        } else if (this.initialOffset[1] >= s[1]) {
        	new Effect.Move(this.element.parentNode, { x: 0, y: 0, mode:'absolute', duration: 0.3});
        }
	},

	/**
	 * Fixes an IE6 issue where the modal close buttons have no height or width.
	 * See Ticket #131.
	 */
	findCloseBtn: function (modalId) {
		if (navigator.appVersion.match('MSIE 6.')) {
			setTimeout("$('" + modalId + "_close').innerHTML = ' ';", 2000);  // duration of fade-in
		}
	}
});