/*
 * A maxshop style in javascript.
 * <p>Loads a basic style.
 * <br />The basic style will contain</p>
 * <ul>
 *		<li>styleId</li>
 *		<li>code</li>
 *		<li>description</li>
 *		<li>longDescription</li>
 *		<li>styleImage</li>
 *		<li>url</li>
 * </ul>
 * <p>The advanced style may contain</p>
 * <ul>
 *	<li>availableSizes</li>
 *	<li>availableColours</li>
 *	<li>items</li>
 *	<li>itemPrices</li>
 *	<li>price</li>
 * </ul>
 * @param {object} basicStyle The basic style infomation
 * @param {object} advancedStyle Advanced style information
 * @constructor
 * @requires maxshop
 */
maxshop.style = function(basicStyle, advancedStyle)
{
	var _id = basicStyle.styleId;
	var _code = basicStyle.code;
	var _description = basicStyle.description;
	var _longDescription = basicStyle.longDescription;
	var _image = basicStyle.styleImage;
	var _url = maxshop.urlPrefix + basicStyle.url;
	var _video = basicStyle.video;
	var _availableSizes;
	var _availableColours;
	var _items;
	var _price;
	var _itemPrices;

	var _colourAvailabilityMap;
	var _availableColourImageMap;

	var _sizeAvailabilityMap;
	var _colours;
	var _sizes;
	var _colourIdStr = 'maxshop_colour_';
	var _sizeIdStr = 'maxshop_size_';
	var _statusBoxId = 'selected_item_description';

	var _colourImages;
	var _itemImages;

	if( advancedStyle )
	{
		if( advancedStyle.availableSizes )
		{
			_availableSizes = advancedStyle.availableSizes;
		}

		if( advancedStyle.availableColours )
		{
			_availableColours = advancedStyle.availableColours;
		}

		if( advancedStyle.availableColourImageMap )
		{
			_availableColourImageMap = advancedStyle.availableColourImageMap;
		}

		if( advancedStyle.items )
		{
			_items = advancedStyle.items;
		}

		if( advancedStyle.price )
		{
			_price = advancedStyle.price;
		}
		
		if( advancedStyle.colourImages )
		{
			_colourImages = advancedStyle.colourImages;
		}

		if( advancedStyle.itemImages )
		{
			_itemImages = advancedStyle.itemImages;
		}

		if( advancedStyle.itemPrices )
		{
			_itemPrices = advancedStyle.itemPrices;
		}
	}


	/*
	 * Get the style description.
	 * @param {boolean} withLink If true will wrap description in a link to the style.
	 * @return string
	 */
	this.getDescription = function(withLink)
	{
		if( withLink )
		{
			return returnWithLink(_description);
		}
		return _description;
	}

	/*
	 * Get the style description.
	 * @return string
	 */
	this.getId = function()
	{
		return _id;
	}

	/*
	 * Get the style url.
	 * @return string
	 */
	this.getUrl = function()
	{
		return _url;
	}

	/*
	 * Get the style code.
	 * @return string
	 */
	this.getCode = function()
	{
		return _code;
	}

	/*
	 * Get the price.
	 * @return string
	 */
	this.getPrice = function()
	{
		return _price.value;
	}

	/**
	 * Get a video link for the style.
	 * @return A jQuery a tag
	 */
	this.getVideoLink = function()
	{
		// If no video has been uploaded, don't display link
		if( _video == null )
		{
			return "";
		}

		var link = $('<a href="javascript:;" class="catwalk">view catwalk</a>');
		link.click( switchImgForVideo )
		return link;
	}

	/*
	 * Get a long description of the style.
	 * If charLimit it will split the string to charLimit and add a more link to the style.
	 * @param {int} charLimit
	 * @return string
	 */
	this.getLongDescription = function(charLimit)
	{
		var returnDesc = _longDescription;
		if( charLimit )
		{
			var description = _longDescription.substr(0, charLimit);
			if( description.length != _longDescription.length )
			{
				description += ' ... <a href="' + _url + '" title="read more about ' + _description  + '" >more</a>';
			}
			returnDesc = description;
		}

		return returnDesc;
	}

	/*
	 * Create a thumbnail of the style.
	 * @param {int,null} width
	 * @param {int,null} height Width must be specified.
	 * @param {boolean} withLink Wether the link should be wrapped in a link to the item
	 * @return jquery &#60;img&#62;
	 */
	this.getThumbnail = function(width, height, withLink)
	{
		var img = "";

		if( _image )
		{
			var url = createThumbnailUrl(_image.image.imageId,_image.image.urlName, width, height);
			img = makeImg(url, width, height);
			if( withLink )
			{
				return returnWithLink(img);
			}
		}

		return img;
	}

	/*
	 * Return a list of available colours in a list
	 * @return jQuery
	 */
	this.getColourList = function()
	{
		var ul = $('<ul></ul>');
		ul.addClass('colour_list');

		for( var i in _availableColours )
		{
			var colour = _availableColours[i];
			var li = $('<li></li>');

			var colourHtml = $('<div>' + colour.description + '</div>');

			if( _availableColourImageMap[colour.colourId] )
			{
				var imageThumbUrl = createThumbnailUrl(_availableColourImageMap[colour.colourId].media.imageId, _availableColourImageMap[colour.colourId].media.urlName, 45, 45);

				colourHtml = $('<img src="' + imageThumbUrl + '" border="0" width="45" height="45" />');

				var imageUrl = createThumbnailUrl(_availableColourImageMap[colour.colourId].media.imageId, _availableColourImageMap[colour.colourId].media.urlName, 100, 100);

				colourHtml.popup(
				{
					ajax: false,
					popupClass: 'jqueryPopup colour_list_popup',
					horizontal: 'left',
					left: 85,
					text: '<div class="popup_text colour_list_popup"><img src="' + imageUrl + '" border="0" width="100" height="100" /><p>' + colour.description + '</p></div>'
				});
			}
			
			li.append(colourHtml);

			li.click(function()
			{
				switchColour($(this));
			})
			li.attr('id', _colourIdStr + colour.colourId);

			ul.append(li);
		}


		return ul;
	}


	/*
	 * Return a list of available colours in a list
	 * @return jQuery
	 */
	this.getSizeList = function()
	{
		var ul = $('<ul></ul>');
		ul.addClass('size_list');

		for( var i in _availableSizes )
		{
			var size = _availableSizes[i];
			var li = $('<li></li>');
			li.append(size.description);
			li.click(function()
			{
				switchSize($(this));
			})
			li.attr('id', _sizeIdStr + size.sizeId);

			ul.append(li);
		}

		return ul;
	}

	this.getSelectedItem = function()
	{
		var selectedSizeId;
		var selectedColourId;

		generateAvailablityMap();

		if( $('.colour_list .active').length > 0 )
		{
			selectedColourId = $('.colour_list .active').attr('id').substr(_colourIdStr.length);
		}

		if( $('.size_list .active').length > 0 )
		{
			selectedSizeId = $('.size_list .active').attr('id').substr(_sizeIdStr.length);
		}

		return findItem(selectedSizeId, selectedColourId);
	}

	this.selectOptionDefaults = function()
	{
		if( _availableColours.length == 1 )
		{
			switchColour($('#' + _colourIdStr + _availableColours[0].colourId));
		}

		if( _availableSizes.length == 1 )
		{
			// Round to select the middle size.
			switchSize($('#' + _sizeIdStr + _availableSizes[0].sizeId));
		}
	}

	//
	//  Private functions
	//  -------------------------------
	//

	/*
	 * Create a img tag for the style
	 * @param {string} url
	 * @param {int} width
	 * @param {int} height
	 */
	function makeImg(url, width, height)
	{
		var img = $('<img src="' + url + '" alt="' + _image.description +  '" title="' + _image.title + '"/>');

		if( width )
		{
			img.attr('width', width);
		}

		if( height )
		{
			img.attr('height', height);
		}

		return img;
	}

	/**
	 * Switch the current image for the video.
	 */
	function switchImgForVideo()
	{
		$('#style_display_left .dropshadow_innerbox a.imageLink').hide();
		$('#zoom_images_link').hide();

		if( $("#catwalk").length > 0 )
		{
			$("#catwalk").show();
		}
		else
		{
			$('#style_display_left .dropshadow_innerbox a.imageLink').after("<div id='catwalk'>");

			if (_video.url.substr(_video.url.length - 4) == ".flv" )
			{
				maxshop.style.insertCatwalkVideo(_video.url);
			}
			else
			{
				maxshop.style.insertCatwalkVideo(_video.url + ".flv");
			}

			// Record the catwalk hit with an AJAX request.
			$.getJSON(maxshop.urlPrefix + "/style/catwalkhit/" + _code + "/", function (data)
			{
				if (data.success == false)
				{
					alert("Failed to record hit.");
				}
			});
		}

		$(this).unbind("click");
		$(this).html("view images");
		$(this).click(switchVideoForImg);
	}

	this.switchVideoForImg = switchVideoForImg;
	this.switchImgForVideo = switchImgForVideo;

	/**
	 * Switch the video for the current image.
	 * @param {object} event
	 * @param {object} element The link of the view catwalk, if not specified it will use (this)
	 */
	function switchVideoForImg( event, element)
	{
		if( $("#catwalk").length > 0 )
		{
			$("#catwalk").remove();
			$('#style_display_left .dropshadow_innerbox a.imageLink').show();

			if( !element )
			{
				element = this;
			}

			$(element).unbind("click");
			$(element).html("view catwalk");
			$(element).click(switchImgForVideo);
		}

		$('#zoom_images_link').show();
	}

	/*
	 * Switch the colour and corrisponding sizes.
	 * @param {jQuery} li A jquery object of the li
	 */
	function switchColour(li)
	{
		// Return straight away if disabled
		if( li.hasClass('disabled') )
		{
			return false;
		}

		$('.colour_list > li').removeClass('active');
		li.addClass('active');

		updateColourSizeStatus();

		return true;
	}

	/*
	 * Switch the size and corrisponding colours.
	 * @param {jQuery} li A jquery object of the li
	 */
	function switchSize(li)
	{
		// Return straight away if disabled
		if( li.hasClass('disabled') )
		{
			return false;
		}

		$('.size_list > li').removeClass('active');
		li.addClass('active');

		updateColourSizeStatus();

		return true;
	}

	/**
	 * Create a thumbnail url.
	 * @param {int} mediaId
	 * @param {string} description
	 * @param {int} width
	 * @param {int} height
	 */
	function createThumbnailUrl(mediaId, description, width, height)
	{
		var tString = '/c=';
		if( width )
		{
			tString += width
			if( height )
			{
				tString += ',' + height;
			}
		}
		tString += '/';

		var url = _image.image.path + mediaId + tString + description;

		return url;
	}

	/*
	 * Find an item based on size and colour.
	 * This is used to find a distinct item from a styles list of items.
	 * @param {int} sizeId
	 * @param {int} colourId
	 * @return {object} A maxshop.item object
	 */
	function findItem(sizeId, colourId)
	{
		var returnItem;
		for( var i in _items )
		{
			var item = _items[i];
			if( (item.size.sizeId == sizeId) && (item.colour.colourId == colourId) )
			{
				var itemPrice = findItemPrice(item.itemId);
				returnItem = new maxshop.item(item, {
					itemPrice:itemPrice
				});
			}
		}

		return returnItem;
	}

	/**
	 * Find the item price from an itemId
	 */
	function findItemPrice( itemId )
	{
		// Loop through the itemPrices until we find a matching price.
		for( itemPrice in _itemPrices )
		{
			if( itemId == _itemPrices[itemPrice].maxItem.itemId )
			{
				if( _itemPrices[itemPrice].price.value == _itemPrices[itemPrice].original.value )
				{
					return _itemPrices[itemPrice].price.value;
				}
				else
				{
					return "Now " + _itemPrices[itemPrice].price.value;
				}
			}
		}
		// Not found.
		return null;
	}

	/**
	 * Find the item price from an itemId
	 */
	function findItemWasPrice( itemId )
	{
		// Loop through the itemPrices until we find a matching price.
		for( itemPrice in _itemPrices )
		{
			if( itemId == _itemPrices[itemPrice].maxItem.itemId )
			{
				if( _itemPrices[itemPrice].price.value != _itemPrices[itemPrice].original.value )
				{
					return "Was " + _itemPrices[itemPrice].original.value;
				}
			}
		}
		// Not found.
		return null;
	}

	/*
	 * Update the colour size selection with the current information
	 */
	function updateColourSizeStatus()
	{
		var selectedSizeId;
		var selectedColourId;
		
		generateAvailablityMap();
		var item;

		if( $('.colour_list .active').length > 0 )
		{
			selectedColourId = $('.colour_list .active').attr('id').substr(_colourIdStr.length);
			$('.size_list > li').addClass('disabled');
			for( var i in _colourAvailabilityMap[selectedColourId] )
			{
				item = _colourAvailabilityMap[selectedColourId][i];
				// Check the price, don't allow free items.'
				if( findItemPrice(item.itemId) != 'Free' )
				{
					$('#' + _sizeIdStr + item.size.sizeId).removeClass('disabled');
				}
			}
		}

		if( $('.size_list .active').length > 0 )
		{
			selectedSizeId = $('.size_list .active').attr('id').substr(_sizeIdStr.length);
			$('.colour_list > li').addClass('disabled');
			for( var j in _sizeAvailabilityMap[selectedSizeId] )
			{
				item = _sizeAvailabilityMap[selectedSizeId][j];
				// Check the price, don't allow free items.'
				if( findItemPrice(item.itemId) != 'Free' )
				{
					$('#' + _colourIdStr + item.colour.colourId).removeClass('disabled');
				}
			}
		}

		var itemDescription = 'Please select an item';
		if( selectedColourId && selectedSizeId)
		{
			itemDescription = '<b>Selection:</b> ' + _colours[selectedColourId].description + ', ' + _sizes[selectedSizeId].description;

			// Update the selected price.
			for( var i in _itemPrices )
			{
				if( _itemPrices[i].maxItem.colour.colourId == selectedColourId && _itemPrices[i].maxItem.size.sizeId == selectedSizeId )
				{
					var wasPrice = findItemWasPrice(_itemPrices[i].maxItem.itemId);
					var priceHtml = '';
					if( wasPrice != null )
					{
						priceHtml += '<span class="price_was">' + wasPrice + '</span><br />';
						priceHtml += '<span class="price_now">';
					}
					priceHtml += findItemPrice(_itemPrices[i].maxItem.itemId);
					if( wasPrice != null )
					{
						priceHtml += '</span>';
					}

					$('#add_to_shopping_bag p.price').html(priceHtml);
				}
			}
		}

		if( selectedColourId && !selectedSizeId )
		{
			itemDescription = "Please select a size";
		}

		if( !selectedColourId && selectedSizeId )
		{
			itemDescription = "Please select a colour";
		}

		var selectedItem = findItem(selectedSizeId, selectedColourId)

		var selectedImg;
		if( _colourImages && _colourImages[selectedColourId] )
		{
			selectedImg = _colourImages[selectedColourId];
		}


		if( selectedItem )
		{
			if( selectedItem.getAvailabilityStatus() != "AVAILABLE" )
			{
				itemDescription += "<br /><span class='availability'>" + selectedItem.getAvailabilityDescription();

				// If its delayed add the delayed date
				if( selectedItem.getAvailabilityStatus() == "DELAYED" )
				{
					itemDescription += ": " + selectedItem.getAvailabilityDate().toLocaleDateString();
				}

				itemDescription += "</span>";
			}

			if( _itemImages && _itemImages[selectedItem.getId()] )
			{
				selectedImg = _itemImages[selectedItem.getId()];
			}
		}

		if( selectedImg )
		{
			switchImage(selectedImg.thumbnailUrl, selectedImg.url, selectedImg.description);
		}
		
		$('#' + _statusBoxId).html(itemDescription);
	}

	/*
	 * Create a list of Colour to Size and Sizes to Colour
	 */
	function generateAvailablityMap()
	{
		// Only generate them if they have not already been generated
		if( !_colourAvailabilityMap )
		{
			var coloursAvailability = new Array();
			var sizesAvailability = new Array();
			var colours = new Array();
			var sizes = new Array();
			for( var i in _items )
			{
				var item = _items[i];
				// Create the colour array if it does not exist
				if( !coloursAvailability[item.colour.colourId] )
				{
					coloursAvailability[item.colour.colourId] = new Array();
				}

				// Create the size array if it does not exist
				if( !sizesAvailability[item.size.sizeId] )
				{
					sizesAvailability[item.size.sizeId] = new Array();
				}

				coloursAvailability[item.colour.colourId].push(item);
				sizesAvailability[item.size.sizeId].push(item);

				colours[item.colour.colourId] = item.colour;
				sizes[item.size.sizeId] = item.size;
			}

			_colourAvailabilityMap = coloursAvailability;
			_sizeAvailabilityMap = sizesAvailability;
			_colours = colours;
			_sizes = sizes;
		}
	}

	/*
	 * Return the item wrapped in a link to the style
	 * @param {jQuery} item The object that needs to be wrapped
	 */
	function returnWithLink(item)
	{
		var link = $('<a href="' + _url + '" title="' + _description + '"></a>');
		link.append(item);
		return link;
	}
}

//
//  Static functions
//  -------------------------------
//

/*
 * Do an ajax request for a style.
 * @param {string} code
 * @param {function} callback First param will be the style
 * @param {function} error A function to run on error
 * @extends maxshop.style
 */
maxshop.style.getByCode = function(code, callback, error)
{
	$.ajax({
		dataType:'json',
		error: error,
		success:function(data)
		{
			var style = new maxshop.style(data.style, {
				availableSizes:data.availableSizes,
				availableColours: data.availableColours,
				items:data.items,
				price:data.currentPrice.price,
				availableColourImageMap: data.availableColourImageMap,
				itemPrices: data.itemPrices
			});
			callback(style);
		},
		url:maxshop.urlPrefix + '/style/' + code + '/json/'
	});
}

/**
 *	Insert the catwalk video into the "catwalk" element.
 *
 *	@param {string} file
 *	@param {boolean} automaticStart - Will automatically default to true
 */
maxshop.style.insertCatwalkVideo = function( file, automaticStart )
{
	if( null == automaticStart )
	{
		automaticStart = true;
	}
	
	var flashvars = {
		file: file,
		skin:"/flash/player/stylish_slim.swf",
		controlbar:"over",
		autostart: automaticStart,
		backcolor:"876B51",
		frontcolor:"EEEEEE",
		screencolor:"c6c1bd",
		lightcolor:"EEEEEE"
	};

	swfobject.embedSWF("/flash/player.swf", "catwalk", "305", "390", "9.0.0", "/flash/player.swf", flashvars);

	maxshop.style.catwalkvideo= swfobject
}

