var datePicker = {
	init: function() { datePicker.build(); },
	build: function() {
		this.gui = {
			ddl:			$dom.getById('template_ticketPanel_dd_Dates'),
			price_types:	$dom.getById('price_types') || $dom.create('span'), // create dummy span if no price types
			btn_submit:		$dom.getById('template_ticketPanel_btn_Reserve'),
			div_display:	$dom.create('div',{id: 'div_display'}),
			txt_display:	$dom.create('span',{id: 'txt_display'}),
			lnk_minical:	$dom.create('a',{id:'lnk_minical',href:'#',title:'Open Calendar'}),
			img_minical:	$dom.create('img',{src: us.popdt.config.ROOT_VIRTUAL + '/_img/button/minical.gif'}),
			cal_minical:	$dom.create('div',{id:'cal_minical',className:'off'}),
			cal_timewindow: $dom.create('div',{id:'cal_timewindow',className:'off'},'Time Wndow')
		}
		this.gui.div_display.appendChild(this.gui.txt_display); // add text to div
		this.gui.div_display.appendChild(this.gui.lnk_minical); // add link to div
		this.gui.lnk_minical.appendChild(this.gui.img_minical); // add image to link
		if (this.gui.ddl == false) { return; } // fail silently if no ddl (no dates available)
		this.gui.ddl.parentNode.insertBefore(this.gui.div_display,this.gui.ddl); // hide DDL, show TEXT
		this.gui.ddl.style.position = 'absolute';
		this.gui.ddl.style.left = '-5001px';
		this.gui.div_display.parentNode.insertBefore(
											this.gui.cal_minical,
											this.gui.div_display.parentNode.lastChild.previousSibling
										); // insert calendar holder below TEXT display
		this.gui.txt_display.innerHTML = this.gui.ddl.options[this.gui.ddl.selectedIndex].innerHTML;
		this.gui.lnk_minical.onclick = function() { return false; }
		us.popdt.event.add(this.gui.lnk_minical,'mousedown',this._calButtonClick)

		this.data = {
			calStart:		$dom.getById('template_ticketPanel_lbl_calendarStart').value,
			dates:			$dom.getById('template_ticketPanel_lbl_calendarDates').value,
			state:			-1 // -1: no data, 0: data loading, 1: data
		}
		this.xhr = us.popdt.io.XHR();
		this.xhr_is_busy = false;
		this.webServiceUrl = us.popdt.config.ROOT + '/svc/production.asmx'
		
		this._getCalData(); // pre-load calendar data
	},
	
	// MAIN HOOKS FOR CORE ACTIONS
	openCalendar: function() {
		this._toggleCalendar(1);
	},
	closeCalendar: function() {
		this._toggleCalendar(0);
	},
	
	// WEBSERVICE CALLS AND PROCESSING
	_getCalData: function() {
		this.data.state = 0;
		var url = this.webServiceUrl + '/GetMiniCalendar';
		var params = 'month={0}&dates={1}&productionID={2}'
			.format(this.data.calStart, this.data.dates.replace(/[,]$/,''), location.toString().toQueryParams()['id']);
		this._postData(url, this._processCalData, params);
	},
	_getCalDataByDate: function(date) {
		this.data.calStart = date;
		this._toggleCalendar(1);
		this._getCalData();
	},
	_getCalTimeData: function(sTimes) {
		var url = this.webServiceUrl + '/GetMiniCalendarOptions';
		var params = 'dates={0}&productionID={1}'
			.format(sTimes,location.toString().toQueryParams()['id']);
		this._postData(url, this._processCalTimeData, params);
	},
	
	// Process data returned from the webservice
	_processCalData: function() { datePicker._onProcessCalData(); },
	_onProcessCalData: function() {
		if (this.xhr.readyState == 4) { // wait for readyState Success
			var cal = this.xhr.responseXML.getElementsByTagName('data')[0].firstChild.nodeValue;
			var calTable = cal;
			var calNode = this.xhr.responseXML.getElementsByTagName('calendar')[0];
			var calPrevious =	calNode.getAttribute('prevMonth');
			var calNext =		calNode.getAttribute('nextMonth');
			var calMonth =		calNode.getAttribute('name');
			var calYear =		calNode.getAttribute('year');
			
			this._buildCalWindow(calTable,calMonth,calYear,calNext,calPrevious);
			this.data.state = 1;
			this._toggleCalLoadingState(0);
		}
	},
	_processCalTimeData: function () { datePicker._onProcessCalTimeData(); },
	_onProcessCalTimeData: function() { // TODO remove check for 'day' node
		if (this.xhr.readyState == 4) {
			var times = this.xhr.responseXML.getElementsByTagName('data')[0].firstChild.nodeValue;
			var date = this.xhr.responseXML.getElementsByTagName('day')[0].firstChild.nodeValue;
			this._buildTimeWindow(date,times);
		}
	},
	
	// UTILITY FUNCTIONS FOR THE ENTIRE APP
	/**
	 * Wrapper function for ALL XHR interaction in the datePicker
	 * @param string sUrl The webservice URL to retrieve data from
	 * @param function fCallbackFunction The function to handle the XHR response
	 */

 	_postData: function(sUrl, fCallbackFunction, sParams) {
		this._workData(sUrl, fCallbackFunction, 'POST', sParams);
	 },
	 
	 _getData: function(sUrl, fCallbackFunction) {
		this._workData(sUrl, fCallbackFunction, 'GET', null);
	 },
	 
	_workData: function(sUrl, fCallbackFunction, sMethod, sData) {
		if (this.xhr_is_busy == true) {
			this.xhr.onreadystatechange = function() {}
			this.xhr.abort();
		}
		
		
		
		this.xhr.open(sMethod, sUrl);
		
		if(sMethod == 'POST') {
			this.xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
			this.xhr.setRequestHeader('Content-Length', sData.length);
		}
		this.xhr.onreadystatechange = fCallbackFunction;
		this.xhr.send(sData);
		this.xhr_is_busy = true;
	},


	
	
	// UI FUNCTIONS
	_toggleCalendar: function(bOnOff) {
		if (bOnOff) {
			if (this.data.state < 1) {
				this.gui.cal_minical.innerHTML = '';
				this._toggleCalLoadingState(1);
			}
			$dom.swapClass(this.gui.cal_minical,'off','on');
			this.gui.price_types.style.visibility = 'hidden';
			this.gui.lnk_minical.setAttribute('title','Close Calendar')
		} else {
			$dom.swapClass(this.gui.cal_minical,'on','off');
			$dom.swapClass(this.gui.cal_timewindow,'on','off');
			this.gui.price_types.style.visibility = 'visible';
			this.gui.lnk_minical.setAttribute('title','Open Calendar')
		}
	},
	// Add or remove the loading BG from the calendar wrapper
	_toggleCalLoadingState: function(bOnOff) {
		if (bOnOff) {
			$dom.addClass(this.gui.cal_minical,'loading');
		} else {
			$dom.removeClass(this.gui.cal_minical,'loading');
		}
	},
	// captures cal button click and either opens or closes the calendar
	_calButtonClick: function() {
		if ($dom.hasClass(datePicker.gui.cal_minical,'off')) {
			datePicker.openCalendar();
		} else {
			datePicker.closeCalendar();
		}
	},
	// captures clicks on individual calendar date links
	_calDateClick: function() {
		var time = this.href.toQueryParams()['time'].replace(/[,]$/,'');
		datePicker._getCalTimeData(time);
	},
	_calPrevNextClick: function() {	datePicker._getCalDataByDate(this.href.toQueryParams()['date']) },
	_btnCloseTimeWindowClick: function() {
		$dom.swapClass(datePicker.gui.cal_timewindow,'on','off');
	},
	
	_buildTimeWindow: function(sDate, sTimeHTML) {
		var win = this.gui.cal_timewindow;
		var cal = this.gui.cal_minical;
		win.innerHTML = sTimeHTML;
		var btn_close = win.insertBefore($dom.create('a',{id:'btn_close_timewindow',href:'?close=true',title:'Close Time Display'},
														$dom.create('span','Close')
												   )
									   ,win.firstChild);
		btn_close.onclick = function() { return false; }
		us.popdt.event.add(btn_close,'mousedown',this._btnCloseTimeWindowClick);
		var d = win.insertBefore($dom.create('h4',sDate),btn_close.nextSibling);
		$dom.swapClass(win,'off','on');
	},
	_buildCalWindow: function(sCalTable,sMonth,iYear,sNextQuery,sPreviousQuery) {
		this.gui.cal_minical.innerHTML = sCalTable;

		// add onclick handlers to all date links to call getcaloptions
		var dateLinks = this.gui.cal_minical.getElementsByTagName('a');
		for (var i=0; i<dateLinks.length; i++) {
			dateLinks[i].onclick = function() { return false; }
			us.popdt.event.add(dateLinks[i],'click',this._calDateClick);
		}
		
		// build layout
		this.gui.cal_minical.insertBefore($dom.create('h4',sMonth + ' ' + iYear),this.gui.cal_minical.firstChild);
		if (sNextQuery || sPreviousQuery) {
			var nav = $dom.create('ul',{id:'cal_nav'});
			if (sPreviousQuery) {
				var link;
				nav.appendChild(
					$dom.create('li',{className:'previous'},
						link = $dom.create('a',{href:'?date='+sPreviousQuery,title:'Previous Month'},
							$dom.create('span','Previous'))));
				link.onclick = function() { return false; }
				us.popdt.event.add(link,'mousedown',this._calPrevNextClick);
			}
			if (sNextQuery) {
				var link;
				nav.appendChild(
					$dom.create('li',{className:'next'},
						link = $dom.create('a',{href:'?date='+sNextQuery,title:'Next Month'},
							$dom.create('span','Next'))));
				link.onclick = function() { return false; }
				us.popdt.event.add(link,'mousedown',this._calPrevNextClick);
			}
			this.gui.cal_minical.insertBefore(nav,this.gui.cal_minical.firstChild);
		}
		this.gui.cal_minical.insertBefore(
			this.gui.cal_timewindow = $dom.create('div',{id:'cal_timewindow',className:'off'}),
			this.gui.cal_minical.getElementsByTagName('table')[0]
		);
	}
}
us.popdt.event.add(window,'load',datePicker.init);

var tabnav = {
	// APPLICATION INITIALIZATION
	init: function() { tabnav.build(); },
	
	build: function() {
		this.gui = {
			tabs: [],								 // array to store tab links
			tabUL: $dom.getById("production_panel_tabs"),	 // tab UL
			contentArea: $dom.getById("production_panels") // content area
		}
		if (!this.gui.contentArea || !this.gui.tabUL || !us.popdt.client.capable.xhr) { return false; } // Stop now if elements not found or XHR not supported
		this.xhr = us.popdt.io.XHR();
		
		var li = this.gui.tabUL.childNodes;
		for (var i=0; i<li.length; i++) {// loop through tabUL children and grab tab links
			if (li[i].nodeType == 1 && li[i].nodeName == 'LI') {
				li[i].firstChild.onclick = function() { this.blur(); return false };
				li[i].firstChild.onmousedown = tabnav.tabClick;
				this.gui.tabs.push(li[i].firstChild);
			}
		}
	},
	
	// CAPTURE USER INTERACTION
	tabClick: function() { tabnav.onTabClick(this); }, // alias to onTabClick

	onTabClick: function(oTabAnchor) {
		var t = oTabAnchor.href.toQueryParams()['tab'];
		this.setTab(t);
		this.displayTabContent(t);
	},
	
	
	// PROCESSING METHODS
	setTab: function(sTabName) {
		for(var i=0; i<this.gui.tabs.length; i++) {
			var p = this.gui.tabs[i].parentNode;
			var tName = this.gui.tabs[i].href.toQueryParams()['tab'];
			if (tName == sTabName) {
				$dom.swapClass(p,'off','on');
			} else {
				$dom.swapClass(p,'on','off');
			}
		}
	},
	setContent: function(soContent) {
		if (typeof soContent == 'object') {
			this.gui.contentArea.innerHTML = '';
			this.gui.contentArea.appendChild(soContent);
		} else {
			this.gui.contentArea.innerHTML = soContent;
		}
	},
	// Route request to appropriate functionality
	displayTabContent: function(sTabName) {
		// All of these could be shortened to:
		// this.getXHRContent(sTabName);
		switch(true) {
			case sTabName=='overview':
				this.displayOverview();
				break;
			case sTabName=='artists':
				this.displayArtists();
				break;
			case sTabName=='photos':
				this.displayGallery();
				break;
			case sTabName=='multimedia':
				this.displayMultimedia();
				break;
			case sTabName=='blog':
				this.displayBlog();
				break;
			case sTabName=='articles':
				this.displayArticles();
				break;
			case sTabName=='podcast':
				this.displayPodcasts();
				break;
			case sTabName=='video':
				this.displayVideos();
				break;
			default:
				// dbug.error('Unknown Tab Name "{0}" in displayTabContent'.format(sTabName));
				break;
		}
	},
	// Set of functionality for each tab
	displayOverview: function() {
		this.getXHRContent('overview')
	},
	displayArtists: function() {
		this.getXHRContent('artists');
	},
	displayGallery: function() {
		this.getXHRContent('photos');
	},
	displayMultimedia: function() {
		this.getXHRContent('multimedia');
	},
	displayBlog: function() {
		this.getXHRContent('blog');
	},
	displayArticles: function() { // this could be wrapped up into a single 'case' of displayTabContent
		this.getXHRContent('articles');
	},
	displayPodcasts: function() {
		this.getXHRContent('podcast');
	},
	displayVideos: function() {
		this.getXHRContent('video');
	},
	
	// All XHR tab content requests go through here
	getXHRContent: function(sTabName) {
		// reset xhr object
		if (this.xhr_is_busy == true) {
			this.xhr.onreadystatechange = function() {}
			this.xhr.abort();
		}
		this.xhr.open("GET",this.getRequestString(sTabName));
		this.xhr.onreadystatechange = this.processXHRContent;
		this.xhr.send(null);
		this.xhr_is_busy = true;
	},
	// build the request string and return it.
	getRequestString: function(sTabName) {
		var loc = location.toString().toQueryParams();
		var query = us.popdt.config.ROOT + "/svc/Production.asmx/GetTabContent";
		query += "?tab={0}&id={1}".format(sTabName, loc.id);
		query += (typeof loc.src != "undefined") ? "&src={0}".format(loc.src) : "";
		return query;
	},
	processXHRContent: function() { tabnav.onProcessXHRContent(); },
	onProcessXHRContent: function() {
		if (this.xhr.readyState == 4) { // wait for readyState Success
			var xml = this.xhr.responseXML, type = '';
			for (var n=xml.firstChild; n; n=n.nextSibling) { // Find first elementNode
				if (n.nodeType == 1) { xml=n; type=n.nodeName.toLowerCase(); break; }
			}
			switch(true) {
				case type=='overviewset':
					this.processOverviewXML(xml);
					break;
				case type=='articleset':
					this.processArticlesXML(xml);
					break;
				case type=='artistsset':
					this.processArtistsXML(xml);
					break;
				case type=='multimediaset':
					this.processMultimediaXML(xml);
					break;
				case type=='galleryset':
					this.processGalleryXML(xml);
					break;
				case type=='blogset':
					this.processBlogXML(xml);
					break;
				case type=='podcastset':
					this.processPodcastsXML(xml);
					break;
				case type=='videoset':
					this.processVideosXML(xml);
					break;
				default:
					// dbug.error('Unknow XML set "{0}" in onProcessXHRContent'.format(type));
			}
			this.xhr_is_busy = false;
		}
	},
	
	// Processing methods for each XHR return set
	// Currently, these are totally unmanageable. Code must be synced up between
	// the css, each of these process methods, and the tab.ascx files. There should
	// be one method - asmx pulls in the redered ascx file, this grabs the output
	// from asmx, and spits it onto the page. If we don't address this, updating
	// this functionality will be a nightmare. Plus, we could save about 200 lines
	// of JavaScript code.
	processArticlesXML: function(xml) {
		var articles = $x.evalJSON($x.xml2json(xml)).articleSet.article;
		
		var wrapper =	'<div class="pnl_articles">';
		wrapper +=			'<h4 class="pnl_header"><span>Articles & Interviews</span></h4>';
		wrapper +=			'<ul id="{0}" class="pnl_content">{1}</ul>';
		wrapper +=		'</div>';
		var li = '';
		
		if (articles.length) {
			for (var i=0; i<articles.length; i++) {
				var liClass = (i % 2 == 1) ? 'odd' : '' ;
				var a = articles[i];
				var link = us.popdt.config.ROOT + '/backstage/article.aspx?id=' + a['@id'];
				li +=	'<li class="{0}">'.format(liClass);
				li +=	'<h4><a href="{0}">{1}</a></h4>'.format(link, a.title);
				li +=	(a.author != '') ? 'by <span class="byline">{0}</span>'.format(a.author) : '';
				li +=	'<p>{0}<a href="{1}"> ...more</a></p>'.format(a.summary, link);
			}
		} else {
			var liClass = (i % 2 == 1) ? 'odd' : '' ;
			var link = us.popdt.config.ROOT + '/backstage/article.aspx?id=' + articles['@id'];
			li +=	'<li class="{0}">'.format(liClass);
			li +=	'<h4><a href="{0}">{1}</a></h4>'.format(link, articles.title);
			li +=	(articles.author != '') ? 'by <span class="byline">{0}</span>'.format(articles.author) : '';
			li +=	'<p>{0}<a href="{1}"> ...more</a></p>'.format(articles.summary, link);
		}
		
		this.setContent(wrapper.format('article_list',li));
	},
	processBlogXML: function(xml) {
		var blog = xml.getElementsByTagName('data')[0].firstChild.nodeValue;
		var content =	'<div class="pnl_blog">'
		content +=			blog;
		content +=		'</div>';
		this.setContent(content);
	},
	processPodcastsXML: function(xml) {
		var podcasts = xml.getElementsByTagName('data')[0].firstChild.nodeValue;
		podcasts = podcasts.replace('<li>','<li class="first">');
		var content =	'<div class="pnl_podcasts">'
		content +=			'<h4 class="pnl_header"><span>Podcasts</span></h4>';
		content +=			podcasts;
		content +=		'</div>';
		this.setContent(content);
		podcasts.evalScripts();
	},
	processVideosXML: function(xml) {
		var videoSelect = document.createElement("select");
		var videos = xml.getElementsByTagName('video');
		
		var firstTitle = $(videos[0]).children("title").text();
		var firstURI = $(videos[0]).children("uri").text();
		var firstDesc = $(videos[0]).children("description").text();
		var firstSplashImg = $(videos[0]).children("imgPath").text();
		var firstFlvWidth = $(videos[0]).children("flvWidth")[0].firstChild.nodeValue;
		var firstFlvHeight = $(videos[0]).children("flvHeight")[0].firstChild.nodeValue;
		if (!firstFlvWidth) firstFlvWidth = 0;
		if (!firstFlvHeight) firstFlvHeight = 0;
		
		var content =	'<div class="pnl_videos">'
		content +=			'<h4 class="pnl_header"><span>Video</span></h4>';
		content +=			'<div id="video_player"></div>';
		content +=			'<p id="video_desc"></p>';
		content +=		'</div>';
		this.setContent(content);
		
		// Load the first video listed in the XML
		this.loadVideo(firstTitle,firstURI,firstDesc,firstSplashImg,firstFlvWidth,firstFlvHeight);
		
		if (videos.length > 1) {
			for(var i=0; i < videos.length; i++) {
				var option = document.createElement("option");
				var vidTitle = videos[i].getElementsByTagName("title");
				if (vidTitle) {
					option.innerHTML = vidTitle[0].firstChild.nodeValue;
				}
				$(option).val(videos[i].getAttribute("id"));
				videoSelect.appendChild(option);
			}
		
			var tabnavObj = this;
			$(videoSelect).addClass("pnl_control");
			$(videoSelect).change(function(event) {
				var i = $(this)[0].selectedIndex;
				var selectedOpt = $(this)[0].options[i];
				var title = selectedOpt.innerHTML;
				var videoID = $(selectedOpt).val();
				var video = $(videos).filter("video[id="+videoID+"]");
				
				var URI = video.children("uri")[0].firstChild.nodeValue;
				var desc = video.children("description")[0].firstChild.nodeValue;
				var img = video.children("imgPath")[0].firstChild.nodeValue;
				
				var flvWidth = video.children("flvWidth")[0].firstChild.nodeValue;
				var flvHeight = video.children("flvHeight")[0].firstChild.nodeValue;
				if (!flvWidth) flvWidth = 0;
				if (!flvHeight) flvHeight = 0;
				
				tabnavObj.loadVideo(title,URI,desc,img,flvWidth,flvHeight);
			});
			
			$("h4.pnl_header").after(videoSelect);
		}
	},
	processOverviewXML: function(xml) {
		var overview = xml.getElementsByTagName('data')[0].firstChild.nodeValue;
		var content =	'<div class="pnl_overview">'
		content +=			'<h4 class="pnl_header"><span>Overview</span></h4>';
		content +=			'<div class="pnl_content">';
		content +=				overview;
		content +=			'</div>';
		content +=		'</div>';
		this.setContent(content);
	},
	processArtistsXML: function(xml) {
		var artists = xml.getElementsByTagName('data')[0].firstChild.nodeValue;
		var content =	'<div class="pnl_artists">'
		content +=			artists;
		content +=		'</div>';
		this.setContent(content);
	},
	processGalleryXML: function(xml) {
		var g = $x.evalJSON($x.xml2json(xml)).galleryset.gallery;
		var img_url = us.popdt.config.ROOT_VIRTUAL + '/_img/button/';
		var options = '\n';
		if (typeof g.length != 'undefined') { // Many galleries
			for (var i=g.length-1; i>-1; i--) { // output is reverse of static output
				var selected = (i==g.length-1) ? ' selected="selected"' : '';
				options += '<option value="{0}"{1}>{2}</option>\n'.format(g[i]['@id'], selected, g[i].name);
			}
		} else { // Single Gallery
			options += '<option value="{0}" selected="Selected">{1}</option>\n'.format(g['@id'], g.name);
		}
		var gui =	'<div class="pnl_gallery" id="template_pnl_tab_gallery"><h4 class="pnl_header"><span>Photo Gallery</span></h4>\n';
		gui +=		'<select id="template_gallery_ddl_galleryList" name="template:gallery:ddl_galleryList" class="pnl_control">\n';
		gui +=		'{0}';
		gui +=		'</select>\n';
		gui +=		'<div class="pnl_content">\n';
		gui +=			'<img id="gall_img" src="" alt="" />\n';
		gui +=			'<p id="gall_caption"> </p>\n';
		gui +=			'<ul>\n';
		gui +=				'<li><a class="ga_jslink" id="btn_gall_back" href=""><img src="{1}" width="54" height="17" /></a></li>\n';
		gui +=				'<li><a class="ga_jslink" id="btn_gall_next" href=""><img src="{2}" width="54" height="17" /></a></li>\n';
		gui +=			'</ul>';
		gui +=		'</div></div>\n';
		gui =		gui.format(options, img_url+'back.gif', img_url+'next.gif');
		this.setContent(gui);
		gallery.state.buildFromTabLoad = true;
		gallery.build();
	},
	processMultimediaXML: function(xml) {
		var m = $x.evalJSON($x.xml2json(xml)).multimediaSet.multimedia;
		var options = '\n';
		var inputs = '\n';
		if (typeof m.length != 'undefined') { // Many Multimedia Files
			for (var i=m.length-1; i>-1; i--){
				var selected = (i==m.length-1) ? ' selected="selected"' : '';
				options += '<option value="{0}"{1}>{2}</option>\n'.format(m[i]['@id'], selected, m[i].name);
				inputs += '<input type="hidden" name="mediaSrc" id="mediaSrc_{0}" value="{1}" />'.format(m[i]['@id'], m[i].path);
			}
		} else { // Single Multimedia File
			options += '<option value="{0}" selected="Selected">{1}</option>\n'.format(m['@id'], m.name);
			inputs += '<input type="hidden" name="mediaSrc" id="mediaSrc_{0}" value="{1}" />'.format(m['@id'], m.path);
		}
		var gui =	'<div class="pnl_multimedia" id="template_pnl_tab_multimedia"><h4 class="pnl_header"><span>Multimedia</span></h4>\n';
		gui +=		'<select id="template_multimedia_ddl_multimediaList" name="template:multimedia:ddl_multimediaList" class="pnl_control">\n';
		gui +=		'{0}';
		gui +=		'</select>\n';
		gui +=		'{1}'
		gui +=		'<div class="pnl_content" id="swf_content">You must have JavaScript enabled and Adobe Flash Player 7 installed to view multimedia content.</div>';
		this.setContent(gui.format(options, inputs));
		mmedia.build();
	},
	
	loadVideo: function(title, URI, desc, imgPath, flvWidth, flvHeight) {
		var splitURI = URI.split('.');
		var videoFormat = splitURI[splitURI.length-1];
		
		//if the URI is local, prepend the virtual root path to it
		if (URI.indexOf("http://") < 0) {
			URI = us.popdt.config.ROOT_VIRTUAL + "/" + URI;
		}
		
		if (videoFormat == "flv") {
			// load flv video
			var so = new SWFObject(us.popdt.config.ROOT_VIRTUAL+"/_swf/steppenwolf_video.swf", title, "497", "402", "8", "#B2C1C6");
			so.addVariable("flvPath",URI);
			if (flvWidth == 0) {
				so.addVariable("flvWidth","438");
			} else {
				so.addVariable("flvWidth",flvWidth);
			}
			if (flvHeight == 0) {
				so.addVariable("flvHeight","252");
			} else {
				so.addVariable("flvHeight",flvHeight);
			}
			//optional - autoPlay will default to false if nothing is set
			so.addVariable("autoPlayBool","false");
			so.addVariable("imgPath",us.popdt.config.ROOT_VIRTUAL+imgPath);
		} else if (videoFormat == "swf") {
			// load swf video
			var so = new SWFObject(URI, title, "495", "400", "8", "#FFFFFF");
		} else {
			alert("Error: unknown file format");
			return;
		}
		
		so.write("video_player");
		
		/* Set the Description text */	
		if (desc) {
			//desc = desc.replace(/<[/a-z]+>/gim,"");
			$("p#video_desc").append(desc);
		} else {
			$("p#video_desc").append("");
		}
	}
}
us.popdt.event.add(window, "load", tabnav.init);



var mmedia = {
	// APPLICATION INITIALIZATION
	init: function() {
		($dom.getById('template_pnl_tab_multimedia') != false) ? mmedia.build() : false ;
	},
	build: function() {
		this.img_path = us.popdt.config.ROOT_VIRTUAL;
		this.xhr = us.popdt.io.XHR();

		this.gui = { // holds all Graphical elements
			wrapper:	$dom.getById('template_pnl_tab_multimedia'),
			nav:		$dom.getById('template_multimedia_ddl_multimediaList'),
			swf_div:	$dom.getById('swf_content')
		};

		us.popdt.event.add(this.gui.nav,'change',this.guiEvent.navSelect);
		this.onNavSelect(this.gui.nav.selectedIndex); // simulate initial nav selection.
	},
	guiEvent: {
		navSelect: function() { // [select]
			mmedia.onNavSelect(this.selectedIndex);
		}
	},
	onNavSelect: function(iNavIndex) {
		var file = this.getFileByID(this.gui.nav[iNavIndex].value)
		this.loadMedia(file);
	},
	
	getFileByID: function(iID) {
		return $dom.getById('mediaSrc_' + iID.toString()).value;
	},
	
	loadMedia: function(sSwfFile) {
		this.fo = new us.popdt.flash.FlashObject(us.popdt.config.ROOT_VIRTUAL + sSwfFile, 'flash', 495, 400, [7]);
		this.fo.write(this.gui.swf_div);
	}
}
us.popdt.event.add(window, "load", mmedia.init);




var gallery = {
	state: {
		initialized: false,
		imageSet: false,
		currentImageIndex: false,
		isNewImageSet: true,
		buildFromTabLoad: true
	},
	init: function() {
		if ($dom.getById('template_pnl_tab_gallery') != false) {
			gallery.state.buildFromTabLoad = false;
			gallery.build();
		}
	},
	build: function() {
		// CREATE CUSTOM EVENTS
		this.customEvents = new us.popdt.event.CustomEvents();
		this.customEvents.create('build');
		this.customEvents.create('getImageSetData');
		this.customEvents.create('processImageSetData');
		this.customEvents.create('');
		this.customEvents.create('imageLoad');
		
		// LISTEN TO CUSTOM EVENTS
		this.customEvents.addListener('processImageSetData',this,'installImageSet');

		// ADD PROPERTIES
		this.img_path = us.popdt.config.ROOT_VIRTUAL;
		this.xhr = us.popdt.io.XHR();

		// UI ELEMENTS
		this.gui = { // holds all Graphical elements
			wrapper:	$dom.getById('template_pnl_tab_gallery'),
			nav:		$dom.getById('template_gallery_ddl_galleryList'),
			caption:	$dom.getById('gall_caption'),
			img:		$dom.getById('gall_img'),
			back:		$dom.getById('btn_gall_back'),
			next:		$dom.getById('btn_gall_next')
		};
		
		this.gui.loader = new us.popdt.widget.Loader(this.gui.img);
		this.gui.loader.customEvents.addListener('loadInComplete',this,'updateImage');

		// ATTACH UI EVENTS
		this.gui.back.onclick = function(){ return false; }
		this.gui.next.onclick = function(){ return false; }
		us.popdt.event.add(this.gui.back,'mousedown',this.captureButtonClick);
		us.popdt.event.add(this.gui.next,'mousedown',this.captureButtonClick);
		us.popdt.event.add(this.gui.nav,'change',this.onNavSelect);
		us.popdt.event.add(this.gui.img,'load',this.onImageLoad);
		
		this.getImageSetData();
	},
	captureButtonClick: function() {
		if (this.id == gallery.gui.next.id) {
			gallery.getNextImage();
		} else if (this.id == gallery.gui.back.id) {
			gallery.getPreviousImage();
		}
	},
	onNavSelect: function() {
		gallery.state.isNewImageSet = true;
		gallery.getImageSetData();
	},

	// MAIN HOOKS: All display gets filtered through here
	getImageSetData: function(nGalleryID) {
		// if the gallery select nav exists (i.e. - this is the production detail page), get the gallery id from it's selected gallery
		if (this.gui.nav) {
			var nGalleryID = (typeof nGalleryID != 'undefined') ? nGalleryID : this.gui.nav[this.gui.nav.selectedIndex].value ;
		// if the gallery select nav doesn't exist (i.e. - this is the watch & listen gallery detail page), get the gallery id from the url
		} else {
			var i = window.location.search.indexOf("=")+1;
			var j = window.location.search.indexOf("&");
			if (j >= 0) {
				var nGalleryID = window.location.search.substring(i,j);
			} else {
				var nGalleryID = window.location.search.substring(i);
			}
		}
		var svc = '{0}/svc/production.asmx/GetImages?galleryID={1}'.format(us.popdt.config.ROOT_VIRTUAL,nGalleryID);
		if (this.xhr) {
			this.xhr.onreadystatechange = function() {}
			this.xhr.abort();
		}
		this.xhr.open("GET",svc);
		this.xhr.onreadystatechange = this.processImageSetData;
		this.xhr.send(null);
	},
	processImageSetData: function() { gallery.onProcessImageSetData(); },
	onProcessImageSetData: function() {
		if (this.xhr.readyState == 4) { // wait for readyState Success
			count = this.xhr.responseXML.getElementsByTagName('photo').length;
			switch (true) {
				case count==0:
					this.state.imageSet = false;
					break;
				default:
					this.state.imageSet = $x.evalJSON($x.xml2json(this.xhr.responseXML)).photoset.photo;
			}
			this.customEvents.fire('processImageSetData');
		}
	},
	installImageSet: function() {
		switch (true) {
			case (!this.state.imageSet): // no images in set
				this.errorNoImagesInSet();
				break;
			default:
				this.installImageGallery(); // more than one image
		}
	},
	
	installImageGallery: function() {
		this.state.currentImageIndex = 0;
		this.updateButtons();
		if (this.state.buildFromTabLoad == true) {
			this.updateImage();
			this.state.buildFromTabLoad = false;
		} else if (this.state.isNewImageSet == true) {
			this.getCurrentImage(true);
			this.state.isNewImageSet = false;
		}
	},

	updateButtons: function() {
		var cs = this.state.imageSet;
		var iIndex = this.state.currentImageIndex;
		if (typeof this.state.imageSet.length == 'undefined') {
			this.toggleNav(false);
			return;
		} else {
			this.toggleNav(true);
		}

		var nID = (iIndex == cs.length-1) ? cs[0]['@id'] : cs[iIndex+1]['@id'] ;
		var bID = (iIndex== 0) ? cs[cs.length-1]['@id'] : cs[iIndex-1]['@id'] ;
		this.gui.next.href = this.gui.next.href.addQueryParams({photoID:nID});
		this.gui.back.href = this.gui.back.href.addQueryParams({photoID:bID});
	},
	toggleNav: function(bOnOff) {
		this.gui.back.style.visibility = (bOnOff) ? 'visible' : 'hidden';
		this.gui.next.style.visibility = (bOnOff) ? 'visible' : 'hidden';
	},
	shiftCurrentIndex: function(sLeftRight) {
		var cs = this.state.imageSet;
		var iIndex = this.state.currentImageIndex;
		if(cs.length == 1) { return; }

		switch(true) {
			case (sLeftRight == 'right'):
				iIndex = (iIndex < cs.length-1) ? iIndex+1 : 0 ;
				break;
			case (sLeftRight == 'left'):
				iIndex = (iIndex > 0) ? iIndex-1 : cs.length-1 ;
				break;
		}

		this.state.currentImageIndex = iIndex;
		this.updateButtons();
	},
	
	getCurrentImage: function(isNewImage) {
		this.gui.loader.loadIn(isNewImage);
		this.updateImage();
	},
	getNextImage: function() {
		if (!this.gui.loader.gui.oFader.busy) {
			this.shiftCurrentIndex('right');
			this.gui.loader.loadIn();
		}
	},
	getPreviousImage: function() {
		if (!this.gui.loader.gui.oFader.busy) {
			this.shiftCurrentIndex('left');
			this.gui.loader.loadIn();
		}
	},
	updateImage: function() {
		if (typeof this.state.imageSet.length == 'undefined') {
			var oIMG = this.state.imageSet;
		} else {
			var oIMG = this.state.imageSet[this.state.currentImageIndex];
		}
		var src = us.popdt.config.ROOT_VIRTUAL + oIMG['@file'];
		// Keep image from caching in IE 6
		src += (us.popdt.client.browser == 'msie' && us.popdt.client.version.major == 6)
				? '?noCache=' + Math.random() : '' ;
		this.gui.img.src = src;
		this.gui.img.setAttribute('alt',oIMG.caption);
		//Safari caption fix
		if (oIMG.caption == null){
			oIMG.caption = "";
		}
		var caption = "<strong>"+oIMG.caption+"</strong>";
		if (oIMG.credit) {
			caption += '<br /><em>Credit: {0}</em>'.format(oIMG.credit);
		}
		this.gui.caption.innerHTML = caption;
	},
	onImageLoad: function() {
		gallery.gui.loader.loadOut();
	},
	
	errorNoImagesInSet: function() {
		// this should never happen
		// dbug.log('No images in requested set.');
	}
}
us.popdt.event.add(window, 'load', gallery.init);




var priceDisplay = {
	init: function() {
		// build when we're coming from the same page
		priceDisplay.build();
	},
	build: function() {
		this.selectNav = $dom.getById('template_ticketPanel_dd_Dates');
		var price_types = $dom.getById('price_types');
		
		if (!this.selectNav || !price_types) { return false; } // do not build if required elements not found

		us.popdt.event.add(this.selectNav,'change',priceDisplay.displayLoading);

		var price_labels = price_types.getElementsByTagName('label');
		this.fader_labels = [];
		this.faders = [];
		for (var i=0; i<price_labels.length; i++) {
			if ($dom.hasClass(price_labels[i],'pricetype_label')) {
				this.fader_labels.push(price_labels[i]);
				var fBGName = 'faderBG'+i;
				var fFGName = 'faderFG'+i;

				this[fBGName] = new us.popdt.fx.CSSColorFader(price_labels[i],'#D3C07C','#F3ECD9',1500,'background-color');
				this[fFGName] = new us.popdt.fx.CSSColorFader(price_labels[i],'#FFF','#555',1500,'color');
				this.faders.push([fBGName, this[fBGName], fFGName, this[fFGName]]);
				
				var referrerUrl = document.referrer.split('?')[0];
				var refProductionId = document.referrer.toQueryParams()['id'];
				
				var locationUrl = location.href.split('?')[0];
				var locationProductionId = location.href.toQueryParams()['id'];
				
				if (referrerUrl == locationUrl && refProductionId == locationProductionId) {
					this.fire();
				}
			}
		}
	},
	fire: function() {
		for (var i=0; i<this.faders.length; i++) {
			this.faders[i][1].animate('priceDisplay.'+this.faders[i][0]);
			this.faders[i][3].animate('priceDisplay.'+this.faders[i][2]);
		}
	},
	displayLoading: function() {
		priceDisplay.onDisplayLoading();
	},
	onDisplayLoading: function() {
		for (var i=0; i<this.fader_labels.length; i++) {
			$dom.addClass(this.fader_labels[i],'loading');
		}
	}
}
us.popdt.event.add(window,'load',priceDisplay.init);
