/*!
 * Remarkables Park
 * jQuery Tron
 */
 
 /* 
	@@ helpers.js
	---------------------------------------------------------------
	Used by jquery.tron2.js
	_______________________________________________________________
*/	

/* 
	@ util_dateRangeDate
	---------------------------------------------------------------
	Used by util_strDateRange
	global.js
	_______________________________________________________________
*/		

	function util_dateRangeDate( dateIn )
	{
		// START DATE	
		var date = dateIn;
		var dateOut;		
		
		if ( date.indexOf('-') != -1 ) // dd-mm-yy
		{			
			var date_parts = date.split('-');
			var date_dd = date_parts[0];
			var date_mm = date_parts[1];
			var date_yy = date_parts[2];	
						
			var temp_m = util_strMonth({
				intMonth: date_mm,
				zeroOffset: true,
				shortMonth: true
			});							
						
			date = ( date_dd + ' ' + temp_m + ' 20' + date_yy );		
			dateOut = new Date( date );			
		}
		else
		{
			date = ( date * 1000 ); // 1261789200 - fix Unix Epoch timestamps (http://www.epochconverter.com/) so that they're the correct length for JS conversion
			dateOut = new Date( parseInt( date, 10 ) );
		}

		//util_log( date + ', dateOut = ' + dateOut );
		
		var dateOutDay = util_strDay( dateOut.getDay() );
		var dateOutDate = dateOut.getDate();		
		
		var dateOutMonth = util_strMonth({
			intMonth: dateOut.getMonth(),
			zeroOffset: false,
			shortMonth: true
		});
				
		var dateOutYear = dateOut.getFullYear();		
		
		return {
			date : date, 
			dateOut : dateOut,
			dateOutDay : dateOutDay,
			dateOutDate : dateOutDate,
			dateOutMonth : dateOutMonth,	
			dateOutYear : dateOutYear			
		};		
	}

/* 
	@ util_strDateRange
	---------------------------------------------------------------
	Convert the JSON start and end dates into a date range string.
	global.js	
	_______________________________________________________________
*/		

	function util_strDateRange( args )
	{
		var defaults = {
			date1in: false,
			date2in: false,
			outputDayIfSingle: false,
			outputDayIfRange: false			
		};				

		var opts = $.extend(defaults, args);	
		var date1in = opts.date1in;
		var date2in = opts.date2in;
		var outputDayIfSingle = opts.outputDayIfSingle;
		var outputDayIfRange = opts.outputDayIfRange;		

		// OUTPUT
		var dates = '';		
		
		// START DATE	
		var date1Vars = util_dateRangeDate( date1in );
		var date1 = date1Vars.date;					
		var startDateDay = date1Vars.dateOutDay;
		var startDateDate = date1Vars.dateOutDate;			
		var startDateMonth = date1Vars.dateOutMonth;	
		var startDateYear = date1Vars.dateOutYear;
		
		// END DATE		
		var date2Vars = util_dateRangeDate( date2in );	
		var date2 = date2Vars.date;				
		var endDateDay = date2Vars.dateOutDay;
		var endDateDate = date2Vars.dateOutDate;			
		var endDateMonth = date2Vars.dateOutMonth;	
		var endDateYear = date2Vars.dateOutYear;		
		
		// HF won't filter duplicate dates at their end so we need to check here:		
		// a simple match is not enough as this includes the time which is not shown
		var startDateParse = Date.parse( startDateMonth + ' ' + startDateDate + ' ' + startDateYear ); // eg Jan 01 2001				
		var endDateParse = Date.parse( endDateMonth + ' ' + endDateDate + ' ' + endDateYear ); // eg Jan 01 2001				
		
		//util_log( startDateMonth + ' ' + startDateDate + ' ' + startDateYear + ' vs ' + endDateMonth + ' ' + endDateDate + ' ' + endDateYear );
		
		var isRange = false;		
		isRange = ( ( date1 != date2 ) && ( startDateParse != endDateParse ) );				
		
		//util_log( startDateParse + ' vs ' + endDateParse + ' = isRange? ' + isRange );
		
		// output start date		
		if ( ( !isRange && outputDayIfSingle ) || ( isRange && outputDayIfRange ) )
		{		
			dates += ( startDateDay + ' ' );
		}
		
		dates += ( startDateDate + ' ' + startDateMonth );

		// output end date	
		
		if ( isRange )
		{
			if ( startDateYear != endDateYear )
			{
				dates += ( ' ' + startDateYear );		
			}			
			
			dates += ( ' \u2014 ' );
		
			if ( outputDayIfRange )
			{
					dates += ( endDateDay + ' ' );		
			}			

			dates += ( endDateDate + ' ' + endDateMonth + ' ' + endDateYear );
		}
		else
		{
			dates += ( ' ' + endDateYear );			
		}

		return dates;
	}
	
/* 
	@ util_strDay
	---------------------------------------------------------------
	Convert the date object day number into the matching string
	datepicker.js
	_______________________________________________________________
*/	

	function util_strDay( intDay )
	{		
		var str = '';
		
		switch( intDay )
		{
			case 0 :
				str = 'Sun';
				break;					
			case 1 :
				str = 'Mon';
				break;
			case 2 :
				str = 'Tue';
				break;			
			case 3 :
				str = 'Wed';
				break;
			case 4 :
				str = 'Thu';
				break;		
			case 5 :
				str = 'Fri';
				break;	
			case 6 :
				str = 'Sat';
				break;						
		}
		
		return str;
	}
	
/* 
	@ util_strMonth
	---------------------------------------------------------------
	Convert the date object month number into the matching string
	datepicker.js	
	_______________________________________________________________
*/	

	function util_strMonth( args )
	{		
		var defaults = {
			intMonth: false,		
			zeroOffset: false,		
			shortMonth: false
		};		

		var opts = $.extend(defaults, args);			
		var intMonth = opts.intMonth;
		var zeroOffset = opts.zeroOffset;
		var shortMonth = opts.shortMonth;

		var str = '';
		
		intMonth = parseInt(intMonth, 10); // 03 -> 3
		
		if ( zeroOffset )
		{
			intMonth = ( intMonth - 1 );
		}
		
		switch( intMonth )
		{
			case 0 :
				str = 'January';
				break;					
			case 1 :
				str = 'February';
				break;
			case 2 :
				str = 'March';
				break;			
			case 3 :
				str = 'April';
				break;
			case 4 :
				str = 'May';
				break;		
			case 5 :
				str = 'June';
				break;	
			case 6 :
				str = 'July';
				break;		
			case 7 :
				str = 'August';
				break;	
			case 8 :
				str = 'September';
				break;	
			case 9 :
				str = 'October';
				break;	
			case 10 :
				str = 'November';
				break;	
			case 11 :
				str = 'December';
				break;						
		}
		
		//util_log( 'util_strMonth() - shortMonth = ' + shortMonth );
		
		if (shortMonth)
		{
			str = str.substring(0, 3);
		}
		
		return str;
	}		
		
	/* 
		@ tron_unique_prefix
		---------------------------------------------------------------
		Used when a tron has a numbered nav, to ensure that we don't
		end up with several div#tron1 slides (in several trons)
		_______________________________________________________________
	*/					
		
		function tron_unique_prefix()
		{
			var str = '';
			var tron_len = $('.tronified').length;
			
			str = 'tron' + ( tron_len + 1 ); // eg tron1; +1 prevents first tron from being tron0
			
			return str;
		}	

/* 
	@ auto_advance_stop
	---------------------------------------------------------------		
	Usage
	$('#tron_or_carousel_id').auto_advance_stop();
	_______________________________________________________________
*/	

	(function($) 
	{		
		$.fn.auto_advance_stop = function() 
		{	
			if ( $(this).data('auto_advance_interval_var') && $(this).data('auto_advance_interval_timeout') ) // WT
			{
//				$(this).data('auto_advance_interval_var', '');
				window.clearInterval( $(this).data('auto_advance_interval_var') );
			}
			else
			{
				// legacy stuff	
				if ( $(parent_el).hasClass('widget-hotel-deals') )
				{
					window.clearInterval( $.globals.intervalId_widgetHotelDeals );
				}
				else if ( $(parent_el).hasClass('widget-hotel-deals-mini') )
				{
					window.clearInterval( $.globals.intervalId_widgetHotelDealsMini );	
				}
			}		
		};
	})(jQuery);			
	
/*
	@ auto_advance_start()
	---------------------------------------------------------------
	Reset the auto-advance interval (restart the timer)	
	
	Usage
	$('#tron_or_carousel_id').auto_advance_start();		
	_______________________________________________________________
*/		

	(function($) 
	{		
		$.fn.auto_advance_start = function() 
		{
			if ( $(this).data('auto_advance_interval_var') && $(this).data('auto_advance_interval_timeout') ) // WT
			{
				if ( $('body').hasClass('windowloaded') )
				{	
					wt_fade_out_flash(); // stop any active flash video				
					next_wt(); // advance immediately						
				
					$(this).data('auto_advance_interval_var', window.setInterval( next_wt, $(this).data('auto_advance_interval_timeout') ) ); // then advance again in N seconds
				}
				else
				{
					$(window).bind('load', function() 
					{			
						wt_fade_out_flash(); // stop any active flash video				
						next_wt(); // advance onload							
					
						$(this).data('auto_advance_interval_var', window.setInterval( next_wt, $(this).data('auto_advance_interval_timeout') ) ); // then advance again in N seconds
					});	
				}				
			}
			else
			{
				// legacy stuff
				if ( $(this).hasClass('widget-hotel-deals') )
				{
					if ( $('body').hasClass('windowloaded') )
					{
						next_widgetHotelDeals(); // advance immediately				
						
						$.globals.intervalId_widgetHotelDeals = window.setInterval( next_widgetHotelDeals, $.globals.autoAdvanceTimeout ); // then advance again in N seconds	
					}
					else
					{
						$(window).bind('load', function() 
						{		
							next_widgetHotelDeals(); // advance onload						
						
							$.globals.intervalId_widgetHotelDeals = window.setInterval( next_widgetHotelDeals, $.globals.autoAdvanceTimeout ); // then advance again in N seconds
						});				
					}			
				}
				else if ( $(this).hasClass('widget-hotel-deals-mini') )
				{			
					if ( $('body').hasClass('windowloaded') )
					{	
						next_widgetHotelDealsMini(); // advance immediately			
					
						$.globals.intervalId_widgetHotelDealsMini = window.setInterval( next_widgetHotelDealsMini, $.globals.autoAdvanceTimeout ); // then advance again in N seconds	
					}
					else
					{
						$(window).bind('load', function() 
						{			
							next_widgetHotelDealsMini(); // advance onload						
						
							$.globals.intervalId_widgetHotelDealsMini = window.setInterval( next_widgetHotelDealsMini, $.globals.autoAdvanceTimeout ); // then advance again in N seconds
						});		
					}				
				}						
			}								
		};
	})(jQuery);	

/*
	@ height_matchify()
	---------------------------------------------------------------
	Match the height of element 2 to the height of element 1
	Originally designed for the PWT homepage tron
	
	$('#widget-homepage-feature').find('.wrapper')
	.height_matchify({
		slave_prop: $('#widget-homepage-feature-intro .wrapper')
	});			
	_______________________________________________________________
*/		

	(function($) 
	{		
		$.fn.height_matchify = function(options) 
		{
			// DEFAULTS
			$.fn.height_matchify.defaults = {
				slave_prop: false /* $(el) | slave's prop element */
			};									
			
			// USER SPECIFIED OVERRIDES
			opts = $.extend($.fn.height_matchify.defaults,options);				
			
			// IF ALREADY ENHANCED, EXIT
			if ( $(this).data('height_matchified') )
			{
				return;
			}	
			
			// IF NO SLAVE ELEMENT WAS SPECIFIED, EXIT
			if ( !opts.slave_prop )
			{
				return;
			}
			
			// IF SLAVE ELEMENT DOES NOT EXIST, EXIT			
			if ( $(opts.slave_prop).length < 1 )
			{
				return;
			}		
			
			// GET MASTER HEIGHT
			opts.master_height = $(this).height();
			
			// SET SLAVE HEIGHT
			opts.slave_vert_padding_top = $(opts.slave_prop).css('paddingTop').replace('px','');
			opts.slave_vert_padding_btm = $(opts.slave_prop).css('paddingBottom').replace('px','');
			opts.slave_vert_padding = parseInt( opts.slave_vert_padding_top, 10 ) + parseInt( opts.slave_vert_padding_btm, 10 );	
			opts.slave_prop_height = ( opts.master_height - opts.slave_vert_padding );								
			
			if ( $.browser.msie && $.browser.version < 7 ) // IE6
			{
				$(opts.slave_prop).height( opts.slave_prop_height );	
			}
			else
			{
				$(opts.slave_prop).css({ minHeight : ( opts.slave_prop_height + 'px' ) });
			}				
			
			// MARK AS DONE					
			$(this).data('height_matchified', true);			
		};
	})(jQuery);
	
/* 
	@ wt_fade_out_flash
	---------------------------------------------------------------
	Wellingtron
	Fade out the currently playing flash video if applicable
	
	Called by JavaScript to tell a Flash video slide to do the 
	following when a slide fade transition has started:
	- pause
	- reset player
	- show preroll image + large play button
	
	Usage: wt_fade_out_flash( flash_id );
	
	Ok in XP FF3.6.3, XP IE6
	_______________________________________________________________
*/

	function wt_fade_out_flash()
	{
		// if a video is playing
		if ( $('.wt').data('video_playing') )
		{
			// find the active flash object
			var wt_active_flash_video = $('.' + options.slide_class + ':visible .flash object');
			
			if ( $(wt_active_flash_video).length > 0 )
			{		
				// tell the Flash to run its internal fade function
				// longhand used as $('#' + flash_id).wt_fade_out_flash(); -- fails
				document.getElementById( $(wt_active_flash_video).attr('id') ).wt_fade_out_flash(); 
									
				// remove the classname that tells that the video is playing
				$('.wt').removeData('video_playing');
			}
		}
	}				

/* 
	@ tron_text_to_anchor
	---------------------------------------------------------------
	Reformat text as an anchor:
	- lowercase
	- spaces -> dashes ( reqd for .camelize() )
	- strip everything except numbers, letters, and hyphens (Regex: http://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/Q_24457865.html)
	- camelcase	
	_______________________________________________________________
*/		
	
	function tron_text_to_anchor( str )
	{					
		var anchorStr = '';
		
		if ( str )
		{
			// var str2 = $.string( str.toLowerCase() ).strip().gsub( ' ', '-').gsub( '&', '-and-').gsub( '&amp;', '-and-').camelize().str; // add dashes for camelize, camelize
			var str2 = $.string( str.toLowerCase() ).strip().gsub( ' ', '').gsub( '&', 'and').gsub( '&amp;', 'and').str; // camelize removed
			anchorStr = str2.replace(/[^a-zA-Z0-9\-]+/g,''); // regex to keep only allowed chars												
		}
		else
		{
			//console.log( str );						
		}
		
		return anchorStr;	
	}		
	
	$(window).bind('load', function() 
	{			
		$('body').addClass('windowloaded');
		//util_log('windowloaded');
	});	

		/* 
	@@ jquery.string.1.0-min.js
	---------------------------------------------------------------
	Used by jquery.tron2.js
	_______________________________________________________________
*/	

/**
 * jquery.string - Prototype string functions for jQuery
 * (c) 2008 David E. Still (http://stilldesigning.com)
 * Original Prototype extensions (c) 2005-2008 Sam Stephenson (http://prototypejs.org)
 */
 
jQuery.__stringPrototype={JSONFilter:/^\/\*-secure-([\s\S]*)\*\/\s*$/,ScriptFragment:"<script[^>]*>([\\S\\s]*?)<\/script>",specialChar:{"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r","\\":"\\\\"},blank:function(A){return/^\s*$/.test(this.s(A)||" ")},camelize:function(C){var A=this.s(C).split("-"),B;C=[A[0]];for(B=1;B<A.length;B++){C.push(A[B].charAt(0).toUpperCase()+A[B].substring(1))}C=C.join("");return this.r(arguments,0,C)},capitalize:function(A){A=this.s(A);A=A.charAt(0).toUpperCase()+A.substring(1).toLowerCase();return this.r(arguments,0,A)},dasherize:function(A){A=this.s(A).split("_").join("-");return this.r(arguments,0,A)},empty:function(A){return this.s(A)===""},endsWith:function(B,A){A=this.s(A);var C=A.length-B.length;return C>=0&&A.lastIndexOf(B)===C},escapeHTML:function(A){A=this.s(A).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");return this.r(arguments,0,A)},evalJSON:function(sanitize,s){s=this.s(s);var json=this.unfilterJSON(false,s);try{if(!sanitize||this.isJSON(json)){return eval("("+json+")")}}catch(e){}throw new SyntaxError("Badly formed JSON string: "+s)},evalScripts:function(s){var scriptTags=this.extractScripts(this.s(s)),results=[];if(scriptTags.length>0){for(var i=0;i<scriptTags.length;i++){results.push(eval(scriptTags[i]))}}return results},extractScripts:function(C){var E=new RegExp(this.ScriptFragment,"img"),D=new RegExp(this.ScriptFragment,"im"),A=this.s(C).match(E)||[],F=[];if(A.length>0){for(var B=0;B<A.length;B++){F.push(A[B].match(D)[1]||"")}}return F},gsub:function(C,B,A){A=this.s(A);if(jQuery.isFunction(B)){A=this.sub(C,B,-1,A)}else{A=A.split(C).join(B)}return this.r(arguments,2,A)},include:function(B,A){return this.s(A).indexOf(B)>-1},inspect:function(B,C){C=this.s(C);var A;try{A=this.sub(/[\x00-\x1f\\]/,function(E){var F=jQuery.__stringPrototype.specialChar[E[0]];return F?F:"\\u00"+E[0].charCodeAt().toPaddedString(2,16)},-1,C)}catch(D){A=C}C=(B)?'"'+A.replace(/"/g,'\\"')+'"':"'"+A.replace(/'/g,"\\'")+"'";return this.r(arguments,1,C)},interpolate:function(F,E,C){C=this.s(C);if(!E){E=/(\#\{\s*(\w+)\s*\})/}var A=new RegExp(E.source,"g");var D=C.match(A),B;for(B=0;B<D.length;B++){C=C.replace(D[B],F[D[B].match(E)[2]])}return this.r(arguments,2,C)},isJSON:function(A){A=this.s(A);if(this.blank(A)){return false}A=A.replace(/\\./g,"@").replace(/"[^"\\\n\r]*"/g,"");return(/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(A)},scan:function(C,B,A){A=this.s(A);this.sub(C,B,-1,A);return this.r(arguments,2,A)},startsWith:function(B,A){return this.s(A).indexOf(B)===0},strip:function(A){A=jQuery.trim(this.s(A));return this.r(arguments,0,A)},stripScripts:function(A){A=this.s(A).replace(new RegExp(this.ScriptFragment,"img"),"");return this.r(arguments,0,A)},stripTags:function(A){A=this.s(A).replace(/<\/?[^>]+>/gi,"");return this.r(arguments,0,A)},sub:function(H,D,E,C){C=this.s(C);if(H.source&&!H.global){var A=(H.ignoreCase)?"ig":"g";A+=(H.multiline)?"m":"";H=new RegExp(H.source,A)}var G=C.split(H),F=C.match(H);if(jQuery.browser.msie){if(C.indexOf(F[0])==0){G.unshift("")}if(C.lastIndexOf(F[F.length-1])==C.length-F[F.length-1].length){G.push("")}}E=(E<0)?(G.length-1):E||1;C=G[0];for(var B=1;B<G.length;B++){if(B<=E){if(jQuery.isFunction(D)){C+=D(F[B-1]||F)+G[B]}else{C+=D+G[B]}}else{C+=(F[B-1]||F)+G[B]}}return this.r(arguments,3,C)},succ:function(A){A=this.s(A);A=A.slice(0,A.length-1)+String.fromCharCode(A.charCodeAt(A.length-1)+1);return this.r(arguments,0,A)},times:function(D,C){C=this.s(C);var A="";for(var B=0;B<D;B++){A+=C}return this.r(arguments,1,A)},toJSON:function(A){return this.r(arguments,0,this.inspect(true,this.s(A)))},toQueryParams:function(F,C){C=this.s(C);var E=C.substring(C.indexOf("?")+1).split("#")[0].split(F||"&"),H={},B,A,D,G;for(B=0;B<E.length;B++){G=E[B].split("=");A=decodeURIComponent(G[0]);D=(G[1])?decodeURIComponent(G[1]):undefined;if(H[A]){if(typeof H[A]=="string"){H[A]=[H[A]]}H[A].push(D)}else{H[A]=D}}return H},truncate:function(C,A,B){B=this.s(B);C=C||30;A=(!A)?"...":A;B=(B.length>C)?B.slice(0,C-A.length)+A:String(B);return this.r(arguments,2,B)},underscore:function(A){A=this.sub(/[A-Z]/,function(B){return"_"+B.toLowerCase()},-1,this.s(A));if(A.charAt(0)=="_"){A=A.substring(1)}return this.r(arguments,0,A)},unescapeHTML:function(A){A=this.stripTags(this.s(A)).replace(/&amp;/g,"&").replace(/&lt;/g,"<").replace(/&gt;/g,">");return this.r(arguments,0,A)},unfilterJSON:function(C,B){B=this.s(B);C=C||this.JSONFilter;var A=B.match(C);B=(A!==null)?A[1]:B;return this.r(arguments,1,jQuery.trim(B))},r:function(A,B,C){if(A.length>B||this.str===undefined){return C}else{this.str=""+C;return this}},s:function(A){if(A===""||A){return A}if(this.str===""||this.str){return this.str}return this}};jQuery.__stringPrototype.parseQuery=jQuery.__stringPrototype.toQueryParams;jQuery.string=function(A){if(A===String.prototype){jQuery.extend(String.prototype,jQuery.__stringPrototype)}else{return jQuery.extend({str:A},jQuery.__stringPrototype)}}
/* 
	@@ jquery.timers.js
	---------------------------------------------------------------
	Used by jquery.tron2.js
	_______________________________________________________________
*/				

/**
 * jQuery.timers - Timer abstractions for jQuery
 * Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com)
 * Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).
 * Date: 2009/10/16
 *
 * @author Blair Mitchelmore
 * @version 1.2
 *
 **/

jQuery.fn.extend({
	everyTime: function(interval, label, fn, times) {
		return this.each(function() {
			jQuery.timer.add(this, interval, label, fn, times);
		});
	},
	oneTime: function(interval, label, fn) {
		return this.each(function() {
			jQuery.timer.add(this, interval, label, fn, 1);
		});
	},
	stopTime: function(label, fn) {
		return this.each(function() {
			jQuery.timer.remove(this, label, fn);
		});
	}
});

jQuery.extend({
	timer: {
		global: [],
		guid: 1,
		dataKey: "jQuery.timer",
		regex: /^([0-9]+(?:\.[0-9]*)?)\s*(.*s)?$/,
		powers: {
			// Yeah this is major overkill...
			'ms': 1,
			'cs': 10,
			'ds': 100,
			's': 1000,
			'das': 10000,
			'hs': 100000,
			'ks': 1000000
		},
		timeParse: function(value) {
			if (value == undefined || value == null)
				return null;
			var result = this.regex.exec(jQuery.trim(value.toString()));
			if (result[2]) {
				var num = parseFloat(result[1]);
				var mult = this.powers[result[2]] || 1;
				return num * mult;
			} else {
				return value;
			}
		},
		add: function(element, interval, label, fn, times) {
			var counter = 0;
			
			if (jQuery.isFunction(label)) {
				if (!times) 
					times = fn;
				fn = label;
				label = interval;
			}
			
			interval = jQuery.timer.timeParse(interval);

			if (typeof interval != 'number' || isNaN(interval) || interval < 0)
				return;

			if (typeof times != 'number' || isNaN(times) || times < 0) 
				times = 0;
			
			times = times || 0;
			
			var timers = jQuery.data(element, this.dataKey) || jQuery.data(element, this.dataKey, {});
			
			if (!timers[label])
				timers[label] = {};
			
			fn.timerID = fn.timerID || this.guid++;
			
			var handler = function() {
				if ((++counter > times && times !== 0) || fn.call(element, counter) === false)
					jQuery.timer.remove(element, label, fn);
			};
			
			handler.timerID = fn.timerID;
			
			if (!timers[label][fn.timerID])
				timers[label][fn.timerID] = window.setInterval(handler,interval);
			
			this.global.push( element );
			
		},
		remove: function(element, label, fn) {
			var timers = jQuery.data(element, this.dataKey), ret;
			
			if ( timers ) {
				
				if (!label) {
					for ( label in timers )
						this.remove(element, label, fn);
				} else if ( timers[label] ) {
					if ( fn ) {
						if ( fn.timerID ) {
							window.clearInterval(timers[label][fn.timerID]);
							delete timers[label][fn.timerID];
						}
					} else {
						for ( var fn in timers[label] ) {
							window.clearInterval(timers[label][fn]);
							delete timers[label][fn];
						}
					}
					
					for ( ret in timers[label] ) break;
					if ( !ret ) {
						ret = null;
						delete timers[label];
					}
				}
				
				for ( ret in timers ) break;
				if ( !ret ) 
					jQuery.removeData(element, this.dataKey);
			}
		}
	}
});

jQuery(window).bind("unload", function() {
	jQuery.each(jQuery.timer.global, function(index, item) {
		jQuery.timer.remove(item);
	});
});	
/* 
	@@ jquery.tron_content_hero.js
	---------------------------------------------------------------
	Used by jquery.tron2.js
	_______________________________________________________________
*/	

/*!
	@ .tron_content_hero()
	---------------------------------------------------------------
	Sub-content HTML builder
	
	Create the HTML to populate a tron slide and append it to the target element
	Author: Dan Smith
	Last updated: 04.11.2010
	
	Usage:	
	$(slide).tron_content_hero(item);		
	_______________________________________________________________
*/	

	(function($) 
	{		
		// Shell for plugin code
		// vars and functions are local within here, which prevents clashes with variables outside of this function
		
		$.fn.tron_content_hero = function(options) 
		{						

			// PLUGIN DEFAULTS
			$.fn.tron_content_hero.defaults = {
				json_item:				false,		/* Object | an item from the in-page JSON */				
				slide_number:			0,	/* Number | number of this slide */
				hero_heading_level: 3,
				hero_image_as_background: false
			};									
			
			options = $.extend($.fn.tron_content_hero.defaults,options);	
			
			// PLUGIN CODE
			return this.each( function() 
			{						
				// passed to function
				options.json =											options.json_item;	
				
				// test
				// console.log('jquery.tron_content_hero.js - ', 'title passed in = ', options.json.title);				
				
				// json in page: text	
				options.title =											options.json.title;
				options.description =								options.json.description;
				
				// json in page: image					
				options.image =											options.json.image;
				options.imagetitle =								options.json.imagetitle;
				options.imagealt =									options.json.imagealt;
				options.image_path_prefix =					options.json.image_path_prefix;				
				options.image_as_background =				options.hero_image_as_background;		
				options.image_as_background_html =	( options.image_as_background ? ( ' style="background-image:url(' + options.image_path_prefix + options.image + '); background-repeat: no-repeat;"' ) : '' );
				
				// json in page: dates					
				options.date_start =								options.json.date_start;
				options.date_end =									options.json.date_end;
				
				// json in page: media				
				options.media_type =								( options.json.media_type || '' );
				options.media_player =							options.json.media_player;					
				options.media_player_html =					( options.media_player ? ( ' media_player="' + options.media_player + '"' ) : '' );
				
				// json in page: links
				options.url =												options.json.link;
				options.url_new_window =						options.json.url_new_window;		
				options.url_new_window_html =				( options.url_new_window ? ( ' target="_blank" title="' + options.title + ' (opens in a new window). "' ) : '' );
				options.url_html_start =						( options.url ? ( '<a href="' + options.url + '"' + options.url_new_window_html + '>' ) : '' );
				options.url_html_end =							( options.url ? ( '</a>' ) : '' );						
				options.more_text =									options.json.more_text;
				options.more_text_inside_description =		options.json.more_text_inside_description;
				
				// variables used within this function				
				options.html_date_range =						'';					
				options.html_start_liner_inner = 		'<div class="inner-liner">'; // jt
				options.html_end_liner_inner = 			'</div>';	// jt
				options.html_start_flash =						'';
				options.html_end_flash =							'';	
				
				// skin-specific options	
				options.skin =											options.json.skin;	
				
				// for building the html string
				options.html =											'';																		

				
				// skin-based options that could go into the JSON if that's easier to manage
				switch (options.skin)
				{
					case 'jt' :
							options.more_text = 'Learn more';
						break;
				}								
				
				// end options

				// preload the image
				if ( options.image_path_prefix && options.image )
				{
					$('<img/>').attr({ src : ( options.image_path_prefix + options.image ) });		
				}						
				
				// build Flash HTML snippet
				if ( options.media_type == 'flash_video' )
				{
					options.html_start_flash = '<div class="flash"><div id="tron-flash-' + options.slide_number + '" class="flash-data" flash_preroll="' + options.image + '" media_src="' + options.media_src + '"' + options.media_player_html + '>';
					options.html_end_flash = '</div></div>';									
				}								
				
				// build date range HTML snippet
				if ( options.date_start && options.date_end )
				{
					options.date_text = '1';
					
					options.date_text = util_strDateRange({ 
						date1in: options.date_start, 
						date2in: options.date_end, 
						outputDayIfSingle: false, 
						outputDayIfRange: false 
					});		
					
					options.html_date_range = '<br /><span class="text-date">' + options.date_text + '</span>';
				}										
				
				// build hero HTML snippet
				options.html +=	'<div class="section hero"' + options.image_as_background_html + '>';				
								
				//options.html +=			'<div class="featured-item">';	
				options.html +=				options.html_start_flash;					
				
				if ( options.image && !options.image_as_background )
				{
					options.html +=			options.url_html_start;		
					options.html +=				'<img src="' + options.image_path_prefix + options.image + '" alt="' + options.imagealt + '" title="' + options.imagetitle + '" />';									
					options.html +=			options.url_html_end;						
				}							

				options.html +=				options.html_end_flash;							

				options.html +=			'<div class="header">';
				options.html +=				'<h' + options.hero_heading_level + ' class="text-title">';
				options.html +=				!options.more_text ? options.url_html_start : ''; // if there is a 'Read more' link, then don't link the heading as well
				options.html +=				options.title;
				options.html +=				!options.more_text ? options.url_html_end : ''; // if there is a 'Read more' link, then don't link the heading as well		
				options.html +=				'</h' + options.hero_heading_level + '>';				
				options.html +=			'</div>';


				
				// if there is a 'Read more' link, then don't link the heading as well
				if ( options.more_text )
				{
					if ( options.more_text_inside_description )
					{					
						options.html += '<p class="intro">';							
						options.html += 	options.description;
						options.html +=		'<span class="more"><a href="' + options.url + '" title="' + options.more_text + ' about ' + options.title + '. ">' + options.more_text + '</a></span>';	
						options.html += '</p>';
					}
					else
					{
						options.html +=	'<p class="intro">' + options.description + '</p>';							
						options.html +=	'<div class="footer">';
						options.html +=		'<p class="more"><span><a href="' + options.url + '" title="' + options.more_text + ' about ' + options.title + '. ">' + options.more_text + '</a></span></p>';
						options.html +=	'</div>';													
					}
				}		
				else
				{
					options.html +=	'<p class="intro">' + options.description + '</p>';							
				}
					
				options.html +=		'</div>';

				$(this).append( $(options.html) );
				
				// TODO: attach behaviours such as rolllovers
								
			});
		};
	})(jQuery);				
/* 
	@@ jquery.tron_nav.js
	---------------------------------------------------------------
	Used by jquery.tron2.js
	_______________________________________________________________
*/	

/* 
	@ tron_nav
	---------------------------------------------------------------
	Build the nav HTML
	
	'nav' var holds all item data
	'nav' holds other nav options
	
	Nav populated thus:
	
	nav.push({ 
		title: slide.title,
		id: slide.id,
		tooltip: slide.tooltip	
	});				
	
	all trons should have one 'nav'
	
	Notes:
	events-landing.html currently has 'Featured Events' at the top
	but there's no guarantee this will stay here,
	and it wouldn't make sense for any of the other labels
	to be the heading for the nav items
	so it would be better to remove the H3 from the markup
	or add a hidden H3
	_______________________________________________________________
*/	
	
	(function($) 
	{		
		// Shell for plugin code
		// vars and functions are local within here, which prevents clashes with variables outside of this function
		
		$.fn.tron_nav = function(options) 
		{									
			// PLUGIN DEFAULTS
			$.fn.tron_nav.defaults = {
				first_class: 'first',
				auto_advance_interval: 0,
				hide_auto_advance_controls: false,
				nav_items_to_generate: false,
				fade_duration: 0,
				tron_debug: false,
				allow_ie7_fades: false
			};									
			
			options = $.extend($.fn.tron_nav.defaults,options);	
			
			// PLUGIN CODE
			return this.each( function() 
			{					
					options.nav = $(this).find('.nav:first');					
					options.count = 0;	
					options.html = '';

					// ADD HTML ==============================================|
		
					options.html += '<ul>';				
					
					// GENERATE THE AUTO ADVANCE CONTROLS
					if ( options.auto_advance_interval > 0 )
					{						
						// DETERMINE WHETHER THE CONTROLS ARE VISIBLE OR NOT
						if ( options.hide_auto_advance_controls )
						{
							options.html += '<li style="display:none;">';
						}
						else
						{
							options.html += '<li>';	
						}						
						
						// note that the bulky span classes are legacy / already used by the CSS, and button elements would usually be used here		
						options.html +=		'<a href="#play" class="control-play-parent"><span class="control control-play">Play</span></a>';
						options.html +=		'<a href="#pause" class="control-pause-parent"><span class="control control-pause">Pause</span></a>';				
						options.html +=	'</li>';					
					}				
					
					// GENERATE THE SLIDE NAV ITEMS					
					$.each( options.nav_items_to_generate, function(i, item)
					{
						options.count++;
						
						if ( ( options.count == 1 ) && ( options.first_class !== '' ) )
						{								
							options.first_class_html = ( ' ' + options.first_class );								
						}
						else
						{													
							options.first_class_html = ''; // reset after 'first' match
						}
						
						// note 'events' phrase is specific to this tron
						options.html +=	'<li class="nav-item' + options.first_class_html + '" id="for-' + item.id + '">';
						options.html +=		'<a class="inactive" href="#' + item.id + '" title="' + item.tooltip + '"><span>' + item.title + '</span></a>';
						options.html +=		'<strong class="active"><span>' + item.title + '</span></strong>';
						options.html +=		'<span class="bg">&nbsp;</span>'; // REM3154	
						options.html +=	'</li>';
					});
					
					options.html += '</ul>';

					// INJECT THE HTML
					if ( $(options.nav).find('ul').length > 0 )
					{
						$(options.nav).addClass('nav-enhanced');
						$(options.nav).find('ul').replaceWith( options.html );						
					}
					else // wt
					{
						$(options.nav).append(options.html).addClass('nav-enhanced');				
					}		
					
					// ADD LISTENERS ==============================================|
					
					// ADD THE AUTO ADVANCE NAV LISTENERS AND HIDE THE PAUSED STATE
					if ( options.auto_advance_interval > 0 )
					{
						// PLAY BUTTON
						$(options.nav).find('.control-play-parent').click( function(e) 
						{			
							if ( options.debug )
							{
								$('#tron_console .text').html('play clicked');
							}
						
							var next;
														 
							// if the user clicked the button, auto advance straight away
							if (e.originalEvent)
							{ 
								// locate and click the next nav item in the sequence							
								next = $(options.nav).find('li.active:first').data('next');
								$(next).trigger('click');															
							}
															 
							// either way, start the timed auto advance
							$(this).everyTime(options.auto_advance_interval, 'auto_advance', 
								function() 
								{
									next = $(options.nav).find('li.active:first').data('next');
									$(next).trigger('click');
								}
							);

							// toggle the visible button state
							$(options.nav).find('.control-pause-parent:first').show();
							$(this).hide();	
							
							// prevent jump to anchor
							e.preventDefault();									
						})
						.hide(); // button hidden during page load

						// PAUSE BUTTON
						$(this).find('.control-pause-parent').click( function(e) 
						{			
							if ( options.debug )
							{
								$('#tron_console .text').html('pause clicked');
							}						
											
							// toggle the visible button state, stop the auto advance
							$(options.nav).find('.control-play-parent:first').show().stopTime('auto_advance');							
							$(this).hide();	
							
							// prevent jump to anchor
							e.preventDefault();									
						})
						.hide(); // button hidden during page load, shown via window.onload triggered click on play button
					}					
					
					// ADD THE SLIDE NAV LISTENERS AND SOME DATA TO AVOID DOM LOOKUPS						
					options.active = $(options.nav).find('strong.active');
					options.inactive = $(options.nav).find('a.inactive');	
					options.inactive_len = options.inactive.length;
					options.tron = $(this);
					
					$.each( $(options.inactive),
						function(i, item)
						{
							var j = i+1;
							var next_nav_item = 0;
							
							if ( j < options.inactive_len )
							{
								next_nav_item = j-1;
							}
							
							$(item).parents('.nav-item:first')
							.data( 'next', $(item).parents('.nav-item:first').siblings('.nav-item').eq(next_nav_item).find('a:first') );
							
							$(item)
							.data( 'href', ( '#' + $(item).attr('href').split('#')[1] ) )	/* save a DOM lookup later, note: hash removed for IE (to strip 'http://...html'), then added again */	
							.data( 'parent_nav_item', $(item).parents('.nav-item:first') ) /* save a DOM lookup later */
							.bind( 'mouseenter mouseleave focus blur', function() 
							{ 
								$(this).data('parent_nav_item').toggleClass('over'); 
							})									
							.click( function(e) 
							{ 
								// inactive = A, active = STRONG	
																	
								// if the user clicked the button, and the tron has loaded and autostarted, stop the auto advance if active
								if (e.originalEvent)
								{
									if ( options.auto_advance_controls && $('body').hasClass('windowloaded') )
									{
										// SELECTING A TAB PUTS THE TRON INTO PAUSE MODE
										// DON'T PUT THE TRON INTO PAUSE MODE IF THE (UN)PAUSE CONTROLS AREN'T VISIBLE
										if ( ! options.hide_auto_advance_controls )
										{
											$(options.play_control).show().stopTime('auto_advance').end();
											$(options.pause_control).hide();										
										}
									}		
								}
							
								// vars
								var old_active_nav_el;			
								var old_active_slide;								
	
								var new_active_nav_el = $(this);
								
								var new_active_slide = $(new_active_nav_el).data('href'); // the id of the newly active slide	
									
								/* if a slide is already active, we'll transition to the next slide */
								if ( $(options.tron).data('active_slide') )
								{										
									// the previously active slide				
									old_active_slide = $(options.tron).data('active_slide');								
									
									// hide the previously active slide and show the new one, using a fade transition
									if ( options.fade_duration > 0 )
									{
										// fade transitions are disabled in IE7
										if ( ( jQuery.browser.msie && parseInt(jQuery.browser.version, 10) == 7 ) && !options.allow_ie7_fades )
										{								
											// visibility:hidden is reqd to force display update in IE7 (http://www.positioniseverything.net/explorer/ienondisappearcontentbugPIE/index.htm)
											wt_fade_out_flash(); // stop out any active flash video	
											$(old_active_slide).css({ visibility : 'hidden' }).hide();	
											$(new_active_slide).css({ visibility : 'visible' }).show();								
										}
										// else ok to do fade transition
										else
										{							
											wt_fade_out_flash(); // stop out any active flash video	
											$(old_active_slide).fadeOut( options.fade_duration );		
											$(new_active_slide).fadeIn( options.fade_duration );									
										}
									}
									// hide the previously active slide and show the new one without using a fade transition
									else
									{
										wt_fade_out_flash(); // stop out any active flash video																					
										$(old_active_slide).hide();			
										$(new_active_slide).show();							
									}
									
									// the previously active nav item																				
									old_active_nav_el = $( '#for-' + old_active_slide.replace('#','') ); // could use attr matching but i think an id will be faster
									
									// toggle the previously active nav item if there was one							
									$(old_active_nav_el).toggleClass('active');										
								}
								// else if a slide is not already active, just show the new one
								else
								{
									$(new_active_slide).show();	
								}
				
								// update the focus if a user clicked the link (rather than the click being triggered)
								if (e.originalEvent)
								{ 
									$(new_active_slide).focus();
								}
								
								// close any open popouts
								if ( typeof( ec_launcher_generate ) !== 'undefined' )
								{					
									ec_toggle(e);
								}																						
								
								// store a reference to the newly active slide
								$(options.tron).data('active_slide', new_active_slide);	
								
								// remove any existing .current-slide classes
								// TODO: regex may be faster...
								for (var z=0; z<options.inactive_len; z++)
								{						
									var y = z+1;
									$(options.tron).removeClass( 'tron-slide-current-' + y );
								}							
								
								// add a CSS class to the tron so we can position slide content dependent on which slide is active
								$(options.tron).addClass( 'tron-slide-current-' + $(new_active_slide).data('slidenum') ); // eg .tron-slide-current-1
		
								// toggle the newly active nav item		
								$(this).data('parent_nav_item').toggleClass('active');
							
								// prevent jump to anchor
								e.preventDefault();				
							}); // end click					
						}
					); // end each
					

			});
		};
	})(jQuery);							/* 
	@@ jquery.tron_skiplinks.js
	---------------------------------------------------------------
	Used by jquery.tron2.js
	_______________________________________________________________
*/

/* 
	@ tron_skiplinks
	---------------------------------------------------------------
	Build the skiplink/backlink HTML
				
	Basic styles are set at the top of this file.
	
	Add skiplink/backlink listeners
	_______________________________________________________________
*/	
	
	(function($) 
	{		
		// Shell for plugin code
		// vars and functions are local within here, which prevents clashes with variables outside of this function
		
		$.fn.tron_skiplinks = function(options) 
		{									
			// PLUGIN DEFAULTS
			$.fn.tron_skiplinks.defaults = {
				slide_heading_level: false
			};									
			
			options = $.extend($.fn.tron_skiplinks.defaults,options);	
			
			// PLUGIN CODE
			return this.each(
				function() 
				{	
					// ADD HTML
				
					options.skip_id = tron_unique_prefix( this ) + 'start'; // tron_unique_prefix in jquery.tron2.js
					options.back_id = tron_unique_prefix( this ) + 'end';									
					
					// GET THE TRON TITLE					
					if ( options.slide_heading_level )
					{
						options.tron_title = $(this).find('.tron-heading:first').text();			
					}
					else
					{
						options.tron_title = 'feature';
					}
										
					// SKIPLINK					
					options.html = '';
					options.html +=	'<div class="clear"></div>';					
					options.html +=	'<p class="tron-skiplink tron-skiplink-wrapper" id="' + options.skip_id + '" tabindex="-1">';
					options.html +=		'<a href="#' + options.back_id + '" class="skiplink">Skip ' + options.tron_title + '</a>';
					options.html +=		'<span class="clear"></span>';
					options.html +=	'</p>';
					
					$(this).before( $(options.html) );

					// BACKLINK
					options.html = '';						
					options.html +=	'<p class="tron-skiplink tron-backlink-wrapper" id="' + options.back_id + '" tabindex="-1">';
					options.html +=		'<a href="#' + options.skip_id + '" class="backlink">Back to ' + options.tron_title + '</a>';
					options.html +=		'<span class="clear"></span>';
					options.html +=	'</p>';	
					//options.html +=	'<div class="clear"></div>';		
					
					$(this).after( options.html );	
					
					// ADD LISTENERS
					options.skip_el = ('#' + options.skip_id);
					options.back_el = ('#' + options.back_id);						
					
					$.each( $( options.skip_el + ', ' + options.back_el ), function(i, item)
					{
						var skiplink = $(item).find('a:first');						
						
						// temporarily display the skiplink so that we can get the real width, not the 1x1 'hidden' width
						$(skiplink)
						.data( 'href', $(skiplink).attr('href') ) /* save a DOM lookup later */	
						.addClass('focus');
						
						// set paragraph width to floated link width to limit the width of the focus outline
						$(item).css({ width: ( $(skiplink).outerWidth() + 'px' ) }); // outerWidth includes padding/border (jQuery 1.2.6)
												
						// fix for IE6 which does not support :focus
						if ( jQuery.browser.msie && parseInt(jQuery.browser.version, 10) == 6 )
						{
							$(skiplink)
							.bind( 'mouseenter hover focus', function() 
							{ 
								$(this).addClass('focus');
							})
							.bind( 'mouseleave blur click', function() 
							{ 
								$(this).removeClass('focus');
							});
						}
						
						$(skiplink)		
						.removeClass('focus') /* hide */							
						.click( function(e) 
						{										
							$( $(this).data('href') ).focus(); // focus the target															
							e.preventDefault();	// prevent jump to anchor	
						});
					}); // end each
				}); // end each
		};
	})(jQuery);						
/* 
	@@ jquery.tron_slide_events.js
	---------------------------------------------------------------
	Used by jquery.tron2.js
	_______________________________________________________________
*/

/* 
	@ tron_slide_events
	---------------------------------------------------------------
	Add the slide listeners
	_______________________________________________________________
*/	
	
	(function($) 
	{		
		// Shell for plugin code
		// vars and functions are local within here, which prevents clashes with variables outside of this function
		
		$.fn.tron_slide_events = function(options) 
		{									
			// PLUGIN DEFAULTS
			$.fn.tron_slide_events.defaults = {
				hide_auto_advance_controls: false,
				hero_image_as_background: false,
				slide_class: ''
			};									
			
			options = $.extend($.fn.tron_slide_events.defaults,options);	
			
			// PLUGIN CODE
			return this.each(
				function() 
				{					
					options.nav = $(this).find('.nav:first');				
					
					// copy .section background to .slide
					if ( options.hero_image_as_background )
					{						
						$.each( $(this).find('.' + options.slide_class + ' .hero'),
							function(i, item)
							{											
								$(item).parents('.' + options.slide_class + ':first').css({ 'background-image' : $(item).css('background-image') });
							}
						);
					}
					
					// ADD HOVER LISTENERS TO PAUSE THE AUTO ADVANCE
					if ( options.hide_auto_advance_controls )
					{
						options.pause_control = $(options.nav).find('.control-pause-parent:first');
						options.play_control = $(options.nav).find('.control-play-parent:first');							
						
						// TODO: 'mouseleave' is currently being triggered when the nav is moused over. This is not ideal.
			
						$(this)
						.bind('mouseenter', 
							function()
							{
								$(options.pause_control).trigger('click');									
							}
						)
						.bind('mouseleave', 
							function()
							{
								$(options.play_control).trigger('click');		
							}
						);	
						
						// add support for linear tabbing
						
						$(this).find('a:first')
						.bind('focus', 
							function()
							{
								$(options.pause_control).trigger('click');	
							}
						);
						
						$(this).find('a:last')
						.bind('blur', 
							function()
							{
								$(options.play_control).trigger('click');		
							}
						);								
			
					}					
				
				}
			);
		};
	})(jQuery);							/* 
	@@ jquery.tron2.js
	---------------------------------------------------------------

	_______________________________________________________________
*/	

/* 
	@ tron_styles
	===============================================================
	Styles used by this plugin	
	Note: this function needs to sit outside of .tronify
	
	If the styles are being overridden, edit the specificity.
	_______________________________________________________________
*/				

	function tron_styles( specificity )
	{
		var opts = [];
		opts.specificity = ( specificity ? (specificity += ' ') : '' );
		
		opts.html = '';
		opts.html +=	'<style type="text/css" title="Styles for jquery.tronify.js">';
		opts.html +=		opts.specificity + '.tron .nav ul li strong.active { display: none; !important } ';					
		opts.html +=		opts.specificity + '.tron .nav ul li.active strong.active { display: block; !important } ';
		opts.html +=		opts.specificity + '.tron .nav ul li.active a.inactive { display: none; !important } ';	
		opts.html +=		opts.specificity + '.tron-skiplink a { position:absolute; left:-10000px; top:auto; width:1px; height:1px; overflow:hidden; } ';		
		opts.html +=		opts.specificity + '.tron-skiplink a:active { position:static; left:auto; top:auto; width:auto; height:auto; overflow:visible; } ';		
		opts.html +=		opts.specificity + '.tron-skiplink a:focus { position:static; left:auto; top:auto; width:auto; height:auto; overflow:visible; } ';		
		opts.html +=		opts.specificity + '.tron-skiplink a.focus { position:static; left:auto; top:auto; width:auto; height:auto; overflow:visible; } ';	
		opts.html +=		opts.specificity + '.tron-skiplink a { font-size:0.9em; text-transform:uppercase; } ';
		opts.html +=		opts.specificity + '.tron-skiplink-wrapper a { margin:0 0 0.5em 0; } ';				
		opts.html +=		opts.specificity + '.tron-backlink-wrapper a { margin:0.5em 0 0 0; } ';			
		opts.html +=	'</style>';					
		
		document.write( opts.html );
	}

/* 
	@ .tronify 
	===============================================================						
	Usage:
	$(el)
	.data('json', 
	{ 
		tron_json_here 
	})
	.tronify({		
		option: 'value'
	});			
	
	A BETTER WAY TO MANAGE TRONS =)
	- less DOM operations = faster show/hide
	- one-size-fits-all + options = less code
	- tron functions integrated = self contained
	- reusable plugin
	- JSON added to element as data in template
	- function called in template
	- JSON updated to be more consistent across trons
	
	STILL TODO:
	- remove any redundant css classes from html eg wt, jt, st, pt
	- update the Drupal templates to match my tron*.html demo files
	- add support for panels that don't use tron data
	- integrate tabbed events panel which has markup wrapped around
	  the day columns
	- test in more browsers (currently only XP FF3.6.7 and some IE6)
	- hook up the setup/callbacks, if reqd
	- add the dependencies to global.js
	- integrate homepage tabbed bookit, which has different markup (maybe could add the classes I require?)
	- add hover-to-pause if options.hide_auto_advance_controls == true
	- debug image.load (replacing window.load)
	- add fade without x-fade as as option
	- test test test
	- 'TODO'
	_______________________________________________________________
*/	

	// add styles after this script, in the page header
	tron_styles( '#page' );
	
	(function($) 
	{		
		// Shell for plugin code
		// vars and functions are local within here, which prevents clashes with variables outside of this function
		
		$.fn.tronify = function(options, callback) 
		{						
			if($.isFunction(options)) 
			{
				callback = options;
				options = null;
			}
			
			// PLUGIN DEFAULTS
			$.fn.tronify.defaults = {
				fade_duration: 0,											/* Number (ms) | 0 = no fade on transition */
				auto_advance_interval: 0,							/* Number (ms) | 0 = no auto advance */			
				hide_auto_advance_controls: false,		/* Boolean | if auto_advance_interval > 0, this hides the play/pause button and triggers these on slide focus/mouseover instead */								
				/* use_inner_liner: false,						Boolean | wraps .liner innerHTML with .inner-liner (as per WT) */			
				hero_heading_level: 5,								/* Number (1-6) | Default is 5 (for PWT) but should be one level higher than featured_heading_level */
				featured_heading_level: 5,						/* Number (1-6) | Default is 5, usual override would be 6 for tabbed events */
				slide_class: 'wrapper',								/* String */
				hero_more_text: '',										/* String | If populated, a 'more' link will be output at the foot of the hero slide */
				slide_heading_level: 4,								/* Number (1-6) | Default is 4 (for PWT). Set to false to suppress slide heading output. */
				hero_image_as_background: false,			/* Boolean | If true, the image is displayed in the background rather than inline */
				prop_offset: 0,												/* Number (px) | used to bump up the tron-liner height in tron_fix_slide_height() */
				allow_ie7_fades: false,								/* Boolean | if true, fades are enabled - note that fades can be buggy in ie7 (with flash?) so test prior to launch */
				debug: false,
				featured_image_pre_html: '',
				featured_image_post_html: '',
				featured_heading_level: 6
				//setup: null,												/* as per the demo code, not used yet */
				//complete: null											/* as per the demo code, placeholder for callback */
			};									
			
			options = $.extend($.fn.tronify.defaults,options);	
							
			
			// TODO, add more options, eg optons.tabs = $(this).find('.' + options.slide_class). this should mean i'm able to get rid of some of the opts.xxx duplicates for less codes
			
			// PLUGIN CODE
			return this.each(
				function() 
				{
					// CHECK IF ALREADY ENHANCED ==============================================|
					if ( $(this).data('tronified') )
					{
						return;
					}
										
					
					if ( options.debug )
					{
						$('body').append('<div id="tron_console"><h2>Console</h2><div class="text"></div></div>');
						
						if (window.console)
						{
							//console.log('Trons running in debug mode. ');				
						}						
					}										
					
					options.target = $(this);
					options.nav = [];	
					options.tabs;
					options.slides = [];						
					options.generate_slides = false; // a nav is always generated, if only to hide/show the existing HTML content		
					var tron = [];
					
					// CHECK FOR JSON ==============================================|
					
					// if there SHOULD be tron data but there isn't, the inline JS should look like this: $('#unique-id').data( 'tab_data', {} ).tronify();					
					// if there SHOULDN'T be tron data, the inline JS should look like this: $('#unique-id').tronify();							
					
					if ( $(this).data('tab_data') )
					{
						options.tabs = $(this).data('tab_data');
						
						// any tron should have at least ONE tab
						if ( options.tabs.tab1 )
						{						
							options.generate_slides = true;			
						}			
						else
						{
							return false; // exit the function as there's nothing more we can do without some JSON	
						}						
					} // end JSON check		
					else
					{
						options.tabs = $(this).find('.' + options.slide_class);	// TODO
					}
				
					// WE HAVE JSON - GENERATE THE TRON SLIDES ==============================================|
					
					if ( options.generate_slides )
					{										
						options.slides.count = -1;			
						options.slides.html_position = ( ( options.fade_duration > 0 ) ? ' style="position:absolute;"' : '' );								
						options.slides_container = $(this).find('.slides:first');
						
						// slide types
						// hero, featured, ad		
						
						// REMOVE THE DEFAULT SLIDE
						$(options.slides_container).empty();						
						
						// LOOP THROUGH THE TABBED SLIDE DATA THE JSON, APPENDING NEW SLIDES AS WE GO							
						$.each(options.tabs,
							function(i, item)
							{
								// global slide properties
								options.slides.count++;
								
								// properties for this slide
								options.slide = [];										
								
								// BUILD SLIDE WRAPPER
								options.slide.title = item.slide_title;
								options.slide.url = item.slide_link;																	
								options.slide.id = tron_text_to_anchor(options.slide.title);
								options.slide.class_generic = options.slide_class;
								options.slide.class_unique = ( options.slide_class + '-' + item.slide_class );
								options.slide.tooltip = 'Show ' + options.slide.title;						
								
								if ( !isNaN(options.slide.title) ) // if slide title is a number (WT)
								{
									options.slide.prefix = tron_unique_prefix( $(this) );
									options.slide.id = tron_text_to_anchor(options.slide.prefix + 'slide' + options.slide.title);	
									options.slide.tooltip = 'Show feature ' + options.slide.title;									
								}
			/* 
			
						move into content builder
			
								if (item.hero && !item.featured) // PT
								{
									options.slide.tooltip = 'Show ' + options.slide.title + ' feature';
								}			
			
								if (item.featured) // JT, TABBED EVENTS
								{
									options.slide.tooltip = 'Show ' + options.slide.title + ' events';
								}
			
								if (item.ad) // ST
								{
									options.slide.tooltip = 'Show ' + options.slide.title + ' advertisement';
								}	
					*/
			
								// ADD THIS SLIDE TO THE NAV DATA
								options.nav.push({ 
									title: options.slide.title,
									id: options.slide.id,
									tooltip: options.slide.tooltip									
								});		
								
								// BUILD SLIDE WRAPPER HTML ==============================================|
								
								options.slide.html = '';																
								options.slide.html +=	'<div class="' + options.slide.class_generic + ' ' + options.slide.class_unique + '" id="' + options.slide.id + '" tabindex="-1"' + options.slides.html_position + '>';		
								
								if ( options.slide_heading_level )
								{
									options.slide.html +=	'<h' + options.slide_heading_level + ' class="access">' + options.slide.title + '</h' + options.slide_heading_level + '>';		
								}										
										
								options.slide.html +=		'<div class="clear"></div>';						
								options.slide.html +=	'</div>';		
								
								// INJECT SLIDE WRAPPER HTML ==============================================|
								
								$(options.slides_container).append( options.slide.html );
								
								// new: add slide number to slide
								$('#' + options.slide.id).data('slidenum', (options.slides.count + 1) );
								
								// BUILD AND INJECT SLIDE CONTENT HTML ==============================================|
								
								options.slide.externals = true;		
						
								// HERO: tron_content_hero
								if ( item.tron_content_hero )
								{										
									// if builder function exists, run it								
									if ( typeof( $.fn.tron_content_hero ) !== 'undefined' ) /* note inclusion of 'fn.' */
									{
										$('#' + options.slide.id).tron_content_hero(
										{
											json_item: item.tron_content_hero,
											slide_number: options.slides.count,
											hero_heading_level: options.hero_heading_level,
											hero_image_as_background: options.hero_image_as_background												
										});
									}
								}
								
								// HERO: tron_content_hero_bg								
								if ( item.tron_content_hero_bg )
								{						
								

								
									// if builder function exists, run it								
									if ( typeof( $.fn.tron_content_hero_bg ) !== 'undefined' ) /* note inclusion of 'fn.' */
									{
										$('#' + options.slide.id).tron_content_hero_bg(
										{
											json_item: item.tron_content_hero_bg,
											hero_image_as_background: options.hero_image_as_background												
										});
									}
								}																								
								
								// FEATURED
								if ( item.tron_content_featured )
								{										
									// if builder function exists, run it								
									if ( typeof( $.fn.tron_content_featured ) !== 'undefined' ) /* note inclusion of 'fn.' */
									{
										$('#' + options.slide.id).tron_content_featured (
										{
											json_item: item.tron_content_featured,
											slide_number: options.slides.count,
											hero_heading_level: options.featured_heading_level,
											featured_image_wrap_html: options.featured_image_wrap_html									
										});
									}
								}								
								
								if ( !options.slide.externals )
								{
									//console.log( 'slide assets not loaded' );
								}
							} // end fn
						); // end each
	
					} // end if generate_slides					

					// REPLACE THE DEFAULT NAV WITH OUR NAV, THEN APPLY EVENT LISTENERS ==============================================|	
					
					$(this).tron_nav({
						first_class: 'first',
						auto_advance_interval: options.auto_advance_interval,
						hide_auto_advance_controls: options.hide_auto_advance_controls,
						nav_items_to_generate: options.nav,
						fade_duration: options.fade_duration,
						debug: options.debug,
						allow_ie7_fades: options.allow_ie7_fades
					});

					// INJECT SKIPLINKS ==============================================|	
					$(this).tron_skiplinks({
						slide_heading_level: '3'										 
					});
							
					// FIX HEIGHTS FOR ABS POS X-FADES ==============================================|	
					if ( options.fade_duration > 0 )
					{												
						tron_fix_slide_height({
							slides: $(this).find('.' + options.slide_class),
							outer_prop: $(this).find('.tron-liner'),
							inner_props: $(this).find('.section')
						});													
					}	
					
					// ADD HOVER LISTENERS TO OUR TRON ==============================================|	
					$(this).tron_slide_events({
						hide_auto_advance_controls: options.hide_auto_advance_controls,
						hero_image_as_background: options.hero_image_as_background,
						slide_class: options.slide_class
					});
					
					// HIDE ALL BUT THE FIRST SLIDE ==============================================|	
					$(this)
					.find('.' + options.slide_class).hide().end() /* hide all slides */
					.find('.nav-item a:first').trigger('click'); /* show the first slide */		
					
					// MARK AS DONE ==============================================|	
					$(this)
					.data('tronified', true)
					.addClass('tronified'); // for tron_unique_prefix;		
					
					var hidden_play_button = $(this).find('.control-play-parent:hidden');
									
					if ( $('body').hasClass('windowloaded') )
					{	
						//console.log('windowloaded');
						$(hidden_play_button).trigger('click')
					}
					else
					{
						$(window).bind('load', function() 
						{		
							//console.log('windowloaded NOW');
							$(hidden_play_button).trigger('click')								
						});	
					}							
				} // end fn
			); // end [process] each [item]		
				
			// FUNCTIONS USED/AVAILABLE WITHIN THIS PLUGIN			
			
			/* 
				@ tron_fix_slide_height
				---------------------------------------------------------------
				originally for wt
				- matched the height of each .liner (which wraps the title and the call to action link)
				- so that we can absolute position the wrappers on top of one another, so that the crossfade works correctly	
				
				Usage:
				tron_fix_slide_height({
					slides: $(this).find('.' + options.slide_class),
					outer_prop: $(this).find('.liner:first'),
					inner_props: $(this).find('.liner .liner')
				});					
				_______________________________________________________________
			*/				
			
				function tron_fix_slide_height( args )
				{		
					var defaults = {
						slides: false,
						outer_prop: false,
						inner_props: false
					};
					
					var opts = $.extend(defaults, args);					
		
					opts.prop_max_height = 0;							
					
					// get the max height
					$.each( $(opts.inner_props),
						function(i,item) 
						{			
							opts.prop_height = $(item).height(); // NB!: slides need to be visible for height to be calculated
							
							if ( opts.prop_height > opts.prop_max_height )
							{
								opts.prop_max_height = opts.prop_height;
							}														
						}							
					); // end each			
					
					// apply the max height to each element in the master_prop array
					$(opts.inner_props).height( opts.prop_max_height + 'px' );
			
					opts.slide_height = $(opts.slides).eq(0).height(); // in the case of the wt, at least, all slides will now be the same height as each slide is (fixed height img + liner height)
					
					// set the height of the parent, to allow for the absolutely positioned wt slides		
					if ( jQuery.browser.msie && parseInt(jQuery.browser.version, 10) == 6 )
					{
						$(opts.outer_prop).height( opts.slide_height + options.prop_offset + 'px' );	
					}
					else
					{
						$(opts.outer_prop).css({ 'min-height' : ( opts.slide_height + options.prop_offset + 'px' ) });
					}
				}																					
		
		};
	})(jQuery);
	
