var pageOptions = {};
var accordionOptions = {};
if (typeof window.HOST == 'undefined') { var HOST = window.location.hostname; }
if (typeof window.PATH == 'undefined') { var PATH = location.protocol + '//' + HOST + '/'; }
if (typeof window.CDN_PATH == 'undefined') { var CDN_PATH = location.protocol + '//cdn.boatus.com/'; }
if (typeof window.API_PATH == 'undefined') { var API_PATH = PATH + '/API/2.0/'; }
if (typeof window.PUBLIC_API_KEY == 'undefined') { var PUBLIC_API_KEY = 'ABCDEF12345'; }
if (typeof window.FB_APP_ID == 'undefined') { var FB_APP_ID = ''; }

// Create the Global BoatUS object.
var BoatUS = {
	version: '0.1',
	optsDefaults: {
		debug: true,
		ads: {
			disableAds: false,
			personalizeAds: true
		},
		Overlay: {
			fixedWidth: true,
			destroyOnUnload: true
		},
		social: false,
		socialOpts: {
			title: $('title:first').html() || "BoatUS",
			description: $("meta[name~='description']").attr("content") || "",
			url: window.location.href,
			FB: true,
			TW: true,
			DG: true,
			SU: true,
			EM: true
		},
		UI: {
			tabs: {
				save: true,					// Should the most recent tab be saved?
				selected: 1,				// 1-based index of the tab to select by default.
				onChange: null				// Callback function for the change event.
			},
			text: {
				startSize: 0,
				curSize: 0,
				defTarget: '#content',
				minSize: -2,
				maxSize: 5
			}
		}
	},
	Options: {},
	pageReady: false,
	Queue: {
		data: [],
		addToQueue: function(fn)
		{
			// Add the ability to queue up events before the page has loaded.
			if (typeof fn != "function") { return; }
			this.data.push(fn);
			BoatUS.log("Method called before page ready: ");
			BoatUS.log(fn);
		},
		fireQueue: function()
		{
			// Loop through all the events in the queue once an event has passed.
			for (var i = 0, l = this.data.length; i < l; i++)
			{
				this.data[i]();
			}
		}
	},
	Events: {},
	// Initialize everything.
	init: function(opts) {
		BoatUS.Options = $.extend(BoatUS.optsDefaults, opts);
		BoatUS.log(BoatUS.Options);
		if (typeof(JSON) != 'object') BoatUS.require_once('/assets/js/json.js');
		this.pageReady = true;
		this.Queue.fireQueue();
		this.adLoadTimeout = setTimeout('BoatUS.Ads.init()', 3000);
		if (BoatUS.Options.social === true) { this.Social.loadFBAPI(); }
		// Bootstrap the page.
		this.Member.init();
		this.Browser.init();
		$('iframe').each(function(i, e) {
			var testString = 'http://trk.roitrax.com/boatus/rts.html';
			if ($(this).attr('src').indexOf(testString) >= 0) $(this).hide();
		});
	},
	// Adds the ability to create a popup window.
	Popup: function(strURL, strName, objOpts) {
		objOpts = objOpts || {};
		strOpts = [];
		if (objOpts.status) { strOpts.push('status=1'); } else { strOpts.push('status=0'); }
		if (objOpts.toolbar) { strOpts.push('toolbar=1'); } else { strOpts.push('toolbar=0'); }
		if (objOpts.location) { strOpts.push('location=1'); } else { strOpts.push('location=0'); }
		if (objOpts.resizeable) { strOpts.push('resizeable=1'); } else { strOpts.push('resizeable=0'); }
		if (objOpts.scrollbars) { strOpts.push('scrollbars=1'); } else { strOpts.push('scrollbars=0'); }
		if (objOpts.height != '') { strOpts.push('height=' + parseInt(objOpts.height)); } else { strOpts.push('height=250'); }
		if (objOpts.width != '') { strOpts.push('width=' + parseInt(objOpts.width)); } else { strOpts.push('width=350'); }
		return window.open(strURL, strName, strOpts.join(','));
	},
	
	// Adds the ability to create dynamically loading overlays.
	Overlay: {
		curOverlay: null,
		overlays: {},
		overlayDimmerDivID: 'boatus_overlayDimmer',
		overlayDivID: 'boatus_overlay',
		curOverlayClickedId: '',
		// Add an overlay to the overlayregistery.
		registerOverlay: function(ovID, ovPath)
		{
			BoatUS.Overlay.overlays[ovID] = {
				id: ovID,
				src: ovPath
			};
		},
		positionOverlay: function() {
			if ($('#' + BoatUS.Overlay.overlayDivID).length > 0) {
				$('#' + BoatUS.Overlay.overlayDivID).center(window);
			}
		},
		createOverlay: function(div_id, objOpts)
		{
			var id = div_id,
			queue = [],
			storageLoaded = false,
			overlayLoadPath,
			t_mobj,
			overlayContentContainer = $('#boatus_overlay_container'),
			overlayDimmerDiv,
			overlayDiv;
			objOpts = $.extend({}, BoatUS.Options.Overlay, objOpts);
			
			if (BoatUS.Overlay.overlays[id] == null) {
				overlayLoadPath = PATH + 'assets/overlay/' + id + '.asp';
			} else {
				overlayLoadPath = BoatUS.Overlay.overlays[id].src;
			}
			// create the content holder if it doesn't already exist.
			if (overlayContentContainer.length < 1)
			{
				overlayContentContainer = $('<div />', { 'id': 'boatus_overlay_container', css: { 'display': 'none' }}).appendTo('body');
			}
			// create the blackout div if it doesn't exist already.
			if ($('#' + BoatUS.Overlay.overlayDimmerDivID).length < 1)
			{
				overlayDimmerDiv = $('<div />', { 'id': BoatUS.Overlay.overlayDimmerDivID, css: { 'background-color': '#000', 'position': 'fixed', 'z-index': 102003403, 'top': 0, 'left': 0, 'right': 0, 'bottom': 0, 'opacity': 0.5, 'display': 'none' }}).appendTo('body').click(function() { BoatUS.closeOverlay(); });
			}
			
			// Create the popup if it doesn't exist already.
			if ($('#' + BoatUS.Overlay.overlayDivID).length < 1)
			{
				overlayDiv = $('<div />', { 'id': BoatUS.Overlay.overlayDivID, css: { 'background-color': '#FFF', 'z-index': 102003408, 'display': 'none' }}).appendTo('body');
			} else { overlayDiv = $('#' + BoatUS.Overlay.overlayDivID); }
			
			if (objOpts.fixedWidth !== false) overlayDiv.css('width', '600px');
			
			var unloadCurrentOverlay = function()
			{
				// Detach the current overlay content div from the overlay div, and return it to the container for later use.
				if (BoatUS.Overlay.curOverlayClickedId != '')
				{
					if (BoatUS.Overlay.curOverlay.opts && BoatUS.Overlay.curOverlay.opts.destroyOnUnload === true) {
						$('#' + BoatUS.Overlay.overlayDivID).remove();
					} else {
						$('.overlay_bdy', '#' + BoatUS.Overlay.overlayDivID).children('div').detach().appendTo(overlayContentContainer);	
					}
					BoatUS.triggerEvent('Overlay.Close', { overlay: BoatUS.Overlay.curOverlayClickedId });
				}
			};
			
			var onHTMLLoaded = function(c, t, s, x, o)
			{
				if(x.status != 200)
				{
					c = $('<div style="top: 312px; left: 356px;" class="content_container" id="' + id + '"><div onclick="BoatUS.closeOverlay(\'' + id + '\');return false;" class="overlay_close" title="Click to Close"></div><div class="overlay_bdy"><h3>Error</h3></div><p>There was a problem loading the desired content. Please try again later.</p><div class="clear"></div></div>');
				}
				$('.overlay_bdy', '#' + BoatUS.Overlay.overlayDivID).empty().append(c.show());
				BoatUS.Overlay.positionOverlay();
				$('#' + BoatUS.Overlay.overlayDivID).show();
				BoatUS.triggerEvent('Overlay.Open', { overlay: BoatUS.Overlay.curOverlayClickedId, opts: o });
			};
			
			var loadHTML = function(m_opts)
			{
				$('#' + BoatUS.Overlay.overlayDimmerDivID).show();
				var o_html = '', contentDiv;
				BoatUS.Overlay.curOverlayClickedId = id;
				o_html += '<div style="top: 312px; left: 356px;" class="content_container" id="' + id + '"><div onclick="BoatUS.closeOverlay(\'' + id + '\');return false;" class="overlay_close" title="Click to Close"></div><div class="overlay_bdy"><h3>Loading...</h3></div><div class="clear"></div></div>';
				$('#' + BoatUS.Overlay.overlayDivID).html(o_html);
				BoatUS.Overlay.positionOverlay();
				$('#' + BoatUS.Overlay.overlayDivID).show();
				if ($('#boatus_overlayContent_' + id).length === 0)
				{
					contentDiv = $('<div />', { id: 'boatus_overlayContent_' + id}).appendTo(overlayContentContainer).hide();
					contentDiv.load(overlayLoadPath, m_opts.params, function(t, s, x) {
						// If the call failed, remove and destroy the new overlay content container so we can try again.
						if (x.status != 200)
						{
							contentDiv.detach();
						} else {
							// On the first open, fire the Load event.
							BoatUS.triggerEvent('Overlay.Load', { overlay: BoatUS.Overlay.curOverlayClickedId, opts: m_opts });
						}
						onHTMLLoaded(contentDiv, t, s, x, m_opts);
					});
				} else {
					contentDiv = $('#boatus_overlayContent_' + id);
					onHTMLLoaded(contentDiv, null, null, {status: 200});
					// On subsequent opens, fire the Open event.
					BoatUS.triggerEvent('Overlay.Open', { overlay: BoatUS.Overlay.curOverlayClickedId, opts: m_opts });
				}
			};
			
			return {
				load: function(m_opts)
				{
					if (BoatUS.Overlay.curOverlay) { unloadCurrentOverlay(); }
					$(window).resize(function() { BoatUS.Overlay.positionOverlay(); });
					$(window).scroll(function() { BoatUS.Overlay.positionOverlay(); });
					m_opts = m_opts || { destroyOnUnload: false };
					t_mobj = {};
					BoatUS.Overlay.curOverlay.opts = m_opts;
					loadHTML(m_opts);
				},
				close: function()
				{
					unloadCurrentOverlay();
					$('#' + BoatUS.Overlay.overlayDivID).hide().html('');
					$('#' + BoatUS.Overlay.overlayDimmerDivID).hide();
					BoatUS.Overlay.curOverlayClickedId = '';
				}
			};
		}
	},
	
	handleOverlay: function(strOVName, objOpts)
	{
		this.Overlay.curOverlay = new this.Overlay.createOverlay(strOVName, objOpts);
		this.Overlay.curOverlay.load(objOpts);
	},
	
	closeOverlay: function()
	{
		this.Overlay.curOverlay.close();
	},
	
	// The Member object allows us to store and access information pertaining to the member if they are logged in to my.boatus.com.
	Member: {
		loggedIn: false,
		info: {
			memberNumber: 0,
			lastVisit: new Date(),
			realName: {
				first: '',
				last: ''
			},
			emailAddress: '',
			zipCode: '',
			hasTowing: false,
			hasInsurance: false
		},
		optInAdPersonalization: false,	// Allows us to turn off personalized ads.
		init: function()
		{
			// Load up information about the current user from the API. Once that information is loaded, we can use that information on the page.
			// In production, this information would be obtained from the services API, and then returned as a JSON object.
			//this.onDataLoaded({ loggedIn: true, realName: { first: 'Andrew' }, boatType: 'power'})
		},
		getAdMember: function()
		{
			// Return an object containing certain data that we can use to personalize ads.
			if (! this.optInAdPersonalization) { return { memberNumber: 0, towing: false, insurance: false }; }
			return { memberNumber: this.info.memberNumber, towing: this.info.hasTowing, insurance: this.info.hasInsurance };
		},
		onDataLoaded: function(r)
		{
			// Data has returned from the API.
			clearTimeout(BoatUS.adLoadTimeout);
			BoatUS.Ads.init();
			for (var v in r) {
				if (typeof this.info[v] != 'function') { this.info[v] = r[v]; }	// Copy all of the response variables in, but don't overwrite functions.
			}
			// This code could turn the log in to my.boatus.com link into a goto boatus.com link if they are logged in.
			if (this.loggedIn) {
				$('.myBoatUSLogin').attr('onclick', '').attr('href', 'http://my.boatus.com/memberpage.asp').html('Go To my.BoatUS.com');
			}
			BoatUS.triggerEvent('Member.Load', { member: this.info.memberNumber });
		}
	},
	
	// The BoatUS Ads object allows us to embed advertising in the page in a non-blocking way.
	Ads :{
		adZones: [],
		initialized: false,
		strAdZoneSelector: 'busa',
		init: function()
		{
			if (this.initialized === true || BoatUS.Options.ads.disableAds === true) { return; }	// Make sure that we only initialize the advertising object once.
			this.initialized = true;
			$('.' + this.strAdZoneSelector).each(function(i){
				BoatUS.Ads.adZones.push($(this).attr('id'));
			});
			// IE gives errors if the API is on a different domain, so disable it.
			//$.post(API_PATH, { zones: BoatUS.Ads.adZones, member: BoatUS.Member.getAdMember() }, function(d,s,x) { BoatUS.Ads.onDataLoaded(d, s, x); });
		},
		onDataLoaded: function(d, s, x)
		{
			// The ad information has been retrieved from the server, lets do something with it.
			BoatUS.triggerEvent('Ads.Load', { });
		},
		renderImageAd: function(ad)
		{
			// Generate an image ad on the page.
		},
		renderFlashAd: function(ad)
		{
			// Generate a swf ad on the page.
		},
		renderTextAd: function(ad)
		{
			// Generate a text ad on the page.
		}
	},
	
	SWF: {
		expressInstallSwfUrl: '/assets/swf/expressInstall.swf',
		videos: {},
		styles: {
			playButton_Default: 'videoPreviewButton',
			playButton_Hover: ''
		},
		videoPlayerSwfUrl: 'http://www.boatus.com/membership/latitudes.swf',
		flashPlayerVersion: '9.0.0',
		flashVarDefs: {},
		flashParamDefs: {
			menu: 'false',
			quality: 'high',
			scale: 'noscale',
			loop: 'false',
			wmode: 'transparent',
			allowScriptAccess: 'sameDomain'
		},
		flashAttrDefaults: {},
		embed: function(swfUrl, id, width, height, flashvars, params, attributes, callbackFn)
		{
			params = $.extend({}, this.flashParamDefs, params);
			flashvars = $.extend({}, this.flashVarDefs, flashvars);
			if (!BoatUS.pageReady) {
				BoatUS.Queue.addToQueue(function() {
					BoatUS.SWF.embed(swfUrl, id, width, height, flashvars, params, attributes, callbackFn);
				});
				return;
			}
			var targetDiv = $('#' + id);
			BoatUS.require_once('/assets/js/swfobject/swfobject.js');
			swfobject.embedSWF(swfUrl, id, width, height, BoatUS.SWF.flashPlayerVersion, this.expressInstallSwfUrl, flashvars, params, attributes, callbackFn);
			BoatUS.triggerEvent("SWF.Load", { swf: swfUrl });
		},
		// Embed a video with a preview frame in it.
		embedVideo: function(id, width, height, videoSrc, firstFrameSrc, flashVars, params, attributes)
		{
			params = $.extend({}, this.flashParamDefs, params);
			if (!BoatUS.pageReady) {
				BoatUS.Queue.addToQueue(function() {
					BoatUS.SWF.embedVideo(id, width, height, videoSrc, firstFrameSrc, flashVars, params, attributes);
				});
				return;
			}
			BoatUS.require_once('/assets/js/swfobject/swfobject.js');
			var videoID = BoatUS.uniqueID();
			this.videos[videoID] = { src: videoSrc, firstFrame: firstFrameSrc, id: id, width: width, height: height, flashVars: flashVars, params: params, attributes: attributes };
			var targetDiv = $('#' + id).css('position', 'relative');
			targetDiv.empty();
			//	create a holder div to load the preview into.
			var embedDiv = $('<div/>', { css: { width: width, height: height, margin: '0 0 8px 0' } }).addClass('videoEmbed').appendTo(targetDiv);
			var thumbLink = $('<a/>', { css: { position: 'absolute', height: height, width: width }, title: 'Click to Play Video', href: '#', click: function() { BoatUS.SWF.playVideo(videoID); return false; } }).addClass('noHover').addClass('noLine').appendTo(embedDiv);
			thumbLink.append($('<img/>', { css: { margin: 0 }, src: firstFrameSrc, width: parseFloat(width), height: parseFloat(height)}));
			var playBtn = $('<span/>', { css: { height: '75px', width: '75px' } }).addClass('playBtn').appendTo(thumbLink);
		},
		playVideo: function(id)
		{
			var curVideo = this.videos[id];
			this.embed(this.videoPlayerSwfUrl, curVideo.id, curVideo.width, curVideo.height, curVideo.flashVars, curVideo.params, curVideo.attributes);
		}
	},
	
	Validate: {
		email: function(strEmail)
		{
			var reg = /^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/;
			return reg.test(strEmail);
		}
	},
	
	Social: {
		loadFBAPI: function()
		{
			window.fbAsyncInit = function() {
				FB.init({appId: FB_APP_ID, status: true, cookie: true, xfbml: true});
			};
			if ($('#fb-root').length === 0) { $('body').prepend($('<div id="fb-root"></div>')); }		// The Facebook API needs a div to attach it's scripts to.
			var e = document.createElement('script'); e.async = true;
			e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
			document.getElementById('fb-root').appendChild(e);
		},
		share: function(args)
		{
			args = BoatUS.Social.parseOpts(args);
			BoatUS.handleOverlay('share', args);
		},
		parseOpts: function(args)
		{
			// go through the options the the args hash and return the set to use.
			args = $.extend({}, BoatUS.Options.socialOpts, args);
			args.title = unescape(args.title);
			return args;
		},
		shareFB: function(args)
		{
			args = BoatUS.Social.parseOpts(args);
			strShareLink = 'http://www.facebook.com/sharer.php?u=' + encodeURIComponent(args.url) + '&t=' + encodeURIComponent(args.title);
			BoatUS.Popup(strShareLink, 'facebookShare', { width: 650, height: 300});
			BoatUS.Social.wtTrackShare('Facebook', args.title, args.url);
			return false;
		},
		shareTW: function(args)
		{
			args = BoatUS.Social.parseOpts(args);
			strShareLink = 'http://twitter.com/share?url=' + encodeURIComponent(args.url) + '&text=' + encodeURIComponent(args.title) + '&via=BoatUS';
			BoatUS.Popup(strShareLink, 'twitterShare', { width: 650, height: 200 });
			BoatUS.Social.wtTrackShare('Twitter', args.title, args.url);
			return false;
		},
		shareDG: function(args)
		{
			args = BoatUS.Social.parseOpts(args);
			strShareLink = 'http://digg.com/submit?url=' + encodeURIComponent(args.url) + '&title=' + encodeURIComponent(args.title) + '&bodytext=' + encodeURIComponent(args.description);
			BoatUS.Popup(strShareLink, 'diggShare', { width: 1050, height: 655 });
			BoatUS.Social.wtTrackShare('Digg', args.title, args.url);
			return false;
		},
		shareSU: function(args)
		{
			args = BoatUS.Social.parseOpts(args);
			strShareLink = 'http://www.stumbleupon.com/submit?url=' + encodeURIComponent(args.url) + '&title=' + encodeURIComponent(args.title);
			BoatUS.Popup(strShareLink, 'stumbleShare', { width: 720, height: 500});
			BoatUS.Social.wtTrackShare('Stumble Upon', args.title, args.url);
			return false;
		},
		shareEM: function(args)
		{
			BoatUS.handleOverlay('sendToFriend', args);
		},
		wtTrackShare: function(strService, strTitle, strURL)
		{
			try {
				dcsMultiTrack('WT.ria_a', 'Social', 'WT.ria_ev', 'Share', 'DCSext.smService', strService, 'WT.ria_c', strTitle + ' (' + strURL + ')', 'DCSext.url', strURL);
			} catch (e) {
		
			}
		}
	},
	// The UI API allows us to build rich UI interactions.
	UI: {
		// Create a tabbed interface.
		tabs: {
			init: function(strContainerID, objOpts)
			{
				var oOpts = {};
				if (!BoatUS.pageReady) {
					// The UI call was too early. Defer until the page has fully loaded.
					BoatUS.Queue.addToQueue(function() {
						BoatUS.UI.tabs.init(strContainerID, objOpts);
					});
					return;
				}
				oOpts = $.extend({}, BoatUS.Options.UI.tabs, objOpts);
				if ($(strContainerID).length > 1) {
					// The tabs function must only be called on a single element. If more than one element is passed, loop through them.
					$(strContainerID).each(function(i, e) {
						BoatUS.UI.tabs.init(this, oOpts);
					});
					return;
				}
				var container, tabsID, curTab;
				if ($(strContainerID).length != 1) { return; }
				container = $(strContainerID);
				$(container).addClass('tabbed-module');
				tabsID = container.attr('id');
				if (oOpts.save) { curTab = BoatUS.Data.get('tabs_' + tabsID);	 } else { BoatUS.Data.remove('tabs_' + tabsID); }
				if ($('#' + curTab).length < 1) { curTab = ''; }
				if (oOpts.selected - 1 >= container.children('div').length) { oOpts.selected = 1; }
				if (curTab === '' || curTab === null || curTab == undefined) { curTab = container.children('div').eq(oOpts.selected - 1); } else { curTab = '#' + curTab; }
				container.children('div').not(curTab).hide();
				$('ul.tabs > li', container).each(function(i, e) {
					$('a', this).click(function(e) {
						BoatUS.UI.tabs.changeTab(this);
						return false;
					});
				});
				curTab = $(curTab, container);
				curTab.addClass('current').show();
				$('a[rel="' + curTab.attr('id') + '"]').parent().addClass('current');
				if (typeof oOpts.onChange == "function") {
					$(container).data('onChange', oOpts.onChange);
					oOpts.onChange({ target: curTab, type: 'click', tabID: $(curTab).attr('rel') }, container);
				}
			},
			// Change to the given tab.
			changeTab: function(arg0, arg1)
			{
				var objTab, clickedTab, clickTabGroup, targetTab;
				if (arg1 === undefined) {
					// if only 1 argument was passed, that argument must be the jquery pointer to the tab to show.
					objTab = arg0;
				} else {
					// otherwise arg0 is the container, and arg1 is the tab index.
					objTab = $('li', arg0).eq(arg1).find('a');
				}
				clickedTab = $(objTab).parent();
				clickedTabGroup = $(objTab).closest('.tabbed-module');
				targetTab = $('#' + $(objTab).attr('rel'));
				clickedTabGroup.find('li').removeClass('current');
				clickedTab.addClass('current');
				BoatUS.Data.set('tabs_' + clickedTabGroup.attr('id'), $(objTab).attr('rel'));
				clickedTabGroup.children('div').hide();
				$(targetTab).show();
				if (typeof clickedTabGroup.data('onChange') == "function") {
					clickedTabGroup.data('onChange')({ target: objTab, type: 'click', tabID: $(objTab).attr('rel') }, clickedTabGroup);
				}
			}
		},
		// work with text
		text: {
			initialized: false,
			init: function()
			{
				// maybe have some bootstrap code when it's first called.
			},
			// Make the text larger or smaller.
			resize: function(strTarget, amt, nest)
			{
				BoatUS.log(amt);
				if (!this.initialized) this.init();
				if ($(strTarget).hasClass('noResize')) { return false; }
				if (amt === 0) { $(strTarget).css('font-size', ''); }
				if (amt < 0) {
					if (BoatUS.Options.UI.text.curSize - Math.abs(amt) < BoatUS.Options.UI.text.minSize) { return false; }
				} else {
					if (BoatUS.Options.UI.text.curSize + Math.abs(amt) > BoatUS.Options.UI.text.maxSize) { return false; }
				}
				if (amt == 0) { BoatUS.Options.UI.text.curSize = 0; }
				if (nest != true) {
					BoatUS.Options.UI.text.curSize += amt;
				}
				$('*', strTarget).contents().css('font-size',((1 + (BoatUS.Options.UI.text.curSize * .1)) * 100) + '%');
				return false;
			}
		}
	},
	// The data API gives us high-level access to any available browser storage APIs.
	Data: {
		get: function(strKey)
		{
			if (typeof(JSON) != 'object') return;		// We can only retrieve data if the JSON methiods are available.
			if (strKey == "" || strKey == undefined || strKey == null) { return ""; }
			var varVal = '';
			if (window.sessionStorage) {
				if (sessionStorage.getItem(strKey) != "") {
					varVal = JSON.parse(sessionStorage.getItem(strKey));
				}
				BoatUS.log("DATA.GET: " + strKey + " = " + varVal);
			} else {
				// provide some sort of fallback. (Cookies, maybe).
				
			}
			return varVal;
		},
		set: function(strKey, varVal)
		{
			if (typeof(JSON) != 'object') return;		// We can only store data if the JSON methiods are available.
			if (window.sessionStorage) {
				sessionStorage.setItem(strKey, JSON.stringify(varVal));
			} else {
				// provide some sort of fallback. (Cookies, maybe).
				
			}
			BoatUS.log("DATA.SET: " + strKey + " = " + varVal);
		},
		remove: function(strKey)
		{
			if (window.sessionStorage) {
				sessionStorage.removeItem(strKey);
			} else {
				// provide some sort of fallback. (Cookies, maybe).
				
			}
			BoatUS.log("DATA_REMOVE: " + strKey);
		}
	},
	// Store information about the current user agent. Useful for page debugging.
	Browser: {
		properties: {
			type: '',
			version: '',
			platform: '',
			cookies: false,
			agent: '',
			flash: false
		},
		init: function(opts)
		{
			this.properties.type = navigator.appName;
			this.properties.version = navigator.appVersion;
			this.properties.cookies = navigator.cookieEnabled;
			this.properties.platform = navigator.platform;
			this.properties.agent = navigator.userAgent
			this.properties.flash = navigator.mimeTypes && navigator.mimeTypes["application/x-shockwave-flash"];
		}
	},
	
	// Triggers a previously bound event.
	triggerEvent: function(eventType, eventArgs)
	{
		if (typeof this.Events[eventType] == 'object') {
			for (var f in this.Events[eventType]) {
				if (typeof this.Events[eventType][f] == 'function') { 
					eventArgs.eventType = eventType;
					this.Events[eventType][f](eventArgs);
				}
			}
		}
	},
	
	// Adds an event to the BoatUS object. The event may later be triggered with BoatUS.triggerEvent( ... ). Event names should be in the format [Module].[Action] (i.e. Overlay.Open)
	addEventListener: function(eventType, objFunc)
	{
		if (this.Events[eventType] === undefined) { this.Events[eventType] = []; }
		this.Events[eventType].push(objFunc);
	},
	
	// Include a JavaScript file into the page.
	require: function(url)
	{
		if (this.Includes === undefined) { this.Includes = {}; }
		$('<script>', { type: 'text/javascript', src: url}).appendTo($('head').first());
		return;
	},
	
	// Include a JavaScript file into the page exactly once.
	require_once: function(url)
	{
		if (this.Includes === undefined) { this.Includes = {}; }
		if (this.Includes[url]) { return; }
		this.require(url);
		this.Includes[url] = true;
		return;
	},
	
	// Abstracts the logging interface so that we can log from any browser.
	log: function(strMsg)
	{
		//if (BoatUS.Options.debug === false || BoatUS.Options.debug == null) { return; }
		if (typeof console != "undefined") {
			console.log(strMsg);
		}
	},
	
	randomString: function(string_length)
	{
		if (string_length === undefined) { string_length=  8; }
		var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
		var randomstring = '';
		for (var i=0; i < string_length; i++) {
			var rnum = Math.floor(Math.random() * chars.length);
			randomstring += chars.substring(rnum,rnum+1);
		}
		return randomstring;
	},
	
	uniqueID: function()
	{
		if (typeof BoatUS.incrementID == "undefined") { BoatUS.incrementID = 0; }
		BoatUS.incrementID++;
		return BoatUS.incrementID;
	}

};
BoatUS.addEventListener('Ads.Load', function(e) { console.log('ads loaded'); });
// Call the Bootstrap function when everything is ready. Events should be bound before this init function is called.
$(document).ready(function() {  BoatUS.init((typeof pageOptions != 'undefined') ? pageOptions : {}); $('.leftNav').accordionMenu((typeof accordionOptions != 'undefined') ? accordionOptions : {}); $('.zebra').jqStripe(); });
 
(function($) {
	$.fn.accordionMenu = function(options) {
		var defaults = {
			startCollapsed: true,
			current: ''
		};
		var opts = $.extend({}, defaults,options);
		$(opts.current).addClass('current');
		$('#topNav ul.subNav').each(function(i, e) {
			$(this).parent().addClass('hasSub');
		});
		return this.each(function(i) {
			buildMenu(this, opts);
		});
	};
	
	var buildMenu = function(el, opts)
	{
		var parent = $(el);
		var startCollapsed = opts.startCollapsed || false;
		//if (parent.hasClass('expanded')) { startCollapsed = false; }
		//if (parent.has('.expanded').length > 0) { startCollapsed = false; }
		//if ($(opts.current, parent).length > 0) { startCollapsed = false; }
		$(parent).children('li').each(function(i, e) {
			if ($(e).children('ul').length > 0) {
				startCollapsed = true;
				if ($(e).has('.expanded').length <= 0) { startCollapsed = true; } else { startCollapsed = false; }
				if ($(opts.current, e).length > 0) { startCollapsed = false; }
				if (startCollapsed)
				{
					$(e).addClass('closed').children('ul').not('.expanded').slideUp("fast");
				} else {
					$(e).addClass('open').children('ul').slideDown('fast');
				}
				$(e).children('.expanded').slideDown('fast').parent().removeClass('closed').addClass('open');
				$(e).addClass('hasSub').find('a:first').attr('title', 'Click to Expand Menu');
				$('a:first', e).click(function(){
					$(this).parent().next().slideToggle('fast', function() {
						if ($(this).parent().hasClass('open'))
						{
							$(this).parent().removeClass('open').addClass('closed');
						} else {
							$(this).parent().removeClass('closed').addClass('open');
						}
					});
					return false;
				}).wrap('<div />');
				if ($('ul', e).length > 0) {
					$('ul', e).accordionMenu(opts);
				}
			}
		});
	};
})(jQuery);
 
(function($){$.fn.extend({center:function(options){var opts=$.extend({inside:window,transition:0,minX:0,minY:0,vertical:true,withScrolling:true,horizontal:true},options);return this.each(function(){var props={position:'absolute'};if(opts.vertical){var top=($(opts.inside).height()-$(this).outerHeight())/2;if(opts.withScrolling){top+=$(opts.inside).scrollTop()||0}top=(top>opts.minY?top:opts.minY);$.extend(props,{top:top+'px'})}if(opts.horizontal){var left=($(opts.inside).width()-$(this).outerWidth())/2;if(opts.withScrolling){left+=$(opts.inside).scrollLeft()||0}left=(left>opts.minX?left:opts.minX);$.extend(props,{left:left+'px'})}if(opts.transition>0){$(this).animate(props,opts.transition)}else{$(this).css(props)}return $(this)})}})})(jQuery); 

(function($){$.fn.jqStripe=function(params){var _params={stripeClasses:['odd','even'],rowSelector:'tbody > tr:visible'};params=$.extend(_params,params);var stripes=params.stripeClasses.length;var classes=params.stripeClasses.join(' ');return this.each(function(){$(params.rowSelector,this).each(function(i){$(this).not('.noStripe').removeClass(classes).addClass(params.stripeClasses[i%stripes]).hover(function(){$(this).addClass('rowHover')},function(){$(this).removeClass('rowHover')})})})}})(jQuery);
