
var ShopBasket = {
	
	onload: null,
	products: [],
	
	_load: function() {
		ShopAPI.products_for_basket({}, function(products) {
			ShopBasket.products = products;
			if ($.isFunction(ShopBasket.onload) ) {
				ShopBasket.onload();
			}
		});
	},
	
	// takes a product and strips it down to its basket representation
	_product_to_basket: function(params, product, item_id) {

		// filter the types for each item down to those matching 
		// the product's sku - this should remove all types for all 
		// items apart from the single matching item/type
		$.each(product.item, function(i, item) {
			item.types = $.grep(item.types, function(type) {
				return type.sku == params.style_sku;
			});
		});
		
		// filter the items down to the one with the matched type
		product.item = $.grep(product.item, function(item) {
			return item.types.length == 1;
		});
		
		if (product.item.length != 1) {
			// something went wrong
			return null;
		}
		
		// set the other attributes of a basket product
		product.item[0].types[0]['selectedQty'] = params.selected_quantity;
		product.item[0].img = [{path: product.item[0].imgPath}];
		product['basketItemID'] = item_id;
		
		return product;

	},
	
	// internal method for adding/updating basket products
	// expects params: style_id, style_sku, selected_quantity
	// causes an update if params.basket_item_id is given
	_update_basket: function(url, params, callback, error_handler) {

		if (!$.isFunction(callback)) {
			callback = function() {return;};
		}
		if (!params['style_id'] || !params['style_sku'] || 
			!params['selected_quantity']) {
			return callback(false);
		}

		ShopAPI.get(url, params, function(xml) {

			var item_id = Number($(xml).find('basketItemID').attr('val'));
			if (item_id <= 0) {
				if ($.isFunction(error_handler)) {
					error_handler($(xml).find('errorType').attr('val'));
				}
				return callback(false);
			}
			
			ShopAPI.product(params, function(product) {
				product = ShopBasket._product_to_basket(params, product, item_id);
				if (!product) {
					return callback(false);
				}
				if (!params['basket_item_id']) {
					ShopBasket.products[ShopBasket.products.length] = product;
				} else {
					ShopBasket.products = $.map(ShopBasket.products, function(existing) {
						return item_id == existing.basketItemID ? product : existing;
					});
				}
				ShopAPI._clear_cached_product(params['style_id']);
				callback(true);
			});
			
		});
		
	},
	
	// add to basket
	add: function(params, callback, error_handler) {
		ShopBasket._update_basket('os_basket_product_add.aspx', 
			params, callback, error_handler);
	},
	
	// edit item in basket
	edit: function(params, callback, error_handler) {
		ShopBasket._update_basket('os_basket_product_edit.aspx', 
			params, callback, error_handler);
	},
	
	// remove product from basket
	// expects params.basket_item_id
	remove: function(params, callback) {
		
		if (!$.isFunction(callback)) {
			callback = function() {return;};
		}
		if (!params['basket_item_id']) {
			return callback(false);
		}

		ShopAPI.get('os_basket_product_remove.aspx', params, function(xml) {
			var success = $(xml).find('errorType').attr('val') == 'none';
			if (success) {
				$.each(ShopBasket.products, function(i, existing) {
					if (existing.basketItemID == params.basket_item_id) {
						ShopAPI._clear_cached_product(existing.styleID);
					}
				});
				ShopBasket.products = $.grep(ShopBasket.products, function(product) {
					return product.basketItemID != params.basket_item_id;
				})
			}
			callback(success);
		});

	},
	
	// returns sum of given function across basket products
	_sum: function(sum_func) {
		var sum = 0;
		$.each(ShopBasket.products, function(i, product) {
			sum += sum_func(product);
		});
		return sum;
	},

	// get the number of items in basket
	items: function() {
		return ShopBasket._sum(function(product) {
			return Number(product.item[0].types[0].selectedQty);
		});
	},
	
	// get the value of all items in basket
	cost: function() {
		return ShopBasket._sum(function(product) {
			return Number(product.item[0].types[0].selectedQty) * 
				Number(product.currentRetailPrice);
		});
	}

}

$(ShopBasket._load);


