/*
This file includes the following files:
 - /core/javascript/jquery/plugins/jquery.simplemodal-1.3.js
 - /core/javascript/jquery/plugins/jquery.cleverlabels.js
 - /core/javascript/jquery/plugins/jquery.form.js
 - /javascript/global.js
*/

/* ---------- Start /core/javascript/jquery/plugins/jquery.simplemodal-1.3.js ---------- */

/*
 * SimpleModal 1.3.5 - jQuery Plugin
 * http://www.ericmmartin.com/projects/simplemodal/
 * Copyright (c) 2010 Eric Martin (http://twitter.com/EricMMartin)
 * Dual licensed under the MIT and GPL licenses
 * Revision: $Id: jquery.simplemodal.js 245 2010-03-25 20:41:15Z emartin24 $
 */

/**
 * SimpleModal is a lightweight jQuery plugin that provides a simple
 * interface to create a modal dialog.
 *
 * The goal of SimpleModal is to provide developers with a cross-browser 
 * overlay and container that will be populated with data provided to
 * SimpleModal.
 *
 * There are two ways to call SimpleModal:
 * 1) As a chained function on a jQuery object, like $('#myDiv').modal();.
 * This call would place the DOM object, #myDiv, inside a modal dialog.
 * Chaining requires a jQuery object. An optional options object can be
 * passed as a parameter.
 *
 * @example $('<div>my data</div>').modal({options});
 * @example $('#myDiv').modal({options});
 * @example jQueryObject.modal({options});
 *
 * 2) As a stand-alone function, like $.modal(data). The data parameter
 * is required and an optional options object can be passed as a second
 * parameter. This method provides more flexibility in the types of data 
 * that are allowed. The data could be a DOM object, a jQuery object, HTML
 * or a string.
 * 
 * @example $.modal('<div>my data</div>', {options});
 * @example $.modal('my data', {options});
 * @example $.modal($('#myDiv'), {options});
 * @example $.modal(jQueryObject, {options});
 * @example $.modal(document.getElementById('myDiv'), {options}); 
 * 
 * A SimpleModal call can contain multiple elements, but only one modal 
 * dialog can be created at a time. Which means that all of the matched
 * elements will be displayed within the modal container.
 * 
 * SimpleModal internally sets the CSS needed to display the modal dialog
 * properly in all browsers, yet provides the developer with the flexibility
 * to easily control the look and feel. The styling for SimpleModal can be 
 * done through external stylesheets, or through SimpleModal, using the
 * overlayCss and/or containerCss options.
 *
 * SimpleModal has been tested in the following browsers:
 * - IE 6, 7, 8
 * - Firefox 2, 3
 * - Opera 9, 10
 * - Safari 3, 4
 * - Chrome 1, 2, 3, 4
 *
 * @name SimpleModal
 * @type jQuery
 * @requires jQuery v1.2.2
 * @cat Plugins/Windows and Overlays
 * @author Eric Martin (http://ericmmartin.com)
 * @version 1.3.5
 */
;(function ($) {
	var ie6 = $.browser.msie && parseInt($.browser.version) == 6 && typeof window['XMLHttpRequest'] != "object",
		ieQuirks = null,
		w = [];

	/*
	 * Stand-alone function to create a modal dialog.
	 * 
	 * @param {string, object} data A string, jQuery object or DOM object
	 * @param {object} [options] An optional object containing options overrides
	 */
	$.modal = function (data, options) {
		return $.modal.impl.init(data, options);
	};

	/*
	 * Stand-alone close function to close the modal dialog
	 */
	$.modal.close = function () {
		$.modal.impl.close();
	};

	/*
	 * Chained function to create a modal dialog.
	 * 
	 * @param {object} [options] An optional object containing options overrides
	 */
	$.fn.modal = function (options) {
		return $.modal.impl.init(this, options);
	};

	/*
	 * SimpleModal default options
	 * 
	 * appendTo:		(String:'body') The jQuery selector to append the elements to. For ASP.NET, use 'form'.
	 * focus:			(Boolean:true) Forces focus to remain on the modal dialog
	 * opacity:			(Number:50) The opacity value for the overlay div, from 0 - 100
	 * overlayId:		(String:'simplemodal-overlay') The DOM element id for the overlay div
	 * overlayCss:		(Object:{}) The CSS styling for the overlay div
	 * containerId:		(String:'simplemodal-container') The DOM element id for the container div
	 * containerCss:	(Object:{}) The CSS styling for the container div
	 * dataId:			(String:'simplemodal-data') The DOM element id for the data div
	 * dataCss:			(Object:{}) The CSS styling for the data div
	 * minHeight:		(Number:null) The minimum height for the container
	 * minWidth:		(Number:null) The minimum width for the container
	 * maxHeight:		(Number:null) The maximum height for the container. If not specified, the window height is used.
	 * maxWidth:		(Number:null) The maximum width for the container. If not specified, the window width is used.
	 * autoResize:		(Boolean:false) Resize container on window resize? Use with caution - this may have undesirable side-effects.
	 * autoPosition:	(Boolean:true) Automatically position container on creation and window resize?
	 * zIndex:			(Number: 1000) Starting z-index value
	 * close:			(Boolean:true) If true, closeHTML, escClose and overClose will be used if set.
	 							If false, none of them will be used.
	 * closeHTML:		(String:'<a class="modalCloseImg" title="Close"></a>') The HTML for the 
							default close link. SimpleModal will automatically add the closeClass to this element.
	 * closeClass:		(String:'simplemodal-close') The CSS class used to bind to the close event
	 * escClose:		(Boolean:true) Allow Esc keypress to close the dialog? 
	 * overlayClose:	(Boolean:false) Allow click on overlay to close the dialog?
	 * position:		(Array:null) Position of container [top, left]. Can be number of pixels or percentage
	 * persist:			(Boolean:false) Persist the data across modal calls? Only used for existing
								DOM elements. If true, the data will be maintained across modal calls, if false,
								the data will be reverted to its original state.
	 * modal:			(Boolean:true) If false, the overlay, iframe, and certain events will be disabled
								allowing the user to interace with the page below the dialog
	 * onOpen:			(Function:null) The callback function used in place of SimpleModal's open
	 * onShow:			(Function:null) The callback function used after the modal dialog has opened
	 * onClose:			(Function:null) The callback function used in place of SimpleModal's close
	 */
	$.modal.defaults = {
		appendTo: 'body',
		focus: true,
		opacity: 50,
		overlayId: 'simplemodal-overlay',
		overlayCss: {},
		containerId: 'simplemodal-container',
		containerCss: {},
		dataId: 'simplemodal-data',
		dataCss: {},
		minHeight: null,
		minWidth: null,
		maxHeight: null,
		maxWidth: null,
		autoResize: false,
		autoPosition: true,
		zIndex: 1000,
		close: true,
		closeHTML: '<a class="modalCloseImg" title="Close"></a>',
		closeClass: 'simplemodal-close',
		escClose: true,
		overlayClose: false,
		position: null,
		persist: false,
		modal: true,
		onOpen: null,
		onShow: null,
		onClose: null
	};

	/*
	 * Main modal object
	 */
	$.modal.impl = {
		/*
		 * Modal dialog options
		 */
		o: null,
		/*
		 * Contains the modal dialog elements and is the object passed 
		 * back to the callback (onOpen, onShow, onClose) functions
		 */
		d: {},
		/*
		 * Initialize the modal dialog
		 */
		init: function (data, options) {
			var s = this;

			// don't allow multiple calls
			if (s.d.data) {
				return false;
			}

			// $.boxModel is undefined if checked earlier
			ieQuirks = $.browser.msie && !$.boxModel;

			// merge defaults and user options
			s.o = $.extend({}, $.modal.defaults, options);

			// keep track of z-index
			s.zIndex = s.o.zIndex;

			// set the onClose callback flag
			s.occb = false;

			// determine how to handle the data based on its type
			if (typeof data == 'object') {
				// convert DOM object to a jQuery object
				data = data instanceof jQuery ? data : $(data);
				s.d.placeholder = false;

				// if the object came from the DOM, keep track of its parent
				if (data.parent().parent().size() > 0) {
					data.before($('<span></span>')
						.attr('id', 'simplemodal-placeholder')
						.css({display: 'none'}));

					s.d.placeholder = true;
					s.display = data.css('display');

					// persist changes? if not, make a clone of the element
					if (!s.o.persist) {
						s.d.orig = data.clone(true);
					}
				}
			}
			else if (typeof data == 'string' || typeof data == 'number') {
				// just insert the data as innerHTML
				data = $('<div></div>').html(data);
			}
			else {
				// unsupported data type!
				alert('SimpleModal Error: Unsupported data type: ' + typeof data);
				return s;
			}

			// create the modal overlay, container and, if necessary, iframe
			s.create(data);
			data = null;

			// display the modal dialog
			s.open();

			// useful for adding events/manipulating data in the modal dialog
			if ($.isFunction(s.o.onShow)) {
				s.o.onShow.apply(s, [s.d]);
			}

			// don't break the chain =)
			return s;
		},
		/*
		 * Create and add the modal overlay and container to the page
		 */
		create: function (data) {
			var s = this;

			// get the window properties
			w = s.getDimensions();

			// add an iframe to prevent select options from bleeding through
			if (s.o.modal && ie6) {
				s.d.iframe = $('<iframe src="javascript:false;"></iframe>')
					.css($.extend(s.o.iframeCss, {
						display: 'none',
						opacity: 0, 
						position: 'fixed',
						height: w[0],
						width: w[1],
						zIndex: s.o.zIndex,
						top: 0,
						left: 0
					}))
					.appendTo(s.o.appendTo);
			}

			// create the overlay
			s.d.overlay = $('<div></div>')
				.attr('id', s.o.overlayId)
				.addClass('simplemodal-overlay')
				.css($.extend(s.o.overlayCss, {
					display: 'none',
					opacity: s.o.opacity / 100,
					height: s.o.modal ? w[0] : 0,
					width: s.o.modal ? w[1] : 0,
					position: 'fixed',
					left: 0,
					top: 0,
					zIndex: s.o.zIndex + 1
				}))
				.appendTo(s.o.appendTo);
		
			// create the container
			s.d.container = $('<div></div>')
				.attr('id', s.o.containerId)
				.addClass('simplemodal-container')
				.css($.extend(s.o.containerCss, {
					display: 'none',
					position: 'fixed', 
					zIndex: s.o.zIndex + 2
				}))
				.append(s.o.close && s.o.closeHTML
					? $(s.o.closeHTML).addClass(s.o.closeClass)
					: '')
				.appendTo(s.o.appendTo);
				
			s.d.wrap = $('<div></div>')
				.attr('tabIndex', -1)
				.addClass('simplemodal-wrap')
				.css({height: '100%', outline: 0, width: '100%'})
				.appendTo(s.d.container);
				
			// add styling and attributes to the data
			// append to body to get correct dimensions, then move to wrap
			s.d.data = data
				.attr('id', data.attr('id') || s.o.dataId)
				.addClass('simplemodal-data')
				.css($.extend(s.o.dataCss, {
						display: 'none'
				}))
				.appendTo('body');
			data = null;

			s.setContainerDimensions();
			s.d.data.appendTo(s.d.wrap);

			// fix issues with IE
			if (ie6 || ieQuirks) {
				s.fixIE();
			}
		},
		/*
		 * Bind events
		 */
		bindEvents: function () {
			var s = this;

			// bind the close event to any element with the closeClass class
			$('.' + s.o.closeClass).bind('click.simplemodal', function (e) {
				e.preventDefault();
				s.close();
			});
			
			// bind the overlay click to the close function, if enabled
			if (s.o.modal && s.o.close && s.o.overlayClose) {
				s.d.overlay.bind('click.simplemodal', function (e) {
					e.preventDefault();
					s.close();
				});
			}
	
			// bind keydown events
			$(document).bind('keydown.simplemodal', function (e) {
				if (s.o.modal && s.o.focus && e.keyCode == 9) { // TAB
					s.watchTab(e);
				}
				else if ((s.o.close && s.o.escClose) && e.keyCode == 27) { // ESC
					e.preventDefault();
					s.close();
				}
			});

			// update window size
			$(window).bind('resize.simplemodal', function () {
				// redetermine the window width/height
				w = s.getDimensions();

				// reposition the dialog
				s.setContainerDimensions(true);
	
				if (ie6 || ieQuirks) {
					s.fixIE();
				}
				else if (s.o.modal) {
					// update the iframe & overlay
					s.d.iframe && s.d.iframe.css({height: w[0], width: w[1]});
					s.d.overlay.css({height: w[0], width: w[1]});
				}
			});
		},
		/*
		 * Unbind events
		 */
		unbindEvents: function () {
			$('.' + this.o.closeClass).unbind('click.simplemodal');
			$(document).unbind('keydown.simplemodal');
			$(window).unbind('resize.simplemodal');
			this.d.overlay.unbind('click.simplemodal');
		},
		/*
		 * Fix issues in IE6 and IE7 in quirks mode
		 */
		fixIE: function () {
			var s = this, p = s.o.position;

			// simulate fixed position - adapted from BlockUI
			$.each([s.d.iframe || null, !s.o.modal ? null : s.d.overlay, s.d.container], function (i, el) {
				if (el) {
					var bch = 'document.body.clientHeight', bcw = 'document.body.clientWidth',
						bsh = 'document.body.scrollHeight', bsl = 'document.body.scrollLeft',
						bst = 'document.body.scrollTop', bsw = 'document.body.scrollWidth',
						ch = 'document.documentElement.clientHeight', cw = 'document.documentElement.clientWidth',
						sl = 'document.documentElement.scrollLeft', st = 'document.documentElement.scrollTop',
						s = el[0].style;

					s.position = 'absolute';
					if (i < 2) {
						s.removeExpression('height');
						s.removeExpression('width');
						s.setExpression('height','' + bsh + ' > ' + bch + ' ? ' + bsh + ' : ' + bch + ' + "px"');
						s.setExpression('width','' + bsw + ' > ' + bcw + ' ? ' + bsw + ' : ' + bcw + ' + "px"');
					}
					else {
						var te, le;
						if (p && p.constructor == Array) {
							var top = p[0] 
								? typeof p[0] == 'number' ? p[0].toString() : p[0].replace(/px/, '')
								: el.css('top').replace(/px/, '');
							te = top.indexOf('%') == -1 
								? top + ' + (t = ' + st + ' ? ' + st + ' : ' + bst + ') + "px"'
								: parseInt(top.replace(/%/, '')) + ' * ((' + ch + ' || ' + bch + ') / 100) + (t = ' + st + ' ? ' + st + ' : ' + bst + ') + "px"';

							if (p[1]) {
								var left = typeof p[1] == 'number' ? p[1].toString() : p[1].replace(/px/, '');
								le = left.indexOf('%') == -1 
									? left + ' + (t = ' + sl + ' ? ' + sl + ' : ' + bsl + ') + "px"'
									: parseInt(left.replace(/%/, '')) + ' * ((' + cw + ' || ' + bcw + ') / 100) + (t = ' + sl + ' ? ' + sl + ' : ' + bsl + ') + "px"';
							}
						}
						else {
							te = '(' + ch + ' || ' + bch + ') / 2 - (this.offsetHeight / 2) + (t = ' + st + ' ? ' + st + ' : ' + bst + ') + "px"';
							le = '(' + cw + ' || ' + bcw + ') / 2 - (this.offsetWidth / 2) + (t = ' + sl + ' ? ' + sl + ' : ' + bsl + ') + "px"';
						}
						s.removeExpression('top');
						s.removeExpression('left');
						s.setExpression('top', te);
						s.setExpression('left', le);
					}
				}
			});
		},
		focus: function (pos) {
			var s = this, p = pos || 'first';

			// focus on dialog or the first visible/enabled input element
			var input = $(':input:enabled:visible:' + p, s.d.wrap);
			input.length > 0 ? input.focus() : s.d.wrap.focus();
		},
		getDimensions: function () {
			var el = $(window);

			// fix a jQuery/Opera bug with determining the window height
			var h = $.browser.opera && $.browser.version > '9.5' && $.fn.jquery <= '1.2.6' ? document.documentElement['clientHeight'] :
				$.browser.opera && $.browser.version < '9.5' && $.fn.jquery > '1.2.6' ? window.innerHeight :
				el.height();

			return [h, el.width()];
		},
		getVal: function (v) {
			return v == 'auto' ? 0 
				: v.indexOf('%') > 0 ? v 
					: parseInt(v.replace(/px/, ''));
		},
		setContainerDimensions: function (resize) {
			var s = this;

			if (!resize || (resize && s.o.autoResize)) {
				// get the dimensions for the container and data
				var ch = $.browser.opera ? s.d.container.height() : s.getVal(s.d.container.css('height')), 
					cw = $.browser.opera ? s.d.container.width() : s.getVal(s.d.container.css('width')),
					dh = s.d.data.outerHeight(true), dw = s.d.data.outerWidth(true);

				var mh = s.o.maxHeight && s.o.maxHeight < w[0] ? s.o.maxHeight : w[0],
					mw = s.o.maxWidth && s.o.maxWidth < w[1] ? s.o.maxWidth : w[1];

				// height
				if (!ch) {
					if (!dh) {ch = s.o.minHeight;}
					else {
						if (dh > mh) {ch = mh;}
						else if (dh < s.o.minHeight) {ch = s.o.minHeight;}
						else {ch = dh;}
					}
				}
				else {
					ch = ch > mh ? mh : ch;
				}

				// width
				if (!cw) {
					if (!dw) {cw = s.o.minWidth;}
					else {
						if (dw > mw) {cw = mw;}
						else if (dw < s.o.minWidth) {cw = s.o.minWidth;}
						else {cw = dw;}
					}
				}
				else {
					cw = cw > mw ? mw : cw;
				}

				s.d.container.css({height: ch, width: cw});
				if (dh > ch || dw > cw) {
					s.d.wrap.css({overflow:'auto'});
				}
			}
			
			if (s.o.autoPosition) {
				s.setPosition();
			}
		},
		setPosition: function () {
			var s = this, top, left,
				hc = (w[0]/2) - (s.d.container.outerHeight(true)/2),
				vc = (w[1]/2) - (s.d.container.outerWidth(true)/2);

			if (s.o.position && Object.prototype.toString.call(s.o.position) === "[object Array]") {
				top = s.o.position[0] || hc;
				left = s.o.position[1] || vc;
			} else {
				top = hc;
				left = vc;
			}
			s.d.container.css({left: left, top: top});
		},
		watchTab: function (e) {
			var s = this;

			if ($(e.target).parents('.simplemodal-container').length > 0) {
				// save the list of inputs
				s.inputs = $(':input:enabled:visible:first, :input:enabled:visible:last', s.d.data[0]);

				// if it's the first or last tabbable element, refocus
				if ((!e.shiftKey && e.target == s.inputs[s.inputs.length -1]) ||
						(e.shiftKey && e.target == s.inputs[0]) ||
						s.inputs.length == 0) {
					e.preventDefault();
					var pos = e.shiftKey ? 'last' : 'first';
					setTimeout(function () {s.focus(pos);}, 10);
				}
			}
			else {
				// might be necessary when custom onShow callback is used
				e.preventDefault();
				setTimeout(function () {s.focus();}, 10);
			}
		},
		/*
		 * Open the modal dialog elements
		 * - Note: If you use the onOpen callback, you must "show" the 
		 *	        overlay and container elements manually 
		 *         (the iframe will be handled by SimpleModal)
		 */
		open: function () {
			var s = this;
			// display the iframe
			s.d.iframe && s.d.iframe.show();

			if ($.isFunction(s.o.onOpen)) {
				// execute the onOpen callback 
				s.o.onOpen.apply(s, [s.d]);
			}
			else {
				// display the remaining elements
				s.d.overlay.show();
				s.d.container.show();
				s.d.data.show();
			}
			
			s.focus();

			// bind default events
			s.bindEvents();
		},
		/*
		 * Close the modal dialog
		 * - Note: If you use an onClose callback, you must remove the 
		 *         overlay, container and iframe elements manually
		 *
		 * @param {boolean} external Indicates whether the call to this
		 *     function was internal or external. If it was external, the
		 *     onClose callback will be ignored
		 */
		close: function () {
			var s = this;

			// prevent close when dialog does not exist
			if (!s.d.data) {
				return false;
			}

			// remove the default events
			s.unbindEvents();

			if ($.isFunction(s.o.onClose) && !s.occb) {
				// set the onClose callback flag
				s.occb = true;

				// execute the onClose callback
				s.o.onClose.apply(s, [s.d]);
			}
			else {
				// if the data came from the DOM, put it back
				if (s.d.placeholder) {
					var ph = $('#simplemodal-placeholder');
					// save changes to the data?
					if (s.o.persist) {
						// insert the (possibly) modified data back into the DOM
						ph.replaceWith(s.d.data.removeClass('simplemodal-data').css('display', s.display));
					}
					else {
						// remove the current and insert the original, 
						// unmodified data back into the DOM
						s.d.data.hide().remove();
						ph.replaceWith(s.d.orig);
					}
				}
				else {
					// otherwise, remove it
					s.d.data.hide().remove();
				}

				// remove the remaining elements
				s.d.container.hide().remove();
				s.d.overlay.hide().remove();
				s.d.iframe && s.d.iframe.hide().remove();

				// reset the dialog object
				s.d = {};
			}
		}
	};
})(jQuery);


/* ---------- End /core/javascript/jquery/plugins/jquery.simplemodal-1.3.js ---------- */

/* ---------- Start /core/javascript/jquery/plugins/jquery.cleverlabels.js ---------- */

/* D3R Cleverlabels
You will need some styling in your css a bit like this:

div.field input.cleverlabel,
div.field textarea.cleverlabel {
	background: #F0F0F0;
	color: #A0A0A0;
	border-color: #E1E1E1;
}
div.password .cleverpassword {
	position: relative;
}
div.password input.password {
	position: relativ;
}
div.password input.cleverlabel {
	position: absolute;
	z-index: 0;
	left: 0;
	bottom: 0;
}
.js div.field .form_note {
	display: none;
}
*/
(function($) {
	$.cleverlabels = function(el, override, options) {
		var base = this;
		
		base.$el = $(el);
        base.el = el;
		base.labeltext = override;
		
		base.$el.data("cleverlabels", base);
		
		base.init = function() {
			base.override = override;
			base.options = $.extend({},$.cleverlabels.defaultOptions, options);
			if (undefined == base.labeltext) {
				base.labeltext = base.$el.attr('placeholder');
			}
			if (undefined == base.labeltext || base.labeltext.length < 1) {
				base.labeltext = $('#'+base.$el.attr('id')+'_note').text();
			}
			if (undefined == base.labeltext || base.labeltext.length < 1) { 
				base.labeltext = $('label[for='+base.$el.attr('id')+']').text();
				if(base.options.allowAsterisk != true) {
					base.labeltext = base.labeltext.replace(/\*/,"");
				}
			}
			if (!$.cleverlabels.html5Support()) {
				if ('password' == base.$el.attr('type')) {
					var $dummy = $('<input type="text" value="'+base.labeltext+'" class="input cleverlabel"/>');
					$dummy.css({width: base.$el.width(), height: base.$el.height()});
					$dummy.focus(function(e){
						base.$el.focus();
					});
					base.$el.wrap('<div class="cleverpassword"></div>');
					base.$el.before($dummy);
					
					base.clearval = function() {
						base.$el.css({opacity:1});
					};
					base.fillval = function() {
						if (base.$el.val() == '') {
							base.$el.css({opacity:0});
						};
					};
				}
				base.fillval();
				base.$el.bind('focus', base.clearval);
				base.$el.bind('blur change', base.fillval);
				base.$el.closest('form').submit(base.clearval);
			} else if (base.$el.attr('placeholder') != base.labeltext) {
				base.$el.attr('placeholder', base.labeltext);
			}
		};

		base.clearval = function() {
			if (base.$el.val() == base.labeltext) {
				base.$el.val('');
				base.$el.removeClass('cleverlabel');
			}
		};
		
		base.fillval = function() {
			base.$el.removeClass('cleverlabel');
			if (base.$el.val() == '' || base.$el.val() == base.labeltext) {
				base.$el.val(base.labeltext);
				base.$el.addClass('cleverlabel');
			}
		};
		
		base.init();
	};
	
	$.cleverlabels.defaultOptions = {
		'allowAsterisk': false
	};
	
	$.cleverlabels.html5Support = function() {
		if ('undefined' == typeof $.support.placeholder) {
			$.support.placeholder = 'placeholder' in document.createElement('input');
		};
		return $.support.placeholder;
	};
	
	$.fn.cleverlabels = function(override, options){
		return this.each(function(){
			(new $.cleverlabels(this, override, options));
		});
	};
	
	$.fn.fillcleverlabels = function(){
		if (!$.cleverlabels.html5Support()) {
			return this.each(function(){
				if (!!$(this).data('cleverlabels')) {
					$(this).data('cleverlabels').fillval();
				};
			});
		};
		return this;
	};
	
	$.fn.clearcleverlabels = function(){
		if (!$.cleverlabels.html5Support()) {
			return this.each(function(){
				if (!!$(this).data('cleverlabels')) {
					$(this).data('cleverlabels').clearval();
				};
			});
		};
		return this;
	};
})(jQuery);


/* ---------- End /core/javascript/jquery/plugins/jquery.cleverlabels.js ---------- */

/* ---------- Start /core/javascript/jquery/plugins/jquery.form.js ---------- */

/*
 * jQuery Form Plugin
 * version: 2.33 (22-SEP-2009)
 * @requires jQuery v1.2.6 or later
 *
 * Examples and documentation at: http://malsup.com/jquery/form/
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 */
;(function($) {

/*
	Usage Note:
	-----------
	Do not use both ajaxSubmit and ajaxForm on the same form.  These
	functions are intended to be exclusive.  Use ajaxSubmit if you want
	to bind your own submit handler to the form.  For example,

	$(document).ready(function() {
		$('#myForm').bind('submit', function() {
			$(this).ajaxSubmit({
				target: '#output'
			});
			return false; // <-- important!
		});
	});

	Use ajaxForm when you want the plugin to manage all the event binding
	for you.  For example,

	$(document).ready(function() {
		$('#myForm').ajaxForm({
			target: '#output'
		});
	});

	When using ajaxForm, the ajaxSubmit function will be invoked for you
	at the appropriate time.
*/

/**
 * ajaxSubmit() provides a mechanism for immediately submitting
 * an HTML form using AJAX.
 */
$.fn.ajaxSubmit = function(options) {
	// fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
	if (!this.length) {
		log('ajaxSubmit: skipping submit process - no element selected');
		return this;
	}

	if (typeof options == 'function')
		options = { success: options };

	var url = $.trim(this.attr('action'));
	if (url) {
		// clean url (don't include hash vaue)
		url = (url.match(/^([^#]+)/)||[])[1];
   	}
   	url = url || window.location.href || '';

	options = $.extend({
		url:  url,
		type: this.attr('method') || 'GET'
	}, options || {});

	// hook for manipulating the form data before it is extracted;
	// convenient for use with rich editors like tinyMCE or FCKEditor
	var veto = {};
	this.trigger('form-pre-serialize', [this, options, veto]);
	if (veto.veto) {
		log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
		return this;
	}

	// provide opportunity to alter form data before it is serialized
	if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
		log('ajaxSubmit: submit aborted via beforeSerialize callback');
		return this;
	}

	var a = this.formToArray(options.semantic);
	if (options.data) {
		options.extraData = options.data;
		for (var n in options.data) {
		  if(options.data[n] instanceof Array) {
			for (var k in options.data[n])
			  a.push( { name: n, value: options.data[n][k] } );
		  }
		  else
			 a.push( { name: n, value: options.data[n] } );
		}
	}

	// give pre-submit callback an opportunity to abort the submit
	if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
		log('ajaxSubmit: submit aborted via beforeSubmit callback');
		return this;
	}

	// fire vetoable 'validate' event
	this.trigger('form-submit-validate', [a, this, options, veto]);
	if (veto.veto) {
		log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
		return this;
	}

	var q = $.param(a);

	if (options.type.toUpperCase() == 'GET') {
		options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
		options.data = null;  // data is null for 'get'
	}
	else
		options.data = q; // data is the query string for 'post'

	var $form = this, callbacks = [];
	if (options.resetForm) callbacks.push(function() { $form.resetForm(); });
	if (options.clearForm) callbacks.push(function() { $form.clearForm(); });

	// perform a load on the target only if dataType is not provided
	if (!options.dataType && options.target) {
		var oldSuccess = options.success || function(){};
		callbacks.push(function(data) {
			$(options.target).html(data).each(oldSuccess, arguments);
		});
	}
	else if (options.success)
		callbacks.push(options.success);

	options.success = function(data, status) {
		for (var i=0, max=callbacks.length; i < max; i++)
			callbacks[i].apply(options, [data, status, $form]);
	};

	// are there files to upload?
	var files = $('input:file', this).fieldValue();
	var found = false;
	for (var j=0; j < files.length; j++)
		if (files[j])
			found = true;

	var multipart = false;
//	var mp = 'multipart/form-data';
//	multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);

	// options.iframe allows user to force iframe mode
   if (options.iframe || found || multipart) {
	   // hack to fix Safari hang (thanks to Tim Molendijk for this)
	   // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
	   if (options.closeKeepAlive)
		   $.get(options.closeKeepAlive, fileUpload);
	   else
		   fileUpload();
	   }
   else
	   $.ajax(options);

	// fire 'notify' event
	this.trigger('form-submit-notify', [this, options]);
	return this;


	// private function for handling file uploads (hat tip to YAHOO!)
	function fileUpload() {
		var form = $form[0];

		if ($(':input[name=submit]', form).length) {
			alert('Error: Form elements must not be named "submit".');
			return;
		}

		var opts = $.extend({}, $.ajaxSettings, options);
		var s = $.extend(true, {}, $.extend(true, {}, $.ajaxSettings), opts);

		var id = 'jqFormIO' + (new Date().getTime());
		var $io = $('<iframe id="' + id + '" name="' + id + '" src="about:blank" />');
		var io = $io[0];

		$io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });

		var xhr = { // mock object
			aborted: 0,
			responseText: null,
			responseXML: null,
			status: 0,
			statusText: 'n/a',
			getAllResponseHeaders: function() {},
			getResponseHeader: function() {},
			setRequestHeader: function() {},
			abort: function() {
				this.aborted = 1;
				$io.attr('src','about:blank'); // abort op in progress
			}
		};

		var g = opts.global;
		// trigger ajax global events so that activity/block indicators work like normal
		if (g && ! $.active++) $.event.trigger("ajaxStart");
		if (g) $.event.trigger("ajaxSend", [xhr, opts]);

		if (s.beforeSend && s.beforeSend(xhr, s) === false) {
			s.global && $.active--;
			return;
		}
		if (xhr.aborted)
			return;

		var cbInvoked = 0;
		var timedOut = 0;

		// add submitting element to data if we know it
		var sub = form.clk;
		if (sub) {
			var n = sub.name;
			if (n && !sub.disabled) {
				options.extraData = options.extraData || {};
				options.extraData[n] = sub.value;
				if (sub.type == "image") {
					options.extraData[name+'.x'] = form.clk_x;
					options.extraData[name+'.y'] = form.clk_y;
				}
			}
		}

		// take a breath so that pending repaints get some cpu time before the upload starts
		setTimeout(function() {
			// make sure form attrs are set
			var t = $form.attr('target'), a = $form.attr('action');

			// update form attrs in IE friendly way
			form.setAttribute('target',id);
			if (form.getAttribute('method') != 'POST')
				form.setAttribute('method', 'POST');
			if (form.getAttribute('action') != opts.url)
				form.setAttribute('action', opts.url);

			// ie borks in some cases when setting encoding
			if (! options.skipEncodingOverride) {
				$form.attr({
					encoding: 'multipart/form-data',
					enctype:  'multipart/form-data'
				});
			}

			// support timout
			if (opts.timeout)
				setTimeout(function() { timedOut = true; cb(); }, opts.timeout);

			// add "extra" data to form if provided in options
			var extraInputs = [];
			try {
				if (options.extraData)
					for (var n in options.extraData)
						extraInputs.push(
							$('<input type="hidden" name="'+n+'" value="'+options.extraData[n]+'" />')
								.appendTo(form)[0]);

				// add iframe to doc and submit the form
				$io.appendTo('body');
				io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
				form.submit();
			}
			finally {
				// reset attrs and remove "extra" input elements
				form.setAttribute('action',a);
				t ? form.setAttribute('target', t) : $form.removeAttr('target');
				$(extraInputs).remove();
			}
		}, 10);

		var domCheckCount = 50;

		function cb() {
			if (cbInvoked++) return;

			io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);

			var ok = true;
			try {
				if (timedOut) throw 'timeout';
				// extract the server response from the iframe
				var data, doc;

				doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
				
				var isXml = opts.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
				log('isXml='+isXml);
				if (!isXml && (doc.body == null || doc.body.innerHTML == '')) {
				 	if (--domCheckCount) {
						// in some browsers (Opera) the iframe DOM is not always traversable when
						// the onload callback fires, so we loop a bit to accommodate
						cbInvoked = 0;
						setTimeout(cb, 100);
						return;
					}
					log('Could not access iframe DOM after 50 tries.');
					return;
				}

				xhr.responseText = doc.body ? doc.body.innerHTML : null;
				xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
				xhr.getResponseHeader = function(header){
					var headers = {'content-type': opts.dataType};
					return headers[header];
				};

				if (opts.dataType == 'json' || opts.dataType == 'script') {
					// see if user embedded response in textarea
					var ta = doc.getElementsByTagName('textarea')[0];
					if (ta)
						xhr.responseText = ta.value;
					else {
						// account for browsers injecting pre around json response
						var pre = doc.getElementsByTagName('pre')[0];
						if (pre)
							xhr.responseText = pre.innerHTML;
					}			  
				}
				else if (opts.dataType == 'xml' && !xhr.responseXML && xhr.responseText != null) {
					xhr.responseXML = toXml(xhr.responseText);
				}
				data = $.httpData(xhr, opts.dataType);
			}
			catch(e){
				ok = false;
				$.handleError(opts, xhr, 'error', e);
			}

			// ordering of these callbacks/triggers is odd, but that's how $.ajax does it
			if (ok) {
				opts.success(data, 'success');
				if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
			}
			if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
			if (g && ! --$.active) $.event.trigger("ajaxStop");
			if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');

			// clean up
			setTimeout(function() {
				$io.remove();
				xhr.responseXML = null;
			}, 100);
		};

		function toXml(s, doc) {
			if (window.ActiveXObject) {
				doc = new ActiveXObject('Microsoft.XMLDOM');
				doc.async = 'false';
				doc.loadXML(s);
			}
			else
				doc = (new DOMParser()).parseFromString(s, 'text/xml');
			return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
		};
	};
};

/**
 * ajaxForm() provides a mechanism for fully automating form submission.
 *
 * The advantages of using this method instead of ajaxSubmit() are:
 *
 * 1: This method will include coordinates for <input type="image" /> elements (if the element
 *	is used to submit the form).
 * 2. This method will include the submit element's name/value data (for the element that was
 *	used to submit the form).
 * 3. This method binds the submit() method to the form for you.
 *
 * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
 * passes the options argument along after properly binding events for submit elements and
 * the form itself.
 */
$.fn.ajaxForm = function(options) {
	return this.ajaxFormUnbind().bind('submit.form-plugin', function() {
		$(this).ajaxSubmit(options);
		return false;
	}).bind('click.form-plugin', function(e) {
		var $el = $(e.target);
		if (!($el.is(":submit,input:image"))) {
			return;
		}
		var form = this;
		form.clk = e.target;
		if (e.target.type == 'image') {
			if (e.offsetX != undefined) {
				form.clk_x = e.offsetX;
				form.clk_y = e.offsetY;
			} else if (typeof $.fn.offset == 'function') { // try to use dimensions plugin
				var offset = $el.offset();
				form.clk_x = e.pageX - offset.left;
				form.clk_y = e.pageY - offset.top;
			} else {
				form.clk_x = e.pageX - e.target.offsetLeft;
				form.clk_y = e.pageY - e.target.offsetTop;
			}
		}
		// clear form vars
		setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 10);
	});
};

// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
$.fn.ajaxFormUnbind = function() {
	return this.unbind('submit.form-plugin click.form-plugin');
};

/**
 * formToArray() gathers form element data into an array of objects that can
 * be passed to any of the following ajax functions: $.get, $.post, or load.
 * Each object in the array has both a 'name' and 'value' property.  An example of
 * an array for a simple login form might be:
 *
 * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
 *
 * It is this array that is passed to pre-submit callback functions provided to the
 * ajaxSubmit() and ajaxForm() methods.
 */
$.fn.formToArray = function(semantic) {
	var a = [];
	if (this.length == 0) return a;

	var form = this[0];
	var els = semantic ? form.getElementsByTagName('*') : form.elements;
	if (!els) return a;
	for(var i=0, max=els.length; i < max; i++) {
		var el = els[i];
		var n = el.name;
		if (!n) continue;

		if (semantic && form.clk && el.type == "image") {
			// handle image inputs on the fly when semantic == true
			if(!el.disabled && form.clk == el) {
				a.push({name: n, value: $(el).val()});
				a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
			}
			continue;
		}

		var v = $.fieldValue(el, true);
		if (v && v.constructor == Array) {
			for(var j=0, jmax=v.length; j < jmax; j++)
				a.push({name: n, value: v[j]});
		}
		else if (v !== null && typeof v != 'undefined')
			a.push({name: n, value: v});
	}

	if (!semantic && form.clk) {
		// input type=='image' are not found in elements array! handle it here
		var $input = $(form.clk), input = $input[0], n = input.name;
		if (n && !input.disabled && input.type == 'image') {
			a.push({name: n, value: $input.val()});
			a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
		}
	}
	return a;
};

/**
 * Serializes form data into a 'submittable' string. This method will return a string
 * in the format: name1=value1&amp;name2=value2
 */
$.fn.formSerialize = function(semantic) {
	//hand off to jQuery.param for proper encoding
	return $.param(this.formToArray(semantic));
};

/**
 * Serializes all field elements in the jQuery object into a query string.
 * This method will return a string in the format: name1=value1&amp;name2=value2
 */
$.fn.fieldSerialize = function(successful) {
	var a = [];
	this.each(function() {
		var n = this.name;
		if (!n) return;
		var v = $.fieldValue(this, successful);
		if (v && v.constructor == Array) {
			for (var i=0,max=v.length; i < max; i++)
				a.push({name: n, value: v[i]});
		}
		else if (v !== null && typeof v != 'undefined')
			a.push({name: this.name, value: v});
	});
	//hand off to jQuery.param for proper encoding
	return $.param(a);
};

/**
 * Returns the value(s) of the element in the matched set.  For example, consider the following form:
 *
 *  <form><fieldset>
 *	  <input name="A" type="text" />
 *	  <input name="A" type="text" />
 *	  <input name="B" type="checkbox" value="B1" />
 *	  <input name="B" type="checkbox" value="B2"/>
 *	  <input name="C" type="radio" value="C1" />
 *	  <input name="C" type="radio" value="C2" />
 *  </fieldset></form>
 *
 *  var v = $(':text').fieldValue();
 *  // if no values are entered into the text inputs
 *  v == ['','']
 *  // if values entered into the text inputs are 'foo' and 'bar'
 *  v == ['foo','bar']
 *
 *  var v = $(':checkbox').fieldValue();
 *  // if neither checkbox is checked
 *  v === undefined
 *  // if both checkboxes are checked
 *  v == ['B1', 'B2']
 *
 *  var v = $(':radio').fieldValue();
 *  // if neither radio is checked
 *  v === undefined
 *  // if first radio is checked
 *  v == ['C1']
 *
 * The successful argument controls whether or not the field element must be 'successful'
 * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
 * The default value of the successful argument is true.  If this value is false the value(s)
 * for each element is returned.
 *
 * Note: This method *always* returns an array.  If no valid value can be determined the
 *	   array will be empty, otherwise it will contain one or more values.
 */
$.fn.fieldValue = function(successful) {
	for (var val=[], i=0, max=this.length; i < max; i++) {
		var el = this[i];
		var v = $.fieldValue(el, successful);
		if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length))
			continue;
		v.constructor == Array ? $.merge(val, v) : val.push(v);
	}
	return val;
};

/**
 * Returns the value of the field element.
 */
$.fieldValue = function(el, successful) {
	var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
	if (typeof successful == 'undefined') successful = true;

	if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
		(t == 'checkbox' || t == 'radio') && !el.checked ||
		(t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
		tag == 'select' && el.selectedIndex == -1))
			return null;

	if (tag == 'select') {
		var index = el.selectedIndex;
		if (index < 0) return null;
		var a = [], ops = el.options;
		var one = (t == 'select-one');
		var max = (one ? index+1 : ops.length);
		for(var i=(one ? index : 0); i < max; i++) {
			var op = ops[i];
			if (op.selected) {
				var v = op.value;
				if (!v) // extra pain for IE...
					v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
				if (one) return v;
				a.push(v);
			}
		}
		return a;
	}
	return el.value;
};

/**
 * Clears the form data.  Takes the following actions on the form's input fields:
 *  - input text fields will have their 'value' property set to the empty string
 *  - select elements will have their 'selectedIndex' property set to -1
 *  - checkbox and radio inputs will have their 'checked' property set to false
 *  - inputs of type submit, button, reset, and hidden will *not* be effected
 *  - button elements will *not* be effected
 */
$.fn.clearForm = function() {
	return this.each(function() {
		$('input,select,textarea', this).clearFields();
	});
};

/**
 * Clears the selected form elements.
 */
$.fn.clearFields = $.fn.clearInputs = function() {
	return this.each(function() {
		var t = this.type, tag = this.tagName.toLowerCase();
		if (t == 'text' || t == 'password' || tag == 'textarea')
			this.value = '';
		else if (t == 'checkbox' || t == 'radio')
			this.checked = false;
		else if (tag == 'select')
			this.selectedIndex = -1;
	});
};

/**
 * Resets the form data.  Causes all form elements to be reset to their original value.
 */
$.fn.resetForm = function() {
	return this.each(function() {
		// guard against an input with the name of 'reset'
		// note that IE reports the reset function as an 'object'
		if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType))
			this.reset();
	});
};

/**
 * Enables or disables any matching elements.
 */
$.fn.enable = function(b) {
	if (b == undefined) b = true;
	return this.each(function() {
		this.disabled = !b;
	});
};

/**
 * Checks/unchecks any matching checkboxes or radio buttons and
 * selects/deselects and matching option elements.
 */
$.fn.selected = function(select) {
	if (select == undefined) select = true;
	return this.each(function() {
		var t = this.type;
		if (t == 'checkbox' || t == 'radio')
			this.checked = select;
		else if (this.tagName.toLowerCase() == 'option') {
			var $sel = $(this).parent('select');
			if (select && $sel[0] && $sel[0].type == 'select-one') {
				// deselect all other options
				$sel.find('option').selected(false);
			}
			this.selected = select;
		}
	});
};

// helper fn for console logging
// set $.fn.ajaxSubmit.debug to true to enable debug logging
function log() {
	if ($.fn.ajaxSubmit.debug && window.console && window.console.log)
		window.console.log('[jquery.form] ' + Array.prototype.join.call(arguments,''));
};

})(jQuery);


/* ---------- End /core/javascript/jquery/plugins/jquery.form.js ---------- */

/* ---------- Start /javascript/global.js ---------- */

jQuery.fn.delegate = function(eventType, rules) {
  return this.bind(eventType, function(e) {
    var target = $(e.target);
    for(var selector in rules)
      if(target.is(selector)) 
        return rules[selector].apply(this, arguments);
  })
};

jQuery.fn.realOffset = function() {
	var that = this[0];
	var x = 0;
	var y = 0;
	do {
		x += that.offsetLeft;
		y += that.offsetTop;
	} while (that = that.offsetParent);
	return {left: x, top: y};
}

/* kills jumping to anchors and selecting their content */
$(function() {
	$("a[href^=#]").live('click', function(e) {
		e.preventDefault();
	}).live('selectstart', function(e) {
		e.preventDefault();
	});
});

jQuery.fn.slideOutRow = function(callback) {
	row = $(this);
	if(row.is('tr'))
	{
		$('td', row).each(function(){
			var el = $(this);
			el.css({
				verticalAlign: 'top'
			});
			var o = $('<span>').addClass('wrap').css({
				display: 'inline-block',
				verticalAlign: 'top',
				overflow: 'hidden'
			});
			var d = $('<span>').addClass('slideOut').css('overflow', 'hidden');
			d.css({
				display: 'inline-block',
				verticalAlign: 'top',
				paddingTop: el.css('paddingTop'),
				paddingBottom: el.css('paddingBottom')
			});
			el.css({
				paddingTop: 0,
				paddingBottom: 0
			});
			d.html(el.html());
			el.html('');
			d.appendTo(o);
			o.appendTo(el);
		});
		
		var t = 0;
		var c = 0;
		
		$('.slideOut', row).each(function(){
			c++;
			$(this).animate({
				marginTop: -row.height(),
				opacity: 0
			}, 300, 'swing', function(){
				row.remove();
				t++;
				if(t==c){
					if(typeof callback != 'undefined')
					{
						callback();
					}
				}
			});
		});
	}
};

function getQuerystring(key, default_)
{
	if (default_==null) default_=false;
	key = key.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	var regex = new RegExp("[\\?&]"+key+"=([^&#]*)");
	var qs = regex.exec(window.location.href);
	if(qs == null)
		return default_;
	else
		return qs[1];
}

jQuery.fn.setStartValue = function(startValue) { 
	var me = $(this);
	if(me.val() == '')
	{
		me.val(startValue);
	}
    me.focus(function(){
		if(me.val() == startValue)
		{
			me.val('');
		}
	}).blur(function(){
		if(me.val() == '')
		{
			me.val(startValue);
		}
	});
	return me;
}

function formSetup(url) {
	$("#simplemodal-container form").ajaxForm({
		target: $("#simplemodal-data"),
		url: url,
		success: function() {
			formSetup(url);
		}
	});
}

function setBasketSummary(text, total){
	$('.basket-text').text(text);
	$('.basket-total').html(total);
}

var shortlisted = {};

function setShortlistSummary(text){
	$('.wishlist-text').text(text);
}

function bindProductPage(urlname, colourUrlName, imagedata){

    var imageData = {};

    imageData[colourUrlName] = imagedata;

	var setInStock = function(inStock){
        var bar = $('.colour-bar');
		if(inStock){
			//$('button span:not(:has(span))',bar).text('Add to Bag');
			$('.in-stock').show();
			$('.out-of-stock').hide();
			Cufon.refresh();
		}else{
			//$('button span:not(:has(span))',bar).text('Out of Stock');
			$('.in-stock').hide();
			$('.out-of-stock').show();
			Cufon.refresh();
		}
	}

	var setOutOfStockLink = function(id){
		$('a.out-of-stock').attr('href', '/products/notify/' + id);
	}

    var hideBasketMessage = function(){
        var conf = $('div.basket-confirm');
        var conf = $('div.basket-confirm');
        if(conf.is(':visible')){
            conf.fadeOut();
        }
//        var press = $('.press-item');
//        if(press.length > 0 && !press.is(':visible')){
//            press.fadeIn();
//        }
    };

    var showBasketMessage = function(message, checkout){
	
        var conf = $('div.basket-confirm');
		
		if(typeof(checkout) != 'boolean')
		{
			checkout = true;
		}
	
		function show(message,checkout){
			if(checkout){
				$('.checkout', conf).removeClass('hidden');
			}else{
				$('.checkout', conf).addClass('hidden');
			}
			$('.success-message', conf).text(message);
			conf.fadeTo(250, 1);
		}
		
        if(conf.is(':visible')){
            conf.stop(true).fadeTo(250, 0.2, function(){
				show(message,checkout);
            });
        }else{
			conf.css({
				'display':'block',
				'opacity':0
			});
            /*var press = $('.press-item');
            if(press.length > 0){
                press.fadeOut();
            }*/
			show(message,checkout);
        }
    };

	var setShortLink = function(){

		var el = $('div.actions a.icon-link-wishlist');

		var link;
		var text;
		var colour = 1;

		var l = el.attr('href');
		if(-1 == l.indexOf('/remove/'))
		{
			colour = l.substring(l.indexOf('/add/') + '/add/'.length);
		}
		else
		{
			colour = l.substring(l.indexOf('/remove/') + '/remove/'.length);
		}

		if(typeof shortlisted[colour] != 'undefined'){
			link = '/wishlist/remove/' + colour;
			text = 'Remove';
		}else{
			link = '/wishlist/add/' + colour;
			text = 'Add to Wishlist';
		}

		if(text != el.text()){
			el.fadeTo(250, 0.5, function(){
				el.text(text);
				Cufon.refresh();
				el.attr('href', link).fadeTo(250, 1);
			});
		}else{
			el.attr('href', link);
		}

	};

	$('div.actions a.icon-link-wishlist').click(function(e){
		e.preventDefault();
		var link = $(this);
		$.getJSON(link.attr('href'), function(data){
			shortlisted = data.payload.shortlisted;
			setShortLink();
			setShortlistSummary(data.payload.text);
		});
	});

    function getColour(colourUrlName){
        if(typeof(imageData[colourUrlName]) == 'undefined'){
            $.getJSON('/product/get-images/' + urlname + '/?colour=' + colourUrlName, function(data){
                imageData[colourUrlName] = data.payload;
                showColour(imageData[colourUrlName]);
            });
        }else{
            showColour(imageData[colourUrlName]);
        }
    }

    function setActiveImage(el){
        $('.thumbnails a').removeClass('active');
        if(typeof(el) == 'undefined'){
            el = $('.thumbnails a:first');
        }
        el.addClass('active');
    }

    function showImage(url){
        var im = new Image();
        var leftim = $('.leftcol img');
        if(leftim.attr('src') && -1 == leftim.attr('src').indexOf(url)){
            leftim.fadeTo(250,0.1,function(){
                im.onload = function(){
                    leftim.attr('src', im.src).fadeTo(250,1);
                };
                im.src = url;
            });
        };
    }

    var showColour = function(data, stopfade){
        var first = true;

        var fade = false;
        if(typeof(stopfade) == 'undefined'){
            fade = true;
        }

        var cont = $('.rightcol .thumbnails').html('');
        $.each(data, function(k,v){

            if(first){
                showImage(v.detail);
                setActiveImage();
				$('#zoom-detail').css('backgroundImage', 'url(' + v.zoom + ')');
            }

            var nl = $('<a>').attr('href', '#').css('backgroundImage','url(' + v.thumb + ')');
			

            if(fade){
                nl.css('opacity', 0);
            }

            if(first){
                nl.addClass('active');
                first = false;
            }

            nl.appendTo(cont).fadeTo(750,1).click(function(e){
                e.preventDefault();
                setActiveImage($(this));
                showImage(v.detail);
				$('#zoom-detail').css('backgroundImage', 'url(' + v.zoom + ')');
            });

        });
    };

    var setArrow = function(){
        if($('span.colours .list').is(':visible')){
            $('span.colours').parent().addClass('expanded');
        }else{
            $('span.colours').parent().removeClass('expanded');
        }
    };

    var toggleDropDown = function(){
        var el = $('span.colours');
        el.children('span.list').slideToggle(setArrow);
    };

	var setStockMessage = function(){
        var ns = $('span.colours .active .no-stock');
        if(ns.length > 0){
            showBasketMessage('Sorry, ' + ns.text() + ' is currently unavailable', false);
			setInStock(false);
        }else{
			setInStock(true);
		}
	}
	
	// Check for a hash, otherwise show bound colour
	var currentHash = false;

    var setColour = function(el){
	
        hideBasketMessage();

        $('span.colours .active .colour').appendTo(
            $('span.colours .list')
        ).click(function(e){
            setColour($(this));
	        e.preventDefault();
	        e.stopPropagation();
        	toggleDropDown();
        }).removeClass('colouronhover');

        el.unbind('click');
        el.appendTo($('span.colours .active'));

		setStockMessage();
        
        var data = el.children('a:first').attr('rel');
        var parts = data.split('|');

        $('form#basket-add select#ddl-colours').val(parts[0]);
        setOutOfStockLink(parts[0]);

        getColour(parts[1]);

        $('div.actions a.icon-link-wishlist').attr('href', '/wishlist/add/' + parts[0]);
        setShortLink();

		if(parts[1]!=colourUrlName){
			window.location.hash = parts[1];
			currentHash = parts[1];
		}else{
			if(window.location.hash.length > 0){
				window.location.hash = colourUrlName;
			}
			currentHash = colourUrlName;
		}

    };
	
	var checkHash = function(){
		if(window.location.hash.length > 1){
			var hash = window.location.hash.substring(1);
		}else{
			var hash = colourUrlName;
		}
		if(hash != currentHash){
			currentHash = hash;
			var el = $('.colours .colour a[rel$="' + hash + '"]');
			if(el.length > 0){
				setColour(el.closest('.colour'));
				gotHash = true;
			}
		}
		setTimeout(checkHash, 1000);
	};
	
	// This does the initial image loading & continues to check for a different hash
	checkHash();

	if(!$('div.basket-confirm').is(':visible')){
		setStockMessage();
	}

    // Bind if active exists
    if($('span.colours .active').length > 0){
        
        $('span.colours .active').click(toggleDropDown);

        $('span.colours .list .colour').click(function(e){
            setColour($(this));
	        e.preventDefault();
	        e.stopPropagation();
        	toggleDropDown();
        });

    }

    $('body').delegate('click', {
        ':not(span.colours *)' : function(e) {
            $('span.colours .list').slideUp(300, setArrow);
        }
    });

    $('.product-bar h4.related-items').click(function(e){
        e.preventDefault();
        $('.product-bar h4.viewed-items').removeClass('active');
        $(this).addClass('active');
        Cufon.refresh();
        $('.viewed-grid .cell').fadeOut(function(){
            $('.related-grid .cell').fadeIn();
        });
    });

    $('.product-bar h4.viewed-items').click(function(e){
        e.preventDefault();
        $('.product-bar h4.related-items').removeClass('active');
        $(this).addClass('active');
        Cufon.refresh();
        $('.related-grid .cell').fadeOut(function(){
            $('.viewed-grid .cell').fadeIn();
        });
    });
		
	$('#zoom-control').mouseover(function(event) {
		$(this).animate({
		    opacity: 0.3
		  }, 0.3);
		$('#zoom-detail').fadeIn();
		$//('#product-information .press-item').stop(true).fadeTo(150, 0);
	});
	
	$('#zoom-control').mouseout(function(event) {
		$(this).animate({
		    opacity: 0
		  }, 0.3);
		$('#zoom-detail').fadeOut();
		//$('#product-information .press-item').stop(true).fadeTo(150, 1);
	});
	
	$('#zoom-control').mousemove(function(event) {
		
		el = $(this);
		viewWidth = 438;
		
		viewHeight = $('.leftcol img').height();
		el.css('height', viewHeight + 'px');
		
		leftPos = (event.pageX - el.offset().left) - (viewWidth/6);
		topPos = (event.pageY - el.offset().top) - (viewHeight/6);
		
		if (leftPos < 1) leftPos = 1;
		if (topPos < 1) topPos = 1;
		
		leftLim = el.width() - (viewWidth/3) - 1;
		topLim = el.height() - (viewHeight/3) - 3;
		
		if (leftPos > leftLim) leftPos = leftLim;
		if (topPos > topLim) topPos = topLim;
		
		el.css('backgroundPosition', leftPos + 'px ' + topPos + 'px');
		$('#zoom-detail').css('backgroundPosition', (leftPos * -3) + 'px ' + (topPos * -3) + 'px');
		//el.attr('style', 'background-position: ' + leftPos + 'px ' + top + 'px');
		

		//var msg = 'Handler for .mousemove() called at ' + leftPos + ', ' + topPos + ' - ' + el.css('backgroundPosition');
		//console.log(msg);

	});
	
	
	
 	//    $('form#basket-add').submit(function(e){
 	// 	e.preventDefault();
 	// 	var form = $(this);
 	// 	var data = form.formSerialize();
 	// 	$.post(form.attr('action'), data, function(data){
 	// 		showBasketMessage(data.message, data.result);
 	// 		setBasketSummary(data.payload['totals']['text'],data.payload['totals']['rawprice']);
 	// 	}, 'json');
 	// });

}

$(document).ready(function(){

    $('a.modal').live('click', function(e){
        var that = $(this);
		$.get(that.attr("href"), "", function(data) {
			var modal = $.modal(data,{
				onShow: function(dialog) {
					$.modal.impl.setPosition();
                    Cufon.refresh();
				},
				overlayClose: true
			});
			$(".simplemodal-close").live("click", function(){
				e.preventDefault();
				modal.close();
			});
			formSetup(that.attr("href"));
		});
		e.preventDefault();
    });
    
    $('#footer .newsletter-signup').submit(function(e){
		e.preventDefault();
		var $this = $(this);
		var d = $this.formSerialize();
		$.post($this.attr('action'), d, function(data){
			data = eval(data);
			if(data.result){
                $this.fadeTo(250,0, function(){
                    $(':not(h4)',$this).remove();
                    $('h4',$this).show().text(data.payload);
                    $this.fadeTo(250,1);
                });
            }else{
                var p = $('#footer .newsletter-signup p.error');
                if(p.length == 0){
                    var elIn = $('input[type=text]', $this).css('border', '1px solid #E24948');
                    p = $('<p>').addClass('error').appendTo($this);
                }
                p.css('opacity',0).text(data.payload).fadeTo(250,1);
            }
		});
	});
	
});


/* ---------- End /javascript/global.js ---------- */


