


// set the domain to the top level
var host = location.hostname;
if (host.indexOf('sportsgirl.')>-1) {
   document.domain = host.substr(host.indexOf('sportsgirl.'));
}


var ShopAPI = {
	
	//host: 'http://shop.' + document.domain,
	host: 'http://shop.sportsgirl.com.au',

	// make a call to the shop backend via the iframe
	get: function(url, params, callback) {
		try {
			var frame_get = window.frames['api_frame'].shop_get;
			frame_get(url, params, callback);
		} catch (e) {
			// call self again if api frame isn't loaded
			window.setTimeout(function() {
				ShopAPI.get(url, params, callback);
			}, 500);
		}
	},
	
	// assigns a product get func to the shop api using the func name and url
	_make_products_getter: function(name, url) {
		ShopAPI[name] = function(params, callback) {
			if (!$.isFunction(callback)) {return;}
			ShopAPI.get(url, params, function(xml) {
				var products = $.xmlToJSON(xml)['product'];
				if (!$.isArray(products)) {
					products = [];
				}
				callback(products);
			});
		};
	},

	// convert the tag types to their querystring params for the products get
	products_for_tags: function(tags, limit, callback) {
		
		limit = (typeof limit == 'undefined') ? 0 : limit;
		
		var values = function(type, attr) {
			var get_type = function(tag) {
				return tag.type[0].Text == type;
			};
			var get_attr = function(tag) {
				return $.isArray(tag[attr]) ? tag[attr][0].Text: tag[attr];
			};
			return $.map($.grep(tags, get_type), get_attr);
		};
		
		var params = {
			tag: values('sportsgirl', 'name'), dept: values('department', 'id'),
			cat: values('category', 'id'), filter: values('filter', 'id'),
			limit: limit
		};
		
		ShopAPI.products(params, callback);
		
	},

	// search content for valid tags and return products for the tags
	products_for_content: function(contents, limit, callback) {
		if (!$.isFunction(callback)) {return;}
		ShopAPI.get('os_get_tags.aspx', {}, function(xml) {
			
			// filter tags to the tags found in content
			var tags = $.grep($.xmlToJSON(xml).tag, function(tag) {
				var found = $.grep(contents, function(content) {
					return $(content).text().toLowerCase().indexOf(
						tag.name[0].Text.toLowerCase()) >= 0;
				})
				return found.length > 0;
			});
			
			// query api for all products for tags found
			if (tags.length > 0) {
				ShopAPI.products_for_tags(tags, limit, callback);
			}

		});
	},
	
	// get the full data for a single product and store its xml in the cache 
	// against its style id on the first lookup for retrieving on subsequent lookups
	
	// we store the product xml in the cache and parse it each time so that we 
	// get a copy of the product that can be modified without effecting the cache
	
	// the value in the cache will initially be a queued list of all the callbacks 
	// that have been requested which are then called once the data is returned

	_product_cache: {},
	product: function(params, callback) {
		
		if (!$.isFunction(callback) || !params['style_id']) {return;}
		
		// check cache
		var cached = ShopAPI._product_cache[params.style_id];
		if (cached) {
			if ($.isArray(cached)) {
				// product requested but not yet returned
				// cache is queued callbacks, append to them
				ShopAPI._product_cache[params.style_id][cached.length] = callback;
				return;
			} else {
				// cache is product xml, call callback
				return callback($.xmlToJSON(cached));
			}
		}
		
		// create the callback queue on first request
		ShopAPI._product_cache[params.style_id] = [callback];

		// on return of product xml, push into cache and call queued callbacks
		ShopAPI.get('os_product_detail.aspx', params, function(xml) {
			var callbacks = ShopAPI._product_cache[params.style_id];
			ShopAPI._product_cache[params.style_id] = xml;
			$.each(callbacks, function(i, callback) {
				ShopAPI.product(params, callback);
			});
		});
		
	},
	
	// remove a product from the cache (called when modified in basket) so the 
	// available quantity for the product will be fresh from the server 
	_clear_cached_product: function(style_id) {
		ShopAPI._product_cache[style_id] = null;
	},

	// get category menu structure
	categories: function(callback) {
		ShopAPI.get('xml/os_menu_bridge.aspx', {}, callback);
	},

	// deeplink url for a product on the shop site given a style id
	product_url: function(style_id) {
		return ShopAPI.host + '/?style_id=' + style_id;
	}

};


// make the product get functions with the name/url mapping
$.each({
	
	products_for_category: 'os_product_gallery.aspx',
	products_unassigned: 'os_product_gallery_unassigned.aspx',
	products_for_basket: 'os_basket_product_list.aspx',
	products: 'os_product_gallery_params.aspx'
	
}, ShopAPI._make_products_getter);


// add the hidden api iframe to the document
$(function() {
	$('body').append('<iframe style="display:none;" name="api_frame" ' +
		'src="' + ShopAPI.host + '/api/"></iframe>')
});

