// global namespace
var MA = {};

if (typeof(jQuery) != 'undefined') {
	$(document).ready(function () {

		// IE6
		if ($.browser.msie && $.browser.version < 8) {
			$(document.body).addClass('MSIE6');
		}

		// Opacity
		$('[opacity]').each(function (i, e) {
			$(this).fadeTo(0, $(this).attr('opacity'));
		});
	});
}

/* Browse Menu */

function initNav () {
	$(document).ready(function () {

		var nav = $('#nav');
		var container = $('#pageContainer');

		// don't toggle on home
		if ($(document.body).attr('id') != 'index-index') {
			// IE6 fails on so many levels
			if (!($.browser.msie && $.browser.version < 7)) {
				$('#departmentsDrop').click(function (e) {
					if (nav.css('display') == 'none') {
						$(document).trigger('showLayer');
						nav.show();
						container.removeClass().addClass('nav-expanded');
					}
					else {
						hideNav();
					}
					$(document.body).focus();
					e.stopPropagation();
					e.preventDefault();
				});
			}
		}
		else {
			nav.show();
			container.addClass('nav-on');
		}

		$(document).click(hideNav);
		$(document).bind('showLayer', hideNav);
	});
}

function hideNav ()
{
	hideDrops();
	$('#subnav').hide();
	if ($(document.body).attr('id') != 'index-index') {
		$('#nav').hide();
		$('#pageContainer').removeClass();
	}
}

function toggleDrop(e, category)
{
	var toggleNav = $('#navSub' + category);
	var nav = $('#nav');
	var subnav = $('#subnav');

	// create jquery event object from browser event
	var e = new jQuery.Event(e);

	// store the display setting before we change it below
	var display = toggleNav.css('display');

	hideDrops();

	if (display == 'none') {
		$('li#category' + category).addClass('active');
		nav.addClass('dropped');
		nav.removeClass('undropped');
		$('ul#navSub' + category).show();

		subnav.show();
	}
	else {
		subnav.hide();
	}

	$(document).focus();
	e.stopPropagation();
}

function hideDrops()
{
	var nav = $('#nav');

	// de-activate all items
	$('#nav > li.droppable').removeClass('active');
	nav.removeClass('dropped');
	nav.addClass('undropped');

	// hide all sub navs
	$('ul.nav-sub').hide();
}

/* Search Box */

function setSearchFocusCssClass(element) {
	if (element.value=='Search...') {
		element.value='';
	}
	element.className = 'searchInputActive';
}
function unsetSearchFocusCssClass(element) {
	if (element.value=='') {
		element.value='Search...';
		element.className = 'searchInput';
	}
}

function setCategorySearchFocusCssClass(element, textValue) {
	if (element.value==textValue) {
		element.value='';
	}
	element.className = 'searchInputActive';
}
function unsetCategorySearchFocusCssClass(element, textValue) {
	if (element.value=='') {
		element.value=textValue;
		element.className = 'searchInput';
	}
}

/* Header: Trolley Info */

function updateHeaderTrolleyInfo (trolleyItemCount, trolleySubtotal, freeShippingHtml)
{
	$('#trolleyInfo a.items').html('<b>'+trolleyItemCount+'</b> item'+(trolleyItemCount != 1 ? 's' : '')+' in trolley');
	$('#trolleyInfo span.price').html(trolleySubtotal);

	if ($('#freeShipping').length == 0)
	{
		$('#trolleyInfo').append('<div id="freeShipping" class="freeShipping"></div>');
	}
	if (freeShippingHtml)
	{
		$('#freeShipping').replaceWith(freeShippingHtml);
		$('#trolleyInfo').addClass('freeShipping').removeClass('noFreeShipping');
	}
	else
	{
		$('#freeShipping').remove();
		$('#trolleyInfo').addClass('noFreeShipping').removeClass('freeShipping');
	}
}

/* Header: Account Menus */

MA.headerMenu = function () {
	return {
		show: function (e, menuID, buttonID, eventNS) {
			$(document).trigger('showLayer');
			$('#'+menuID).show();
			$('#'+buttonID).addClass('menu');
			$(document).bind('click.'+eventNS+' showLayer', function (e) { MA.headerMenu.hide(e, menuID, buttonID, eventNS) });
			$('#'+menuID).bind('click.'+eventNS, function (e) {
				e.stopPropagation();
			});
			$('#headerLoginEmail').focus();
		}
	,	hide: function (e, menuID, buttonID, eventNS) {
			$('#'+menuID).hide();
			$('#'+buttonID).removeClass('menu');
			$(document).unbind('click.'+eventNS);
		}
	,	toggle: function (e, menuID, buttonID, eventNS) {
			if ($.browser.msie && $.browser.version < 7) return true;

			// create jquery event object from browser event
			var e = new jQuery.Event(e);
			e.preventDefault();
			e.stopPropagation();

			if ($('#'+menuID).css('display') == 'none') {
				MA.headerMenu.show(e, menuID, buttonID, eventNS);
			} else {
				MA.headerMenu.hide(e, menuID, buttonID, eventNS);
			}

			return false;
		}
	}
}();

MA.headerAccountMenu = function () {
	var menuID = 'headerAccountMenu';
	var buttonID = 'headerAccountButton';
	var eventNS = 'MA_'+menuID;

	return {
		show: function (e) {
			MA.headerMenu.show(e, menuID, buttonID, eventNS);
		}
	,	hide: function (e) {
			MA.headerMenu.hide(e, menuID, buttonID, eventNS);
		}
	,	toggle: function (e) {
			MA.headerMenu.toggle(e, menuID, buttonID, eventNS);
		}
	}
}();

MA.headerLoginMenu = function () {
	var menuID = 'headerLoginMenu';
	var buttonID = 'headerLoginButton';
	var eventNS = 'MA_'+menuID;

	return {
		show: function (e) {
			MA.headerMenu.show(e, menuID, buttonID, eventNS);
		}
	,	hide: function (e) {
			MA.headerMenu.hide(e, menuID, buttonID, eventNS);
		}
	,	toggle: function (e) {
			MA.headerMenu.toggle(e, menuID, buttonID, eventNS);
		}
	}
}();

/* Misc */

function bookmarkPage(title, url){
	if(document.all) {
		window.external.AddFavorite(url, title);
	}
}

function getOpenWindowsSettings(width,height,scroll,menubar,toolbar,status) {
	var startLeft = (screen.width-width)/2;
	var startTop = (screen.height-height)/2;
	var settings  ='height='+height+',';
	settings +='width='+width+',';
	settings +='top='+startTop+',';
	settings +='left='+startLeft+',';
	settings +='scrollbars='+scroll+',';
	settings +='menubar='+menubar+',';
	settings +='toolbar='+toolbar+',';
	settings +='status='+status+',';
	settings +='resizable=yes';
	return settings;
}

function popupWindow(url,name,width,height) {
	settings = getOpenWindowsSettings(width, height, 'yes', 'yes', 'yes', 'yes');
	window.open(url,name,settings);
}

function popupWindowSettings(url,name,width,height,scroll,menubar,toolbar,status) {
	settings = getOpenWindowsSettings(width,height,scroll,menubar,toolbar,status);
	window.open(url,name,settings);
}

function shareMySpace(title, content, url, l)
{
	var targetUrl = 'http://www.myspace.com/index.cfm?fuseaction=postto&' + 't=' + encodeURIComponent(title)
	+ '&c=' + encodeURIComponent(content) + '&u=' + encodeURIComponent(url) + '&l=' + l;
	window.open(targetUrl);
	return false;
}


function shareDelicious() { window.open('http://del.icio.us/post?v=4&noui&jump=close&url='+encodeURIComponent(location.href)+'&title='+encodeURIComponent(document.title), 'delicious','toolbar=no,width=700,height=400'); return false; }
function shareFacebook() { u=location.href;t=document.title;window.open('http://www.facebook.com/sharer.php?u='+encodeURIComponent(u)+'&t='+encodeURIComponent(t),'sharer','toolbar=0,status=0,width=626,height=436');return false; }
function shareWishlistFacebook() { u=location.href;window.open('http://www.facebook.com/share.php?u='+encodeURIComponent(u),'sharer','toolbar=0,status=0,width=626,height=436');return false; }

// cookies
function createCookie(name, value, days)
{
	if (days) {
		var date = new Date();
		date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
		var expires = "; expires="+date.toGMTString();
	}
	else {
		var expires = "";
	}
	document.cookie = name + "=" + value + expires + "; path=/";
}

function readCookie (name)
{
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for (var i=0; i < ca.length; i++)
	{
		var c = ca[i];
		while (c.charAt(0) == ' ')
		{
			c = c.substring(1, c.length);
		}
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
	}
	return null;
}

function eraseCookie(name)
{
	createCookie(name, "" , -1);
}

function setRefString(string)
{
	document.cookie = "linkRef=" + string + "; path=/";
	return true;
}

function number_format(number, decimals, dec_point, thousands_sep) {
    // Formats a number with grouped thousands
    //
    // version: 1004.1212
    // discuss at: http://phpjs.org/functions/number_format
    var n = !isFinite(+number) ? 0 : +number,
        prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
        sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
        dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
        s = '',
        toFixedFix = function (n, prec) {
            var k = Math.pow(10, prec);
            return '' + Math.round(n * k) / k;
        };
    // Fix for IE parseFloat(0.55).toFixed(0) = 0;
    s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
    if (s[0].length > 3) {
        s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
    }
    if ((s[1] || '').length < prec) {
        s[1] = s[1] || '';
        s[1] += new Array(prec - s[1].length + 1).join('0');
    }
    return s.join(dec);
}

// "Welcome to Mighty Ape" notification bar hider
function hideWelcome()
{
	createCookie('HideWelcomeBar', 'true', 1000);
	var welcome = document.getElementById('welcomeBar');
	welcome.style.display = 'none';
	return false;
}

function loadProducts(listId, direction, tracking, params)
{
	var page = $('#listPage_' + listId).val();
	var totalPages = $('#listMaxPages_' + listId).val();

	// generate base url
	var requestUrl = '/ajax/products/get-list-products/direction/' + direction + '/page/' + page + '/tracking/' + tracking + '/';

	var listContainer = $('#listContainer_'+listId);
	listContainer.addClass('loading');

	// do request passing in an extra params that are required
	jQuery.getJSON(requestUrl, params, function (data) {
		// manually make the button go back to inactive state in MSIE
		window.focus();

		// store the new page number
		$('#listPage_' + listId).val(data.page);

		// update the pages count
		$('#listPageLabel_' + listId).html(data.pagesLabel);

		// replace items
		for (i = 0; i < data.items.length; i++) {
			containerId = 'listItems_' + listId + '_item' + (i + 1);
			$('#' +containerId).html(data.items[i]);
		}

		// toggle prev/next arrows
		if (data.page == '1') {
			$('#listPrev_' + listId).hide();
		}
		else {
			$('#listPrev_' + listId).show();
		}

		if (data.page == totalPages) {
			$('#listNext_' + listId).hide();
		}
		else {
			$('#listNext_' + listId).show();
		}

		listContainer.removeClass('loading');

		// enable link tracking for dynamic content
		listContainer.find('[id^="T_"]').mousedown(function() { setRefString(this.id); });
	});
}

function closeNotice(container)
{
	$('#' + container).animate({top: -70}, 'slow', function () { $('#' + container).hide(); } );
}

function getAdvertisement(advertisementSlot, advertisementType, storeId, zoneId, categoryId)
{
	if (zoneId == '') {
		zoneId = 0;
	}
	if (categoryId == '') {
		categoryId = 0;
	}
	var requestUrl = '/ajax/advertisement/get-advertisement/storeId/' + storeId + '/advertisementType/' + advertisementType + '/zoneId/' + zoneId + '/categoryId/' + categoryId + '/?' + new Date().getTime();

	jQuery.getJSON(requestUrl, function (data) {
		if (data.response != 0) {
			$('#advertisement-' + advertisementSlot).html(data.response);
			$('#advertisement-' + advertisementSlot).fadeIn();
		}
	});
}

function AdvertisementStripStartTimer (id, timeRemaining)
{
	this.id = id;
	this.timeRemaining = timeRemaining;

	this.timer;

	// start the timer
	this.startTimer = function ()
	{
		this.renderTimer();
		this.timer = window.setInterval(this.id+'.timerTick()', 1000);
	}

	// update the timer (called every second)
	this.timerTick = function ()
	{
		this.timeRemaining--;

		if (this.timeRemaining < 0)
		{
			window.clearInterval(this.timer);
			// reload the page after a short delay
			window.setTimeout('window.location.reload(true)', 2000);
		}
		else
		{
			this.renderTimer();
		}
	}

	// render the timer
	this.renderTimer = function ()
	{
		var t = this.timeRemaining;
		var days = Math.floor(t / 86400); t -= days * 86400;
		var hours = Math.floor(t / 3600); t -= hours * 3600;
		var minutes = Math.floor(t / 60); t -= minutes * 60;
		var seconds = Math.floor(t);

		$('#'+this.id+'_days').html(days+'<span class="unit"> D </span>');
		if (days > 0)
		{
			// hours should be padded only if there are days
			$('#'+this.id+'_hours').html(padZero(hours)+'<span class="unit"> H </span>');
		}
		else
		{
			$('#'+this.id+'_hours').html(hours+'<span class="unit"> H </span>');
		}
		$('#'+this.id+'_minutes').html(padZero(minutes)+'<span class="unit"> M </span>');
		$('#'+this.id+'_seconds').html(padZero(seconds)+'<span class="unit"> S </span>');

		if (days == 0)
		{
			$('#'+this.id+'_days').hide();
		}
	}
}

function padZero (num)
{
	return ((num >= 0) && (num < 10)) ? "0" + num : num + "";
}

function preventDoubleClick(formId)
{
	$(formId).submit(function() {
		$('input[type=submit]', this).attr('disabled', 'disabled');
	});
}


/* JSON PARSER/STRINGIFIER (minified) */
/* from http://www.json.org/json2.js */

if(!this.JSON){this.JSON={};}
(function(){function f(n){return n<10?'0'+n:n;}
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}
var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}
function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}
if(typeof rep==='function'){value=rep.call(holder,key,value);}
switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}
v=partial.length===0?'[]':gap?'[\n'+gap+
partial.join(',\n'+gap)+'\n'+
mind+']':'['+partial.join(',')+']';gap=mind;return v;}
if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==='string'){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}
v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+
mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}
rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
return str('',{'':value});};}
if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
return reviver.call(holder,key,value);}
cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
throw new SyntaxError('JSON.parse');};}}());


/* JQUERY EVOLVE ANIMATION PLUGIN */

if (typeof(jQuery) != 'undefined') { (function($) {
	$.extend({
		evolve: function(source, target, callback, context)
		{
			var source_id = source.attr('id');
			var target_id = target.attr('id');

			target.css('visibility', 'hidden');

			var shadow = $('#'+source_id+'_shadow');
			if( !shadow.length ) {
			  $('body').prepend('<div id="'+source_id+'_shadow" style="display: none; background-color: #cccccc; position: static; top: 0px; z-index: 100000;" class="rounded">&nbsp;</div>');
			  var shadow = $('#'+source_id+'_shadow');
			}

			if( !shadow.length ) {
			  //alert('Cannot create the shadow div');
			  target.css('visibility', 'visible');
			  return;
			}

			shadow.width(source.outerWidth()).height(source.outerHeight()).css('top', source.offset().top).css('left', source.offset().left).fadeTo(0, 0.5).show();

			shadow.css({
				position: 'absolute'
			});

			shadow.animate(
				{
					width: target.outerWidth()
				,	height: target.outerHeight()
				,	top: target.offset().top
				,	left: target.offset().left
				}
			,	{ duration: 300 }
			)
			.fadeTo(0, 0, function ()
				{
					target.css('visibility', 'visible');
					shadow.remove();
					if (callback) callback.call(context);
				}
			);
		}
	});
})(jQuery); }


/* OVERLAY WINDOW */

function OverlayWindow (id)
{
	this.id = id;

	this.XHR = null;
	this.minWindowWidth = 800;
	this.minWindowHeight = 450;
	this.noIE6 = true;

	this.open = function (e, openerButton)
	{
		// don't display overlay if client window is too small, or we're in IE6
		if (this.minWindowWidth && $(window).width() < this.minWindowWidth) return true;
		if (this.minWindowHeight && $(window).height() < this.minWindowHeight) return true;
		if (this.noIE6 && $.browser.msie && $.browser.version < 7) return true;

		// create jquery event object from browser event
		var e = new jQuery.Event(e);

		// only try to display overlay after the DOM is ready
		$(document).ready( $.proxy(function ()
		{
			if ($('#blackOut').length == 0) {
				$(document.body).append('<div id="blackOut"></div>');
				$('#blackOut').fadeTo(0, 0.5);
			}
			else {
				$('#blackOut').fadeTo(0, 0.5);
				$('#blackOut').show();
			}

			// create overlay
			if ($('#'+this.id).length == 0)
			{
				$(document.body).append('<div id="'+this.id+'" class="overlay loading"></div>');
			}
			else
			{
				$('#'+this.id).addClass('loading');
				$('#'+this.id).empty();
				$('#'+this.id).show();
			}

			// create boxes
			$('#'+this.id).append('<div id="'+this.id+'OuterBox" class="overlayOuterBox" style="visibility:hidden"></div><div id="'+this.id+'Content" class="overlayContent" style="visibility:hidden"></div>');
			$('#'+this.id+'OuterBox').fadeTo(0, 0.5);

			// position boxes
			this.reposition();

			// outside click handler
			$('#'+this.id).bind('click.'+this.id, $.proxy(this.close, this));
			$('#'+this.id+'Content').bind('click.'+this.id, function (e) { e.stopPropagation(); });

			// escape key handler
			$(document).bind('keyup.'+this.id, $.proxy(this.close, this));

			// pseudo-event for sub-classes to initialise stuff before opening
			this.beforeOpen();

			// evolve animation (if openerButton exists and is displayed)
			if (openerButton.id && openerButton.offsetWidth > 0)
			{
				$.evolve($(openerButton), $('#'+this.id+'Content'), function () { $('#'+this.id+'OuterBox, #'+this.id+'Content').css('visibility', 'visible'); }, this);
			}
			else
			{
				$('#'+this.id+'OuterBox, #'+this.id+'Content').css('visibility', 'visible');
			}

			// window resize handler. NB: this must be registered after the evolve animation
			$(window).bind('resize.'+this.id, $.proxy(this.reposition, this));

			// load content
			this.load();

			// pseudo-event for subclasses to do housekeeping
			this.afterOpen();

		}, this));

		// stop default action
		e.stopPropagation();
		e.preventDefault();
		return false;
	}

	this.reposition = function (e)
	{
		var x = Math.floor(($(window).width() - $('#'+this.id+'OuterBox').width()) / 2);
		var y = Math.floor(($(window).height() - $('#'+this.id+'OuterBox').height()) / 2);

		if (x < -10) x = -10;
		if (y < -10) y = -10;

		$('#'+this.id+'OuterBox').css({
			left: x
		,	top: y
		});
		$('#'+this.id+'Content').css({
			left: x + 10
		,	top: y + 10
		});
	}

	this.close = function (e)
	{
		// only close on keyup if it's the Esc key
		if (e && (e.type == 'keyup' && e.which != 27)) return;

		this.beforeClose();

		// close overlay
		$('#blackOut').fadeOut(400);
		$('#'+this.id).hide(400, function () { $('#'+this.id).empty() });

		// remove handler
		$(document).unbind('keyup', this.close);

		this.afterClose();

		// stop this running more than once
		if (e)
		{
			e.preventDefault();
			e.stopPropagation();
		}
	}

	this.cleanup = function ()
	{
		// abort any ajax requests that may still be running
		if (this.XHR) this.XHR.abort();

		// remove old event handlers
		$(window).unbind('.'+this.id);
		$(document).unbind('.'+this.id);
	}

	// pseudo-event methods that may optionally be defined by subclasses
	this.beforeOpen = function () {};
	this.afterOpen = function () {};
	this.beforeClose = function () {};
	this.afterClose = function () {};

	// methods that should be defined by subclasses
	this.load = function () {};
	this.render = function () {};
}



/* TROLLEY OVERLAY */

function TrolleyOverlayWindow (products)
{
	$.extend(this, new OverlayWindow('trolleyOverlay'));

	this.products = products;

	this.minimisedHeight = 144;
	this.maximisedHeight = 420;
	this.outerBoxHeightDelta = 22;

	// pseudo-event handler for initialising prior to opening the overlay
	this.beforeOpen = function ()
	{
		// minimise
		$('#'+this.id+'Content').height(this.minimisedHeight);
		$('#'+this.id+'OuterBox').height(this.minimisedHeight+this.outerBoxHeightDelta);
	}

	// method to load the data (content)
	this.load = function ()
	{
		this.XHR = $.ajax(
		{
			url: '/trolley/add/overlay/format/json/'
		,	type: 'POST'
		,	data: { products: JSON.stringify(this.products), trolleyButtonId: $(this.trolleyButton).attr('id') }
		,	cache: false
		,	timeout: 30 * 1000
		,	dataType: 'json'
		,	context: this
		,	success: function (data, textStatus, XHR)
			{
				if (data.status == '2')
				{
					if (data.redirect)
					{
						window.location.href = data.redirect;
					}
					else
					{
						window.location.reload(true);
					}
				}
				else
				{
					this.render(data);
				}
			}
		,	error: function (XHR, textStatus, errorThrown)
			{
				alert('An error occurred while trying to add the item to your trolley: '+textStatus+'\n\n'+'Please click the Add to Trolley button again to retry.');
				this.close();
			}
		});
	}

	// method to take the loaded data and render it
	this.render = function (data)
	{
		$('#'+this.id).removeClass('loading');
		$('#'+this.id).removeClass('error');

		if (data.status == '1')
		{
			$('#'+this.id+'Content').html(data.html);

			// enable link tracking for dynamic content
			$('#'+this.id+'Content').find('[id^="T_"]').mousedown(function() { setRefString(this.id); });

			var arrows = $('#'+this.id+' div.loadable a.next');
			arrows.hide();

			if ($('#'+this.id+'RelatedProducts').length > 0)
			{
				$('#'+this.id+'OuterBox').delay(1000).animate({ height: this.maximisedHeight+this.outerBoxHeightDelta}, 'slow');
				$('#'+this.id+'Content').delay(1000).animate({ height: this.maximisedHeight }, 'slow');
				$('#'+this.id+'RelatedProducts').delay(1000).slideDown('slow', $.proxy(function () { arrows.fadeIn(); this.reposition(); }, this));
			}

			// update message in page header
			updateHeaderTrolleyInfo(data.trolleyItemCount, data.trolleySubtotal, data.freeShippingHtml);

			// reload the trolley, if we're on the trolley page
			if (typeof(reloadTrolley) != 'undefined') reloadTrolley();
		}
		else
		{
			$('#'+this.id).addClass('error');
			$('#'+this.id+'Content').html('<div class="trolleyOverlayError"><p><span class="errorTitle">Oops, something went wrong!</span></p><p>'+data.error+'</p><p><a href="/trolley/"><b>View Trolley</b></a></p></div>');
		}
	}
}

var trolleyOverlayWindowInstance = null;

function addToTrolley (products, trolleyButton, e)
{
	if (trolleyOverlayWindowInstance) trolleyOverlayWindowInstance.cleanup();

	trolleyOverlayWindowInstance = new TrolleyOverlayWindow(products);
	return trolleyOverlayWindowInstance.open(e, trolleyButton);
}

function closeTrolleyOverlay ()
{
	trolleyOverlayWindowInstance.close();
}

/* LIGHTBOX */

MA.Lightbox = function (galleryType, galleryId, imageId)
{
	$.extend(this, new OverlayWindow('lightbox'));
	this.minWindowWidth = 980;
	this.minWindowHeight = 525;
	this.noIE6 = true;

	this.galleryType = galleryType;
	this.galleryId = galleryId;
	this.galleryRef = galleryType+':'+galleryId;
	this.imageId = imageId;
	this.images = [];
	this.currentImageIndex = 0;

	// pseudo-event handler for initialising prior to opening the overlay
	this.beforeOpen = function ()
	{
	}

	// method to load the data (content)
	this.load = function ()
	{
		var data;

		// if we've already loaded this gallery before, get it from our cache
		if (data = MA.lightboxDataCache[this.galleryRef])
		{
			this.render(data);
		}
		else // otherwise fetch the gallery json
		{
			this.XHR = $.ajax(
			{
				url: '/ajax/lightbox/get-data/'
			,	type: 'POST'
			,	data: { type: this.galleryType, id: this.galleryId, img: this.imageId }
			,	cache: false
			,	timeout: 30 * 1000
			,	dataType: 'json'
			,	context: this
			,	success: function (data, textStatus, XHR)
				{
					if (data.status == '2')
					{
						if (data.redirect)
						{
							window.location.href = data.redirect;
						}
						else
						{
							window.location.reload(true);
						}
					}
					else
					{
						MA.lightboxDataCache[this.galleryRef] = data;
						this.render(data);
					}
				}
			,	error: function (XHR, textStatus, errorThrown)
				{
					alert('An error occurred while trying to open the image viewer: '+textStatus+'\n\n'+'Click the image again to retry.');
					this.close();
				}
			});
		}
	}

	// method to take the loaded data and render it
	this.render = function (data)
	{
		$('#'+this.id).removeClass('loading');
		$('#'+this.id).removeClass('error');

		if (data.status == '1')
		{
			this.images = data.images;

			var html = '<div class="overlayTitle">'
				+ '<a class="close" href="javascript:MA.closeLightbox();">Close</a>'
				+ '<a class="title" href="'+data.linkURL+'">'+data.title+'</a>'
				+ '<span class="count">Image <strong class="currentImageIndex">'+(this.currentImageIndex+1)+'</strong> of <strong class="totalImageCount">'+data.images.length+'</strong>'
				+ '</div>'
				+ '<div id="'+this.id+'Viewport"></div>'
				+ '<div id="'+this.id+'Thumbnails"><div id="'+this.id+'ThumbnailsContainer"></div><div id="'+this.id+'Triangle"></div></div>'
				+ '<div id="'+this.id+'PrevArrow" class="arrow"><div></div></div>'
				+ '<div id="'+this.id+'NextArrow" class="arrow"><div></div></div>'
			;
			$('#'+this.id+'Content').html(html);

			this.renderThumbnails();

			if (this.images.length > 1)
			{
				// events for arrows
				function arrowMouseover (e) {
					$('#'+e.data.context.id+' .arrow').stop().fadeTo(100, 0.66);
					$(this).stop().fadeTo(100, 1);
				}
				function arrowMouseout (e) {
					$(this).stop().fadeTo(100, 0.33);
				}
				function arrowMousedown (e) {
					$(this).addClass('mousedown');
				}
				function arrowMouseup (e) {
					$(this).removeClass('mousedown');
				}

				$('#'+this.id+' .arrow').fadeTo(0, 0)
					.bind('mouseover', { context: this }, arrowMouseover)
					.bind('mouseout', { context: this }, arrowMouseout)
					.bind('mousedown', { context: this }, arrowMousedown)
					.bind('mouseup', { context: this }, arrowMouseup);
				$('#'+this.id+'NextArrow').bind('click', $.proxy(this.nextImage, this));
				$('#'+this.id+'PrevArrow').bind('click', $.proxy(this.previousImage, this));

				$('#'+this.id+'Viewport').bind('mouseover', $.proxy(function () {
					$('#'+this.id+' .arrow').stop().fadeTo(100, 0.33);
				}, this)).bind('mouseout', $.proxy(function () {
					$('#'+this.id+' .arrow').stop().fadeTo(2000, 0);
				}, this));
			}
			else
			{
				// hide arrows if only 1 image in gallery
				$('#'+this.id+' .arrow').hide();
			}

			// Render image
			var foundImage = false;
			for (var i = 0; i < this.images.length; i++)
			{
				if (this.images[i].id == this.imageId)
				{
					this.renderImage(i);
					foundImage = true;
					break;
				}
			}
			if (!foundImage) this.renderImage(0);

			// Key handlers
			$(document).bind('keydown.'+this.id, $.proxy(function (e) {
				if (e.which == 37 || e.which == 38) {
					e.preventDefault();
					this.previousImage();
				}
				else if (e.which == 39 || e.which == 40) {
					e.preventDefault();
					this.nextImage();
				}
			}, this));

			$(document).bind('mousewheel', $.proxy(function (e, delta) {
				e.preventDefault();
				if (delta < 0) {
					this.nextImage();
				} else {
					this.previousImage();
				}
			}, this));
		}
		else
		{
			$('#'+this.id).addClass('error');
			$('#'+this.id+'Content').html('<div class="lightboxError"><p><span class="errorTitle">Woops, something went wrong!</span></p><p>'+data.error+'</p></div>');
		}
	}

	this.renderThumbnails = function ()
	{
		for (var i=0; i < this.images.length; i++)
		{
			var image = this.images[i];
			var size = this._getRatioSize(image.thumbnailWidth, image.thumbnailHeight, 110, 200);

			var img = new Image();
			img.src = image.thumbnailURL;
			img.width = size.width;
			img.height = size.height;
			if (i == 0) img.className = 'first';

			$(img).fadeTo(0, 0.75);
			$(img).bind('mouseover', function () {
				if (!$(this).hasClass('active')) $(this).stop().fadeTo(100, 1);
			});
			$(img).bind('mouseout', function () {
				if (!$(this).hasClass('active')) $(this).stop().fadeTo(500, 0.75);
			});
			$(img).bind('click', $.proxy(function (j) { return function () { this.renderImage(j); }; }(i), this));

			$('#'+this.id+'ThumbnailsContainer').append(img);
		}
	}

	this.renderImage = function (i)
	{
		var html = '';
		var image = this.images[i];
		if (!image) return false;

		var viewPort = $('#'+this.id+'Viewport');
		var size = this._getRatioSize(image.imageWidth, image.imageHeight, viewPort.innerWidth(), viewPort.innerHeight());

		var img = new Image();
		img.src = image.imageURL;
		img.width = size.width;
		img.height = size.height;
		img.style.left = size.left+'px';
		img.style.top = size.top+'px';

		$('#'+this.id+'Viewport img').fadeOut(500, function () { $(this).remove() });
		$('#'+this.id+'Viewport').prepend(img);

		// update the current image number
		this.currentImageIndex = i;
		$('#'+this.id+' .currentImageIndex').html(this.currentImageIndex + 1);

		// give the thumbnail active class
		$('#'+this.id+'Thumbnails img').removeClass('active').trigger('mouseout');
		var selectedThumb = $('#'+this.id+'Thumbnails img').eq(i);
		selectedThumb.addClass('active').stop().fadeTo(0, 1);

		var thumbList = $('#'+this.id+'Thumbnails');

		// position the triangle
		$('#'+this.id+'Triangle').css('top', thumbList.scrollTop() + selectedThumb.position().top + Math.round(selectedThumb.outerHeight() / 2) - 8);

		// scroll the thumbnail list
		if (selectedThumb.position().top < 50)
		{
			// if the selected thumbnail is above the visible (scrolled) area, scroll up
			thumbList.scrollTop(thumbList.scrollTop() + selectedThumb.position().top - 50);
		}
		else
		{
			// if the selected thumbnail is below the visible (scrolled) area, scroll down so it's in the middle
			thumbList.scrollTop(thumbList.scrollTop() + selectedThumb.position().top - Math.round((thumbList.innerHeight() - selectedThumb.outerHeight()) / 2));
		}
	}


	this._getRatioSize = function (width, height, maxWidth, maxHeight)
	{
		var size = { width: width, height: height, left: 0, top: 0};
		var ratio = width / height;

		// calculate new dimensions to fit inside max while maintaining aspect ratio
		if (width > maxWidth || height > maxHeight)
		{
			if (size.width > maxWidth)
			{
				size.width = maxWidth;
				size.height = Math.round(size.width / ratio);
			}

			if (size.height > maxHeight)
			{
				size.height = maxHeight;
				size.width = Math.round(size.height * ratio);
			}
		}

		if (size.width < maxWidth)
		{
			size.left = Math.round((maxWidth - size.width) / 2);
		}
		if (size.height < maxHeight)
		{
			size.top = Math.round((maxHeight - size.height) / 2);
		}

		return size;
	}

	this.nextImage = function ()
	{
		if (++this.currentImageIndex >= this.images.length)
		{
			this.currentImageIndex = 0;
		}

		this.renderImage(this.currentImageIndex);
	}

	this.previousImage = function ()
	{
		if (--this.currentImageIndex < 0)
		{
			this.currentImageIndex = this.images.length - 1;
		}

		this.renderImage(this.currentImageIndex);
	}

	this.beforeClose = function ()
	{
		$(document).unbind('keydown.'+MA.lightboxInstance.id);
		$(document).unbind('mousewheel');
	}
}

MA.lightboxInstance = null;
MA.lightboxDataCache = {};
MA.openLightbox = function (galleryType, galleryId, imageId, opener, e)
{
	if (MA.lightboxInstance) MA.lightboxInstance.cleanup();

	MA.lightboxInstance = new MA.Lightbox(galleryType, galleryId, imageId);
	return MA.lightboxInstance.open(e, opener);
}
MA.closeLightbox = function ()
{
	MA.lightboxInstance.close();
}
