/*jslint evil: true, forin: true */

//-- Vodafone UI elements --
//-- vdfCarousel, vfTabs, vdfAccordion --


// Vodafone Carousel plugin
// Author: Holger Hellinger (2010), James Westgate (2011) (http://www.sapient.com)
// Version 1.2

(function($) {
	
	var instances = 1; 
	
	$.fn.vdfCarousel = function(config) {
		
		$.fn.vdfCarousel.defaults = {
			carouselContainer : 'ul.carousel',
			carouselAutoInterval : 0, //When above zero, scroll to the right after the set interval.						
			elementWidth : 350,	
			closeButton : null, //If a closing button is needed enter HTML for it (class closeBtn)	
			openButton : null,	//If a open button is needed enter HTML for it (class openBtn)
			navigationDropElement : 'h2.panelheader', //Where to put the Navigation
			navigationContainer : '<span class="panel carouselNavigation"></span>', //Container for the navigation (html)
			navigationContainerElement : '.panel.carouselNavigation', //Classname string eg ".navigationContainer"	
			navigationArrows : '<a title="previous item" class="dir left" href="#">left</a><a title="next item" class="dir right" href="#">right</a>', //HTML for arrows, must have a.dir right/left
			navigationDots : '<a title="###" class="dot" href="#" rel="###">###</a>', //HTML for Dots/Pagination, must have a.dot
			beforeNavigate: null, //function callback before navigation
			navigate: null //function callback when navigate completes
		};
				
		var opts = $.extend({}, $.fn.vdfCarousel.defaults, config);

		return this.each(function(index) {
						
			var self = $(this);
		
			var carouselElements, carouselElementsLength;
			var animated = false;
			var carouselContainerElement = self.find(opts.carouselContainer);
			var intervalTimer = 0;
			
			//Tab focus fix
			var elementStr = 'ul.carousel li.carouselElement';
			focusFix(self, elementStr, 0, opts);
			
			//Overwrite the predefined width with the new calculated one		
			var elementWidth = $(elementStr, self).width();
			$(elementStr, self).css('width', elementWidth);
			
			//Init the Carousel 
			carouselElements = carouselContainerElement.find('li.carouselElement');
			carouselElementsLength = carouselElements.length;
			
			//If no elements do not animate (causes display issues)
			if (carouselElementsLength <= 1) return false; 		
			
			//Clone first and last element to allow smooth sliding/animating
			$(carouselElements[0]).clone().removeClass('focused').addClass('ignoreTabbing').insertAfter(carouselElements[carouselElementsLength-1]);
			$(carouselElements[carouselElementsLength-1]).clone().addClass('ignoreTabbing').insertBefore(carouselElements[0]);
			
			//Fix position (initially the carousel must hide the 'first' while last one)
			carouselContainerElement.css({'left': -elementWidth, 'width': elementWidth * (carouselElementsLength + 2) + 100});
			
			//Set an ID if not present 
			var containerId = carouselContainerElement.attr('id');
			if (containerId==='') {
				containerId = 'carousel' + (instances++) + '_auto';
				carouselContainerElement.attr('id', containerId);
			}
			
			//Adding unique IDs
			carouselElements.each(function(i) {
				$(this).attr('id', containerId + '_' + i);
			});
			
			//ARIA initial
			$(carouselContainerElement).attr({'role':'slider','aria-valuemax':carouselElementsLength,'aria-valuemin':'1','aria-valuenow':'1','aria-activedescendant':'carouselElemId0'});
	
			//Build carousel navigation
			//add carousel navigation if a container for it is present
			var navigationDropContainer = self.find(opts.navigationDropElement);
			if (navigationDropContainer.length) {
					
				//prepend the container to the dropzone
				navigationDropContainer.prepend(opts.navigationContainer);
				
				//Add Arrows if present
				navigationDropContainer.find(opts.navigationContainerElement).prepend(opts.navigationArrows);
				
				//Add pagination if present
				if (opts.navigationDots) {
					
					var builder = ['<span class="dotContainer">'];
					for (var i=0; i < carouselElementsLength; i++) {
						var temp = opts.navigationDots.replace(/###/g, i+1);
						if (i===0) temp = temp.replace(/dot/g, 'dot activeDot');
						builder.push(temp);
					}
					builder.push('</span>');
					navigationDropContainer.find(opts.navigationContainerElement).prepend(builder.join(''));
				}
				
				//Add closebutton and openbutton if wanted
				var closeButtonElement, openButtonElement;
				if (opts.closeButton) {
					closeButtonElement = $(opts.closeButton);
					navigationDropContainer.find(opts.navigationContainerElement).append(closeButtonElement);
					
					closeButtonElement.click(function(event) {
						
						$(this).css('visibility','hidden');
						
						$(self).animate({height:['toggle', 'swing'], opacity:'toggle'}, {duration: 200, queue:true, complete: function() {
							$(openButtonElement).css('visibility','visible').show();						
						}});
						return false;
					});	
				}
				if (opts.openButton) {
					openButtonElement = $(opts.openButton);
					openButtonElement.insertBefore(self);
					
					openButtonElement.click(function(event) {
						
						$(this).css('visibility','hidden');
						
						$(self).animate({height:['toggle', 'swing'], opacity:'toggle'}, {duration: 200, queue:true, complete: function() {
							$(closeButtonElement).css('visibility','visible');
						}});
						return false;
					});
				}
				
				//ARIA
				$(opts.navigationContainerElement).attr('role','menu');
				$(opts.navigationContainerElement +' a').attr({'role':'menuitem','aria-haspopup':'false','aria-controls':$(carouselContainerElement).attr('id')});
				
				$(self).mouseenter(function() {

					//Cancel timer
					clearAutoInterval();
				});
				
				$(self).mouseleave(function() {
					
					//Cancel timer
					setAutoInterval(carouselElementsLength);
				});
					
				//Add click events on navigation elements
				self.find('a.dot').click(function(event) {		

					//Cancel timer
					clearAutoInterval();
					
					animate($(this).attr('rel'), null, carouselElementsLength);
					event.preventDefault();
				});	
				
				self.find('a.dir').click(function(event) {
					
					//Cancel timer
					clearAutoInterval();
					
					animate( null, ($(this).hasClass('right')) ? 'right' : 'left', carouselElementsLength);
					event.preventDefault();
				});	
			}
			
			//Set up auto interval if required
			setAutoInterval(carouselElementsLength);
			
			//Helper functions
			function setAutoInterval(carouselElementsLength) {
				
				if (opts.carouselAutoInterval > 0 && !intervalTimer) {
										
					intervalTimer = setInterval(function(){
					
						animate(null, 'right', carouselElementsLength);
						
					}, opts.carouselAutoInterval);
				}
			}
			
			//Clear any auto scroll timing
			function clearAutoInterval() {
				
				if (intervalTimer) {
					clearInterval(intervalTimer);
					intervalTimer = null;
				}
			}
			
			function animate(elem, direction, len) {	
			
				if (!animated) {
					
					animated = true;
					
					//show for sliding
					$('ul.carousel li.ignoreTabbing').css('visibility','visible');
					
					var left = 0;
					if (elem !== null) left = -(elementWidth * elem);
					if (direction !== null) {
						
						var actLeft = parseInt(carouselContainerElement.css('left'), 10);
						left = (direction === 'left') ? actLeft + elementWidth : (direction === 'right') ? actLeft - elementWidth : left;
					}
					
					//Highlight navigation
					var elementToHighlight = parseInt(Math.abs(left / elementWidth), 10);
					elementToHighlight = (elementToHighlight === len + 1) ? 1 : elementToHighlight;
					
					var elem = elementToHighlight-1;
					
					//Remove activated class
					var optionDots = self.find('a.dot');
					var dotsLength = optionDots.length - 1;
					
					optionDots.removeClass('activeDot').each(function(i) {	
						if (i===elem || (elem === -1 && i == dotsLength)) $(this).addClass('activeDot'); //Add class
					});
					
					//Add a class focused and several tabindexs on the actual focused element
					focusFix(self, 'ul.carousel li.carouselElement', elementToHighlight, opts);
				
					//Raise beforeNavigate callback 
					if (opts.beforeNavigate) opts.beforeNavigate(elementToHighlight-1);
					
					carouselContainerElement.animate({left:left}, {duration: 400, queue:true, complete: function() {
								
						var container = carouselContainerElement, width = elementWidth;
						var actLeft = parseInt(container.css('left'),10);
				
						if (actLeft === 0) container.css('left',-width * len);
						if (actLeft <= -(width * len + width)) container.css('left',-width);
						
						//hidden to avoid tabbing
						$('ul.carousel li.ignoreTabbing').css('visibility','hidden');
								
						animated = false;
						if (opts.navigate) opts.navigate(elementToHighlight-1); //Raise navigate callback
					}});
				}
				return false;
			};
		
			//Add a class focused and several tabindexs on the actual focused element
			function focusFix(self, elementStr, elementToHighlight, opts) {
				
				$(elementStr, self).each(function(i) {
					
					var that = $(this);
					that.removeClass('focused').removeAttr('tabindex').attr('tabindex','-1');
					that.find('a','input').attr('tabindex','-1');
					
					if (i === parseInt(elementToHighlight, 10)) {
						
						//Add class
						that.addClass('focused').removeAttr('tabindex').attr('tabindex','1');
						that.find('a','input').removeAttr('tabindex');
						
						//Active ARIA
						carouselContainerElement.attr({'aria-activedescendant':'carouselElemId'+(i-1),'aria-valuenow':i});
					}
				});
			};
			

		});
	};
	
})(jQuery); 


// Vodafone Tabs plugin
// Author: Ryan Mitchell (2010), James Westgate (2011) (http://www.sapient.com)
// Version 1.21
 
(function($) {
	
	$.fn.vfTabs = function(config) {
		
		return this.each(function(i, tabbedContentItem) {
			
		
			var self = this;
			
			// element-specific code here
			var defaults = { 
				activeState : 'activeTabElement',
				tabContainerSelect : '.tabbedContent',
				tabListClass : 'tabList',
				setHeight : false,
				updateFromHash : true,
				tabbedContentItem : null,
				tabListElement : null,
				tabBoxHeightArray : [],
				tabListItemArray : [],
				tabBoxArray : [],
				previousItem : 0,
				tabId : ''
			};
			
			//extend/overrule defaults with the passed in config
			var opts = $.extend({}, defaults, config);
		
			tabbedContentItemElements = $(tabbedContentItem);
			
			opts.tabId = tabbedContentItemElements.attr('id');
			if (opts.tabId == '') {
				opts.tabId = 'tabsItem' + i;
				tabbedContentItemElements.attr('id', opts.tabId);
			}
			opts.tabbedContentItem = tabbedContentItemElements;
	
		
			//-- Initialise the object
		
			//check for a custom height
			var aCustomWidth = tabbedContentItemElements.attr('class').match(/tabbedContentHeight_[A-Za-z0-9]*/);
			if (aCustomWidth) {
				opts.setHeight = aCustomWidth[0].replace('tabbedContentHeight_','');
			}
			
			//Create the tab list from headers
			opts.tabListElement = $('<ul id="tabList_' + opts.tabId + '" class="'+opts.tabListClass+' JSTabs"></ul>');
			//get tabs not nested
			var aItems = tabbedContentItemElements.find('.tabLead:not(#'+opts.tabId + ' ' + opts.tabContainerSelect +' .tabLead), .tabHeader:not(#'+opts.tabId + ' ' + opts.tabContainerSelect + ' .tabHeader)');
			//header creation
			for (var iterator=0,iLen=aItems.length; iterator < iLen; iterator++) {
				var eItem = aItems[iterator];
				var eLiItem = $('<li id="tab_'+eItem.id+'"><a href="#' + eItem.id + '"><span>'+eItem.innerHTML+'</span></a></li>');
				if (iterator === 0) {
					eLiItem.addClass('firstTab');
				}
				else if (iterator === aItems.length-1) {
					eLiItem.addClass('lastTab');
				}
				
				opts.tabListElement.append(eLiItem);
				$(eItem).hide();
			}
			
			//add class to state how many tabs there are
			opts.tabListElement.addClass('contains'+aItems.length+'Tabs');
			tabbedContentItemElements.prepend(opts.tabListElement);
			
			var sTabElementFindString = 'ul.'+opts.tabListClass+' li:not(#'+opts.tabId+' ul.'+opts.tabListClass+' ul.'+opts.tabListClass+' li), div.tabContentBox:not(#'+opts.tabId+' div.tabContentBox div.tabContentBox)';
			var eTabElements = tabbedContentItemElements.find(sTabElementFindString);
					
			var iActionNumbers = eTabElements.length/2;
			
			opts.tabListItemArray = eTabElements.slice(0,iActionNumbers);
			opts.tabBoxArray = eTabElements.slice(iActionNumbers);
	
			for (var k = 0, l = opts.tabBoxArray.length; k < l; k++){
				if (opts.setHeight) {
					opts.tabBoxHeightArray[k] = opts.setHeight;
				}
				else {
					opts.tabBoxHeightArray[k] = $(opts.tabBoxArray[k]).outerHeight();
				}
			}
			
			var initialTab = 0;
			
			//if we are tracking hash values, check for a valid initial state
			if (opts.updateFromHash) {
				var sCurrentHash = location.hash;
				var iLen2 = opts.tabListItemArray.length;
				for (var iIndex = 0; iIndex < iLen2; iIndex++) {
					if (('#'+opts.tabListItemArray[iIndex].id) == sCurrentHash) {
						initialTab = iIndex;
						//we're done here!
						iIndex = iLen2;
					}
				}
			}
			
			//Select first item and display it
			selectItem.call(opts.tabListItemArray[initialTab], initialTab);
			
			//assign click handlers		
			opts.tabListItemArray.each(function(i, element){
			
				$(element).bind('click', opts, function (event) {
					
					//raise tab click eventon the item, passing through it's index and the tab containers opts
					$(this).trigger('tabActionEvent', [i, opts]);
					
					//process call
					return selectItem.call(this,i);
				});
			});
			
			
			//Tab is selected when clicked, removes the active css class from all tabs in the list
			//Displays the corresponding content box when a tab is clicked	
			function selectItem(i, manualCall) {		
				
				var manualCallLocal = !!manualCall;
				$(opts.tabListElement).find('.' + opts.activeState).removeClass(opts.activeState);
				
				var targetElement = (!manualCallLocal) ? targetElement = $(this): $(opts.tabListItemArray[i]);
	
				targetElement.addClass(opts.activeState);
				
				//add active state to the child, used for specfic styling in IE6
				targetElement.children('a').addClass(opts.activeState);
				
				opts.tabBoxArray.hide();
				show(i, manualCallLocal);		
				opts.previousItem = i; //here we set the previous item as the current item
				
				return false;
			};	
			
	
			//Display tab content div, use a slide open animation, using the height of the last open tab as the start point
			function show(iIndex, manualCall){
	
				var height = opts.tabBoxHeightArray[iIndex];
				var tabBox = $(opts.tabBoxArray[iIndex]);
				
				if (opts.setHeight === false) {
					
					tabBox.css({height : opts.tabBoxHeightArray[opts.previousItem], display : ''})
					tabBox.animate({height: height}, 200, function () {
							
						//reset styles and hide
						tabBox.css('height','auto');
						if (!manualCall) $('body').trigger('tabOpenedEvent', [self, iIndex]);
					});
				}
				else {
					tabBox.css({display : '', height : opts.setHeight + 'px'});
					if (!manualCall) $('body').trigger('tabOpenedEvent', [self, iIndex]);
				}
				return false;	
			};
		});
	};
	
})(jQuery);



// Vodafone Accordion plugin
// Author: Ryan Mitchell (2010), James Westgate (2011) (http://www.sapient.com)
// Version 1.3

(function($) {
	
	$.fn.vdfAccordion = function(config) {
		
		$.fn.vdfAccordion.defaults = {
			headerSelect : '.accordionHeader',						
			contentSelect : 'div.accordionContent',
			activeState : 'active',
			inactiveState : 'inactive',
			openState : 'accordOpen',
			closePrevious : true
		};
		
		var options = $.extend({}, $.fn.vdfAccordion.defaults, config);

		return this.each(function() {

			var self = $(this);
			var accordionBoxHeights = [];
			var accordionList, accordionBoxes;
			var lastView = false;
			
			//init functions
			accordionList = self.find(options.headerSelect);
			accordionBoxes = self.find(options.contentSelect);
			
			//get all the heights		
			for (var i = 0, j = accordionBoxes.length; i < j; i++){
				accordionBoxHeights[i] = $(accordionBoxes[i]).height();
			}
			
			//in order to make the accordion keyboard accessble we need links
			var addLinks = false;
			var wrap;
			var childLinkElements = $(accordionList[0]).find('a');
			if (childLinkElements.length === 0) {
				addLinks = true;
				
				//create wrapping element used below once
				wrap = $('<a href="#"></a>');
			}
			
			//for each header item
			accordionList.each(function(index, item){
				
				var itemElements = $(item);
				
				//add a link to enable keyboard navigation
				if (addLinks) itemElements.wrapInner(wrap);
				
				//add click action
				itemElements.click(function(event) {		
					expandView(index, this);
					return false;
				});	
				
				//set init state?
				if (itemElements.hasClass(options.activeState)) {
					expandView(index, item);
				}
				else if (itemElements.hasClass(options.inactiveState)) {
					
					//itemElements.css({overflow:'hidden',display:'none'});
					lastView = {
						'index': index,
						'content': $(accordionBoxes[index]),
						'height': accordionBoxHeights[index]
					};
					resetView(false);
				}
			});
			
			//This resets the accordion view
			function resetView(isTransition) {
				
				if (lastView) {		
					
					$(accordionList[lastView.index]).removeClass(options.activeState).addClass(options.inactiveState);
					lastView.content.removeClass(options.openState);
					
					if (isTransition) {
						contract(lastView.content, lastView.height);
					}
					else {
						$(lastView.content).css({overflow:'hidden',display:'none'});
					}
				}
			};
		
			//Accordion view responds to click and is expanded
			function expandView(iIndexPos, eItem) {	
				
				$(eItem).removeClass(options.inactiveState).addClass(options.activeState);
				
				//if this is a new view
				var contentElements = $(accordionBoxes[iIndexPos]);
				var height = accordionBoxHeights[iIndexPos];
				
				if (options.closePrevious === false) {
					lastView = {
						'index': iIndexPos,
						'content': contentElements,
						'height': height
					};
				}
				
				if (contentElements.css('display') === 'none') {
					if (options.closePrevious) {
						resetView();
					}
					contentElements.addClass(options.openState);
					expand(contentElements, height);
					
					lastView = {
						'index': iIndexPos,
						'content': contentElements,
						'height': height
					};
				}
				else {
					resetView();
				}
			};
		});
	}
	
	//vdf.Tools.Expander.expand
	//This expands the relevant responder
	function expand(responderElement, iCurrentHeight) 
	{
		var animateSettings = { opacity:100, height: iCurrentHeight }
		if ($(document.body).hasClass('browserIE6')) animateSettings = { height: iCurrentHeight };

		responderElement.css('height',0).animate(animateSettings, 200, function () {
			responderElement.css({ height:'', display:'block'});
		});
		
		return false;		
	};
	
	//vdf.Tools.Expander.contract
	//This expands or contracts the relevant responder
	function contract(responderElement) 
	{
		var animateSettings = { opacity:0, height: 0 }
		if ($(document.body).hasClass('browserIE6')) animateSettings = { height: 0 }
		
		$(responderElement).css('overflow','hidden').animate(animateSettings, 400, function () {
			$(responderElement).css('display','none');
		});
		
		return false;
	};
	
})(jQuery); 



/*!
 * Vodafone Modal layer plugin
 * Originally for the VF Total Comms project
 * Author: Ryan Mitchell (2010), James Westgate (2011) (http://www.sapient.com)
 * Version 1.3
 * 
 */
(function($) {
	
	var parentElement = 'body';
	var eModalContainer = false;

	$.fn.vfModalLayer = function(callback) {
		
		//Create event bindings
		$(".modalLayer").live('click', startModalLayer);
		
		//Live Event for each button and anchor that looks like this. 
		$('#mask, .ModalLayer .closeBtn, .ModalLayer .link_close, .ModalLayer a.cancel').live("click", function(oEvent,sLiveEvent){
			$(parentElement).data('activeModal').hide();
			return false;
		});
		
		//live event for form submission in modallayer
		$("#modalContainer form.ajaxForm").live('submit', modalFormSubmit);
		
		//set the callback function
		if (callback) callbackFunction = callback;
		
		//no direct action to take at the point of binding
		return this;
	};
	
	// Open a modal layer
	// Searches for casses and matches and switches to the ajax branch, or static branch
	function startModalLayer(event) {
		
		var targetElement = this;
		var modalType = 'modalType_ajax';
		var modalElements, modalClassString, modalLayer, messageData;
		var initCall = true;
		var bAjaxCall = true;
		var classString = "ajax";
		
		modalClassString = $(targetElement).attr('class').match(/modalStyle_[A-Za-z0-9]*/);
		modalClassString = (modalClassString) ? modalClassString[0].replace('_','') : 'modalStyleClassic';
		
		//set callback function
		var modalFunctions = callbackFunction;

		//create or reuse existing layer
		modalLayer = $(parentElement).data(modalType);
		if (modalLayer) {
			initCall = false;
			modalLayer.Message(messageData, classString, modalFunctions, initCall, targetElement);
		}
		else {

			modalLayer = new Modal({modalType : modalType, modalClassString : modalClassString});
			
			//get initial content
			if (bAjaxCall === false) {
				messageData = modalElements.html();
				modalLayer.Message(messageData, classString, modalFunctions, initCall, targetElement);
			}
			else {
				
				//load remote content
				$.ajax({
					
					url: targetElement.href,
					type: 'GET',
					success: function(messageDataReturned) {
						messageData = messageDataReturned;
					},
					error: function(XMLHttpRequest, textStatus, errorThrown) {
						messageData = '<div class="closeOverlay"><span class="link_close"><a href="#">Close</a></span></div><div class="modalWidthElement" style="width:450px"><h3>Sorry! We are not able to process your request now, please try later.</h3></div>';
					},
					complete : function (XMLHttpRequest, textStatus) {
						modalLayer.Message(messageData, classString, modalFunctions, initCall, targetElement);
					}
				});
			}
		}
		
		return false;
	};
	
	//Class constructor
	function Modal(modalSettings) {
		
		var data = {};
		var modalType = '';
	
		this.modalElement = null;
		
		//Single text message Method, thats hands a callback, an ln Data and an Target to the show Method
		this.Message = function(messageData, classString, modalFunctions, initCall, eventTarget) {
			
			if (initCall) {
				data.data = messageData;
				data.from = classString;
				
				if (data.from !== 'ajax') $(data.from).empty();
				this.updateContent(messageData);
			}
			this.show(modalFunctions, initCall, eventTarget);
		};
		
		this.updateContent = function(data) {
			this.modalElement.find('.modalLayerContent').empty().html(data);
		};
		
		//Reset the position of the lightbox on screen
		this.fixPosition = fixPosition();

		//Shows the ModalLayer with initializing of all necessary Elements
		//Contains a callback, and if it is not an initial call, contents are not filled again.
		this.show = function(callback, initCall, eventTarget) {
			
			//set active modal for any timeout calls
			$(parentElement).data('activeModal',this);
			showMask();
			
			this.modalElement.removeAttr('style');
			
			//chose transition
			if (typeof(this.animations[modalType]) == 'object') {
				this.animations[modalType].show.call(this, initCall, eventTarget, callback);
			}
			//use default
			else {
				this.animations.modalStyleClassic.show.call(this, initCall, eventTarget, callback);
			}
			
			//set focus
			this.modalElement.focus();
			
			return false;
		};
		
		//Hides the ModalLayer
		this.hide = function() {
			
			var self = this;
			
			hideMask();
			
			//chose transition
			if (typeof(this.animations[this.modalType]) == 'object') {
				this.animations[this.modalType].hide.call(this, animationEnd);
			}
			//use default
			else {
				this.animations.modalStyleClassic.hide.call(this, animationEnd);
			}
			return false;
			
			function animationEnd () {
				self.modalElement.hide();
				var sModalID = self.modalElement.attr('id');
				if (sModalID == 'modalType_ajax') {
					self.modalElement.remove();
					
					//delete vdf.Tools.ModalLayer.aModalLayers[sModalID];
					$(parentElement).data(modalType, null);
				}
				//raise event to highlight that the modal has closed
				$(parentElement).trigger('modalClosedEvent', [sModalID]);
			};
		};
		
		//Contains animation functions for lightbox. Each definition must include a show and hide
		this.animations = {
			
			//manufacturors pages animations
			modalStyleClassic : {
				
				show : function (initCall, eventTarget, callback) {
					var modalLayerElement = this.modalElement;
					fixPosition();
					modalLayerElement.fadeIn(300, function () {
						
						$(parentElement).trigger('modalOpenEvent', [modalLayerElement.attr('id')]);
						if (callback) callback.call(this, initCall, eventTarget);
					});
				},
				hide : function (animationEnd) {
					var modalLayerElement = this.modalElement;
					modalLayerElement.animate({width: '0px', height: '0px', top:'50%', left:'50%', opacity: 0}, 100, animationEnd);
				}
			},
			
			//classic co.uk
			modalStyleClassic2 : {
				
				show : function (initCall, eventTarget, callback) {
					
					var _this = this;
					var $eModalLayer = _this.modalElement;
					
					$eModalLayer.css({display:'block', visibility:'hidden'});
					
					var aModalWidthElement = $eModalLayer.find('.modalWidthElement');
					
					//get the final height of the window & width
					var iFinalWidth = (aModalWidthElement[0]) ? $(aModalWidthElement[0]).outerWidth() : $eModalLayer.outerWidth();
					var iFinalHeight = $eModalLayer.outerHeight();

					//set the start height & width & left and right
					var iStartHeight = 100;
					var iStartWidth = 150;
					
					//get the start and end left
					var iContainerWidth = $(parentElement).width();
					
					var iStartLeft = (iContainerWidth-iStartWidth) / 2;
					var iFinalLeft = (iContainerWidth-iFinalWidth) / 2;
					var iViewportHeight = eModalContainer.height();
					var iFinalTop = (iViewportHeight - iFinalHeight) / 2;
				
					$eModalLayer.css({left : iStartLeft, width : iStartWidth, height : iStartHeight, top : iViewportHeight/2, overflow : 'hidden', visibility:'visible'})
					$eModalLayer.animate({ left:iFinalLeft, width:iFinalWidth}, 300);
						
					window.setTimeout(function () {
						$(parentElement).data('activeModal').animations.modalStyleClassic.show2.call(_this,iFinalHeight, iFinalTop, initCall, eventTarget, callback);
					}, 600);
				},
				
				//function used in show
				show2 : function (finalHeight, finalTop, initCall, eventTarget, callback) {

					var sModalID = this.modalElement.attr('id');
					
					this.modalElement.animate({height:finalHeight, top:finalTop}, 300, function() { 
						$(this).css('overflow','auto');
						
						//raise event to highlight that the modal has closed
						$(parentElement).trigger('modalOpenEvent', [sModalID]);
						if (callback) callback.call(this, initCall, eventTarget);
					}); 
				},
				
				hide : function (animationEnd) {
					animationEnd();
				}
			}
		};
	

		//-- Inital operations, happen when object is created
		
		//Create container
		if (!eModalContainer) {
			eModalContainer = $('<div id="modalContainer"></div>');
			var iViewportHeight = window.innerHeight ? window.innerHeight : $(window).height();
			eModalContainer.height(iViewportHeight);
			$(parentElement).append(eModalContainer);
		}
		
		modalType = modalSettings.modalClassString;
		this.modalElement = $(createModalLayer(modalSettings.modalType,modalType));
		
		eModalContainer.append(this.modalElement);
		
		//When the viewport is resized we should resize the modalContainer
		$(window).resize(function() {
			eModalContainer.height((window.innerHeight) ? window.innerHeight : $(window).height());
		});
		
		//create mask
		if ($('#mask').length === 0) eModalContainer.append(modalType === 'modalStyleManufacturors' ? $('<div id="mask"></div>') : $('<div id="mask" class="MaskClassic"></div>'));
	
		//append to global modal list
		$(parentElement).data(modalType,this);
	};
	
	//Initial setup of the ModalLayer
	//returns The String containing the Grid for a general Layer
	function createModalLayer(sModalName, modalType) {
		var html = (modalType === 'modalStyleManufacturors') ? '<a class="closeBtn" href="#">close</a>' : '';
		
		//set type of modal
		var sModalID = (sModalName) ? sModalName : 'ModalLayer';
		return ['<div id="', sModalID, '" class="ModalLayer ', modalType, '" tabindex="-1">', html, '<div class="modalLayerContent">', '</div>', '</div>'].join('');
	};

	//Show mask
	function showMask() {
		$('#modalContainer').css('visibility','visible');
		if ($('body').hasClass('browserIE6')) ie6Fix.hideSelectBoxes(true);
	};
	
	//Hide mask
	function hideMask() {
		$('#modalContainer').css('visibility','hidden');
		if ($('body').hasClass('browserIE6')) ie6Fix.hideSelectBoxes(false);
	};

	//Takes care of the position of the ModalLayer. Additional this is attached to a resize event of the window
	//Makes sure, that the Layer is alwas centered and at least inside the window.
	function fixPosition() {
		var activeModal = $(parentElement).data('activeModal');
		if (activeModal) {
			var modalLayerElement = $(activeModal.modalElement);

			var viewportHeight = eModalContainer.height();  
			var top = viewportHeight/2-modalLayerElement.height()/2;
			if (modalLayerElement.css('position') === 'absolute') {
				top = 30 + (document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop;
			}
			if (top < 0)  top = 0;
		
			modalLayerElement.css('top', top);
			modalLayerElement.css('left', $('#mask').width() / 2 - modalLayerElement.width() / 2);    
		}
	};

	//When called submits the form using ajax and repopulates the lightbox with the returned information
	function modalFormSubmit(event, liveEvent) {
		var form = $(event.currentTarget);
		var parameters = form.serialize();
		var sDestination = form.attr('action');
		
		//update with loading state
		$(parentElement).data('activeModal').updateContent('<div class="loadingBox">The form is being submmitted, please wait.</div>');
		
		//send the form via ajax and get the response
		$.post(sDestination, parameters, function(data){
			
			//update the modal, removes loading state
			$(parentElement).data('activeModal').updateContent(data);
		});
		return false;
	};
	
	//Default call back function
	var callbackFunction = function () {

	};

	
})(jQuery);


/*
 * A png fixing plug-in for IE6
 * 
 * Based on methods found in Supersleight (Drew McLellan) and DD_belated png fix (Drew Diller).
 * Author: James Westgate (2011)
 * http://www.opencomponents.com/superpng
 * 
 * Dual licensed under the MIT or GPL Version 2 licenses.
 *  
 * Version 1.2
 */

(function($){
	
	var opts;
	var vmlInit = true;

	$.fn.superpng = function(settings) {
		
		if (!$.browser.msie || parseInt($.browser.version, 10) > 6) return;
		
		var result; //Set up chainability
		var imgCache = {};
		
		if (opts == null) opts = $.extend({}, {
			cache: true,
			path: 'blank.gif',
			mode: 'auto'  //filter, vml
		}, settings);
		
		//Caching of background images not enabled by default in IE6
		if (opts.cache) document.execCommand('BackgroundImageCache', false, true);
		
		result = this.each(function() {
			
			var self = $(this);
			var bg = self.css('background-image');
			var initial = (this.vml === undefined);	
				
			//Background pngs
			if (!initial || (opts.mode !== 'filter' && bg.match(/\.png/i) !== null)) {
				
				var src = bg.substring(5, bg.length-2);
				var bgposx = self.css('backgroundPositionX');
				var bgposy = self.css('backgroundPositionY');
				
				self.css('background-image', ['url(', opts.path, ')'].join(''));
				
				//Determine if we use the alpha image method, or the vml method
				if (initial && opts.mode !== 'vml' && typeof(bgposx) === 'undefined' && typeof(bgposy) === 'undefined') {
					self.css('filter', ["progid:DXImageTransform.Microsoft.AlphaImageLoader(src='", src, "', sizingMethod='crop')"].join(''));					
				}
				else {
					
					//Add vml namespace and built-in behaviour
					if (vmlInit) {
				
						vmlInit = false;
										
						//vml behaviour and additional stylesheet code			
						$('head').append('<style media="screen">vml\\:* {behavior:url(#default#vml);} .superpng-container {position:relative; margin:0; padding:0; display:block; overflow: hidden} .superpng-vml {position: absolute; top:0; left:0; margin:0}</style>');
					}
					
					//Blank out existing image early
					if (initial) self.css('background-image', 'url(' + opts.path + ')');

					(function(self, initial, src, bgposx, bgposy, imgCache) {
						
						var img = imgCache[src];
						
						if (typeof img === 'undefined') {
							
							img = $(['<img src="', src, '" alt="" style="clear:both; display:inline; position: absolute; left: -9999px; top: -9999px;"></img>'].join(''));
							
							img.bind('load', function() {
							
								var element = $(this);
								imgCache[src] = element;
								addvml(self, initial, element, bgposx, bgposy);	
								
								if (result) cleanUp();							
							});
							
							img.appendTo('body');
						}
						else {
							addvml(self, initial, img, bgposx, bgposy);
						}
						
						function addvml(self, initial, element, bgposx, bgposy) {
							
							//Get width and height of container
							var width = self.width();
							var height = self.height();
							var repeat = self.css('backgroundRepeat');
							var location = '';
							var position = [getPosition(bgposx, width), ',', getPosition(bgposy, height)].join('');
										
							//If no repeat then work out left and top relative to div
							if (repeat === 'no-repeat' || repeat === 'repeat-y') {
								if (bgposx.match('right') || bgposx.match('100%')) {
									location = ['left:', width - element.width(), 'px;'].join('');
									width = element.width();
								}
							};
							
							if (repeat === 'no-repeat' || repeat === 'repeat-x') {
								if (bgposy.match('bottom') || bgposy.match('100%')) {
									location += ['top:', height - element.height(), 'px;'].join('');
									height = element.height();
								}
							}
							
							var style = ['width:', width, 'px; height:', height, 'px;'].join('');
						
							//Insert a relative container containing vml
							if (initial) {
								
								//Create vml element and place inside container
								var builder = ['<div class="superpng-container" style="', style, location, '"><vml:rect stroked="f" class="superpng-vml" style="', style, '"><vml:fill type="tile" src="', src, '" position="', position, '"/></vml:rect></div>'];
								
								//Add to DOM
								self.wrapInner(builder.join(''));
								self.get(0).vml = $('.superpng-vml', self); //set a reference to the vml called 'vml'
							}
							
							//Update existing vml
							else {
								var fill = self.get(0).vml.children(':first');
								self.get(0).vml.attr('style', style);
								fill.attr('position', position);
							}
							
							function getPosition(pos, wh) {
								
								if (pos.match('px')) return parseFloat(pos.replace('px', '')) / wh;
								if (pos.match('%')) return parseFloat(pos.replace('%', '')) / 100;
								if (pos.match('right') || pos.match('bottom')) return 1;
						
								return 0;
							}
						}
						
						//Remove temporary elements
						function cleanUp() {
							for (var key in imgCache) {
								imgCache[key].remove();
							}
						}
						
					})(self, initial, src, bgposx, bgposy, imgCache);
				}
			}
			
			//image elements
			else if (self.is('img[src$=png]')){

				var styles = {
					'width': self.width() + 'px',
					'height': self.height() + 'px',
					'filter': ["progid:DXImageTransform.Microsoft.AlphaImageLoader(src='", self.attr('src'), "', sizingMethod='scale')"].join('')
				};
				
				self.css(styles).attr('src', opts.path);
			}

		});
		
		return result;
	};

})(jQuery);
