
var bc_ew_playButton = "http://img2.timeinc.net/ew/i/hbo/brightcove/bc_ew_playButton.gif";
var bc_ew_buyButton = "http://img2.timeinc.net/ew/i/hbo/brightcove/bc_ew_buyButton.gif";
var bc_ew_tabSelectedLeft = "http://img2.timeinc.net/ew/i/hbo/brightcove/bc_ew_tabSelectedLeft.gif";
var bc_ew_tabSelectedRight = "http://img2.timeinc.net/ew/i/hbo/brightcove/bc_ew_tabSelectedRight.gif";
var bc_ew_tabLeft = "http://img2.timeinc.net/ew/i/hbo/brightcove/bc_ew_tabLeft.gif";
var bc_ew_tabRight = "http://img2.timeinc.net/ew/i/hbo/brightcove/bc_ew_tabRight.gif";
var dvd_flight = "http://img2.timeinc.net/ew/i/hbo/brightcove/dvd_flight.jpg";
var main_promo = "http://img2.timeinc.net/ew/i/hbo/brightcove/main_promo.jpg";
var dvd_curb  = "http://img2.timeinc.net/ew/i/hbo/brightcove/dvd_curb.jpg";
var dvd_entouage  = "http://img2.timeinc.net/ew/i/hbo/brightcove/dvd_entouage.jpg";
var promo_curb =  "http://img2.timeinc.net/ew/i/hbo/brightcove/promo_curb.jpg";
var tvfan_curb = "http://img2.timeinc.net/ew/i/hbo/brightcove/tvfan_curb.gif";
var tvfan_generic = "http://img2.timeinc.net/ew/i/hbo/brightcove/tvfan_generic.gif";
var promo_entourage = "http://img2.timeinc.net/ew/i/hbo/brightcove/promo_entourage.jpg";
var tvfan_entourage = "http://img2.timeinc.net/ew/i/hbo/brightcove/tvfan_entourage.gif";
var dvd_extras = "http://img2.timeinc.net/ew/i/hbo/brightcove/dvd_extras.jpg";
var promo_extras = "http://img2.timeinc.net/ew/i/hbo/brightcove/promo_extras.jpg";
var tvfan_extras = "http://img2.timeinc.net/ew/i/hbo/brightcove/tvfan_extras.gif";
var promo_flight = "http://img2.timeinc.net/ew/i/hbo/brightcove/promo_flight.jpg";
var tvfan_flight = "http://img2.timeinc.net/ew/i/hbo/brightcove/tvfan_flight.gif";




var BrowserDetect = {
	init: function () {
		this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
		this.version = this.searchVersion(navigator.userAgent)
			|| this.searchVersion(navigator.appVersion)
			|| "an unknown version";
		this.OS = this.searchString(this.dataOS) || "an unknown OS";
	},
	searchString: function (data) {
		for (var i=0;i<data.length;i++)	{
			var dataString = data[i].string;
			var dataProp = data[i].prop;
			this.versionSearchString = data[i].versionSearch || data[i].identity;
			if (dataString) {
				if (dataString.indexOf(data[i].subString) != -1)
					return data[i].identity;
			}
			else if (dataProp)
				return data[i].identity;
		}
	},
	searchVersion: function (dataString) {
		var index = dataString.indexOf(this.versionSearchString);
		if (index == -1) return;
		return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
	},
	dataBrowser: [
		{ 	string: navigator.userAgent,
			subString: "OmniWeb",
			versionSearch: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			subString: "Apple",
			identity: "Safari"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			subString: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			subString: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			subString: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.vendor,
			subString: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			subString: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			subString: "MSIE",
			identity: "Explorer",
			versionSearch: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			subString: "Mozilla",
			identity: "Netscape",
			versionSearch: "Mozilla"
		}
	],
	dataOS : [
		{
			string: navigator.platform,
			subString: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			subString: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.platform,
			subString: "Linux",
			identity: "Linux"
		}
	]

};
BrowserDetect.init();




  /**
  * This file includes the functions necessary to create the html navigation of the TIME
  * player.  A quick overview of the flow is that after the brightcove video player has 
  * loaded we use the player as a gateway to communicate to brightcove's backend and get
  * the lineups.  The first lineup we get is the 'newest videos' lineup which appears at
  * the bottom of the page.  We get this first so that we determine which corresponding tab
  * in the nav we should link to.  After we get this lineup we then get the featured lineup
  * and then finally the rest of the lineups.
  *
  * The code is broken into 6 major sections.  
  * 1. Global variables and constants
  * 2. Functions that pertain to the communication with the brightcove backend.
  * 3. Functions that build the actual HTML with the information received from the server.
  * 4. Functions to handle the custom ad integration.
  * 5. Functions to handle UI events.
  * 6. Helper and utility functions used throughout the other functions.
  * 
  * @author Jesse Streb
  **/

/************************************************************************************
 * Global variables and constants
 ************************************************************************************/
var BC_PLAYER_ID = "1438502196";
var BC_NEWEST_LINEUP_ID = "1232409122";
var BC_ID_OF_BANNER_AD = "topBanner";

var bc_isIE = (navigator.appVersion.toLowerCase().indexOf('msie 6.0') != -1);
var bc_gCurrentTitleId = null;
var bc_gTotalWidth = 0;
var bc_gFirstLineUp = null;
var bc_gNumVids = 0;
var bc_gNumOfVidsReceived = 0;
var bc_gCount = 0;
var bc_gCurrentLineUpId = null;
var bc_gLineUpArray = new Array;
var bc_gCurrentSelectedTab = null;
var bc_gNewCurrentTab = null;
var bc_gBuildFeatured = true;
var bc_gFeaturedTitleCount = 0;
var bc_gNumFeatured = 0;
var bc_gFirstVideo = true;
var bc_gArgs = null;
var bc_gArgLineup = null;
var bc_gCurrentPlayingLineupId = null;
var bc_gUIExistsAlready = false;
var bc_gAdPlaying = false;
var bc_gTitleInfoArray = new Array();
var bc_gFeaturedTitles = new Array();

/*new variable to track if this is in the first tab*/
var bc_gFirstTabLinked = false;

/*The configuration for the brightcove player.  To reuse this template you would have to replace the playerId.*/
var config = new Array();
config["videoId"] = null; //the default video loaded into the player
config["videoRef"] = null; //the default video loaded into the player by ref id specified in console
config["lineupId"] = null; //the default lineup loaded into the player
config["playerTag"] = null; //player tag used for identifying this page in brightcove reporting
config["autoStart"] = false; //tells the player to start playing video on load
config["preloadBackColor"] = "#FFFFFF"; //background color while loading the player
config["width"] = 486;
config["height"] = 412;
config["playerId"] = BC_PLAYER_ID;
//config["adServerURL"] = "http://saluteyourshorts.net/brightcove/sandbox/Dev%20Forums/Ad%20Class%2001/ad_xml_test_02.xml?";
config["externalAds"]= true;

/************************************************************************************
 * Below methods deal with the communication between the Brightcove server and the 
 * dynamic construction of the UI.
 ************************************************************************************/

/**
 * onTemplateLoaded is the entry point for building our nav.  Once this is loaded we register our
 * eventListeners that we need in our javascript.
 * 
 * @param message If there was an error this is passed in here.
 */
function onTemplateLoaded(message) {
	document.getElementById('bc_newestText').innerHTML = "Most Popular Videos";
	document.getElementById('bc_newestFromText').style.left = "197px";
	bc_gArgs = bc_getArgs();
	callFlash("enableAdFormats", 14, 15, 6, 2);
	callFlash("addEventListener", "contentLoad", "bc_onContentLoad");
	callFlash("addEventListener", "mediaStart", "bc_onMediaStart");
	//callFlash("addEventListener", "mediaComplete", "bc_mediaComplete");
	callFlash("addEventListener", "adComplete", "bc_adComplete");
}

/**
 * Once the content has been loaded this is fired.  We registered this event handler in onTemplateLoaded.
 * After we have the content we need to first get the lineup that contains the newest videos so that we
 * can get the corresponding videos.
 * @param {Object} evt
 */
function bc_onContentLoad(evt) {
	//If the user hit back on their browser then we do not need to rebuild the UI, but we need to fetch each title so that they can play.  
	if(bc_gCurrentSelectedTab == null) {
		bc_gBuildFeatured = false;
		callFlash("getPlayerLineups");
	} else {
		bc_gUIExistsAlready = true;
		callFlash("getPlayerLineups");
	}
}

/**
 * This is the callback for the above call.  This gives us the lineUpDTO for the 'newest videos', the highlighted videos at the bottom of the
 * page.  Here we pre-populate our associate array so that we can populate it later with the corresponding information.
 * 
 * @param {Object} pLineupDTO
 */
function fetchLineupById_Result(pLineupDTO) {
	//Track how many featured titles there are so that we know when have created all of the featured titles in the nav.
	bc_gNumFeatured= (pLineupDTO.videoIds.length > 6) ? 6 : pLineupDTO.videoIds.length;
	for(var i = 0; i < bc_gNumFeatured; i++) {
		bc_gFeaturedTitles[pLineupDTO.videoIds[i]] = true;
		callFlash("fetchTitleById", pLineupDTO.videoIds[i]);
	}
}

/**
 * A callback for fetchTitleById which is called for each title that is not in the first lineup.
 * Here you can see the code forks depending on whether or not we are building the featured area 
 * in the bottom or one of lineups under one of the tabs. 
 * 
 * @param {Object} titleDTO - An object that contains all the necessary information for this title.
 */
function fetchTitleById_Result(pTitleDTO) {
	//If we have already built the UI then we do not need to do anything.
	if(!bc_gUIExistsAlready) {
		//If there was error getting the title then we need to skip this title.
		if(pTitleDTO != null) {
			//If the user is deep linking and this is the featured video we can update and show the copy.
			if(bc_gArgs != null && pTitleDTO.id + "" == bc_gArgs.bctid + "") {
				bc_gArgLineup = bc_gCurrentLineUpId;
				bc_gFirstVideo = false;
				document.getElementById('bc_currentTitle').innerHTML = pTitleDTO.displayName;
				document.getElementById('bc_currentTitleDesc').innerHTML = pTitleDTO.shortDescription;
				
				document.getElementById('bc_currentTitleDesc').style.height= "54px";	
				document.getElementById('bc_currentTitleText').style.display = "block";
			}
			
			//This is where we fork the construction in the UI based on whether or not this is for the featured area.
			(bc_gBuildFeatured) ? bc_buildFeaturedVideos(pTitleDTO) : bc_buildVideoContainer(pTitleDTO);
		} else {
			bc_gNumOfVidsReceived++;
		}
	}
}

/**
 * This is the callback for the call to BC server to get the lineup that is loaded into the player.  Here we build the top Nav and also 
 * make the call to get the title for first lineup.  We do not make the call to get all of them since we need to know which lineup to 
 * associate the title with.
 * @param {Object} pLineupArray - An array of lineupDTOs
 */
function getPlayerLineups_Result(pLineupArray) {
	//If the UI already exists we do not want to rebuild it but just fetch each title so that we can play them back.
	if(!bc_gUIExistsAlready) {
		var lineup = null;
	
		bc_gFirstLineUp = pLineupArray[0].id + "";
		bc_gCurrentLineUpId = pLineupArray[0].id;
		bc_gCurrentPlayingLineupId = pLineupArray[0].id;
		bc_gCurrentSelectedTab = pLineupArray[0].id;
	
		//For some reason I am getting lineups that don't exists so I need to create a lineup array that is correct.
		for(var i=0; i<pLineupArray.length; i++) {
			bc_gLineUpArray[i] = pLineupArray[i];
			if(bc_gLineUpArray[i].referenceId + "" === "featured_bottom")
				break;
		}
	
		for(i=0; i<bc_gLineUpArray.length; i++) {
			lineup = bc_gLineUpArray[i];
			bc_createLineupTab(lineup.displayName, lineup.id, lineup.referenceId);
			//If this is the first lineup then we want to get the videos.
			if(i === 0) {
				bc_gNumVids = lineup.videoIds.length;
				for(var j=0; j < lineup.videoIds.length; j++) {
					bc_isFeatured(lineup.videoIds[j], lineup.id, lineup.displayName);
					//If a specific video was not passed in then we have already loaded the titles so we can call get which is faster.
					if(bc_gArgs == null || bc_gArgs.bctid == null) {
						callFlash("getTitleById", lineup.videoIds[j]);
					} else {
						//Need to call fetch since the lineup that has been loaded is about to be different.
						callFlash("fetchTitleById", lineup.videoIds[j]);
						if(bc_gArgs.bctid == lineup.videoIds[j]) {
							bc_gFirstTabLinked = true;	
						}
					}
				}
			}
		}
	
		//after we have created all of the tabs then we should make it flush on the right.
		document.getElementById('bc_innerTabContainer').style.left = (974 - bc_gTotalWidth) + "px";
		document.getElementById('brightcovePlayerContainer').style.fontWeight = "normal";
		if(bc_gArgs == null || bc_gArgs.bctid == null) {
			document.getElementById('bc_innerTabContainer').style.display = "block";
		}
		
			// dan's ew code
			
			document.getElementById("1453556817_tabNormal").onmousedown = function() {
				document.getElementById("show-buy").src = dvd_flight;
				
				//document.getElementById("show-buy").parentNode.setAttribute( "href" , "foo1" );
				document.getElementById("show-promo").src = main_promo;
				document.getElementById("show-promo").parentNode.setAttribute( "href" , "http://www.hbo.com/" );
				document.getElementById("tvfan-flip").src = tvfan_generic;
				document.getElementById("tvfan-flip").parentNode.setAttribute( "href" , "http://tvfan.ew.com/" );
				//document.getElementById("rss-flip").src = "";
				//document.getElementById("rss-flip").parentNode.setAttribute( "href" , "" );
				document.getElementById("hbo-poll").src = "http://www.ew.com/ew/video/hbo/mainpoll";
				document.getElementById("video_copy_r").innerHTML = "&#169;2008 Home Box Office, Inc. All Rights Reserved. HBO&reg; and Home Box Office&reg; are service marks of Home Box Office, Inc.";
			};
			document.getElementById("1454954152_tabNormal").onmousedown = function() {
			
				document.getElementById("show-buy").src = dvd_curb;
				//document.getElementById("show-buy").parentNode.setAttribute( "href" , "foo1" );
				document.getElementById("show-promo").src = promo_curb;
				document.getElementById("show-promo").parentNode.setAttribute( "href" , "http://www.hbo.com/larrydavid/" );
				document.getElementById("tvfan-flip").src = tvfan_curb;
				document.getElementById("tvfan-flip").parentNode.setAttribute( "href" , "http://tvfan.ew.com/shows/Curb+Your+Enthusiasm" );
				//document.getElementById("rss-flip").src = "";
				document.getElementById("hbo-poll").src = "http://www.ew.com/ew/video/hbo/curbpoll";
				document.getElementById("video_copy_r").innerHTML = "&#169;2008 Home Box Office, Inc. All Rights Reserved. HBO&reg;, Home Box Office&reg; and Curb Your Enthusiasm&reg; are service marks of Home Box Office, Inc.";
			};
			document.getElementById("1452258093_tabNormal").onmousedown = function() {
			
				document.getElementById("show-buy").src = dvd_entouage;
				//document.getElementById("show-buy").parentNode.setAttribute( "href" , "foo1" );
				document.getElementById("show-promo").src = promo_entourage;
				document.getElementById("show-promo").parentNode.setAttribute( "href" , "http://www.hbo.com/entourage/" );
				document.getElementById("tvfan-flip").src = tvfan_entourage;
				document.getElementById("tvfan-flip").parentNode.setAttribute( "href" , "http://tvfan.ew.com/shows/Entourage" );
				//document.getElementById("rss-flip").src = "";
				document.getElementById("hbo-poll").src = "http://www.ew.com/ew/video/hbo/entouragepoll";
				document.getElementById("video_copy_r").innerHTML = "&#169;2008 Home Box Office, Inc. All Rights Reserved. HBO&reg;, Home Box Office&reg; and Entourage SM are service marks of Home Box Office, Inc.";
			};
			document.getElementById("1452258115_tabNormal").onmousedown = function() {
			
				document.getElementById("show-buy").src = dvd_extras;
				//document.getElementById("show-buy").parentNode.setAttribute( "href" , "foo1" );
				document.getElementById("show-promo").src = promo_extras;
				document.getElementById("show-promo").parentNode.setAttribute( "href" , "http://www.hbo.com/extras/" );
				document.getElementById("tvfan-flip").src = tvfan_extras;
				document.getElementById("tvfan-flip").parentNode.setAttribute( "href" , "http://tvfan.ew.com/shows/Extras" );
				//document.getElementById("rss-flip").src = "";
				document.getElementById("hbo-poll").src = "http://www.ew.com/ew/video/hbo/extraspoll";
				document.getElementById("video_copy_r").innerHTML = "&#169;2008 Home Box Office, Inc. All Rights Reserved. HBO&reg;, Home Box Office&reg; and Extras SM are service marks of Home Box Office, Inc.";
			};
			document.getElementById("1453536058_tabNormal").onmousedown = function() {
			
				document.getElementById("show-buy").src = dvd_flight;
				//document.getElementById("show-buy").parentNode.setAttribute( "href" , "foo1" );
				document.getElementById("show-promo").src = promo_flight;
				document.getElementById("show-promo").parentNode.setAttribute( "href" , "http://www.hbo.com/conchords/" );
				document.getElementById("tvfan-flip").src = tvfan_flight;
				document.getElementById("tvfan-flip").parentNode.setAttribute( "href" , "http://tvfan.ew.com/shows/Flight+of+the+Conchords" );
				//document.getElementById("rss-flip").src = "";
				document.getElementById("hbo-poll").src = "http://www.ew.com/ew/video/hbo/flightpoll";
				document.getElementById("video_copy_r").innerHTML = "&#169;2008 Home Box Office, Inc. All Rights Reserved. HBO&reg; and Home Box Office&reg; are service marks of Home Box Office, Inc. Flight of the Conchords SM service mark and trademarks are used by Home Box Office, Inc. under license.";
			};
			
			
			//
		
	} else {
		for(i=1; i<bc_gLineUpArray.length; i++) {
			for(var j=0; j < bc_gLineUpArray[i].videoIds.length; j++) {
				//Need to call fetch since the lineup that has been loaded is about to be different.
				callFlash("fetchTitleById", bc_gLineUpArray[i].videoIds[j]);	
			}
		}
	}
}

/**
 * Once we have gotten all the videos for a given lineup and added them to the page we can then
 * get the next lineup in our list.
 */
function bc_getNextLineup() {
	bc_gCount++;
	if(bc_gCount < (bc_gLineUpArray.length)) {
		bc_gCurrentLineUpId = bc_gLineUpArray[bc_gCount].id;
		bc_gNumVids = bc_gLineUpArray[bc_gCount].videoIds.length;
		for(var i=0; i < bc_gLineUpArray[bc_gCount].videoIds.length; i++) {
			bc_isFeatured(bc_gLineUpArray[bc_gCount].videoIds[i], bc_gLineUpArray[bc_gCount].id, bc_gLineUpArray[bc_gCount].displayName);
			callFlash("fetchTitleById", bc_gLineUpArray[bc_gCount].videoIds[i]);
		}
	} else {
		//If we are deep linking and we have found the correct tab we can show the tab container.
		if(bc_gArgLineup != null) {
			bc_showLineUp(bc_gArgLineup);
			bc_gCurrentPlayingLineupId = bc_gArgLineup;
			document.getElementById('bc_innerTabContainer').style.display = "block";
			callFlash("getCurrentTitle");
		} else { //Something go screw up so we should show the current playing movie.
			document.getElementById('bc_currentTitleText').style.display = "block";
			document.getElementById(bc_gFirstLineUp).style.display = "block";
			bc_showLineUp(bc_gFirstLineUp);
			bc_gCurrentPlayingLineupId = bc_gFirstLineUp;
			document.getElementById('bc_innerTabContainer').style.display = "block";
			callFlash("getCurrentTitle");
		}
		
		//now that we have gotten all of the titles we can now correctly build the featured area below.
		bc_gBuildFeatured = true;
		for(var i in bc_gFeaturedTitles) {
			bc_updateFeaturedVideos(i);
		}
	}
}

/**
 * A callback for fetchTitleById which provides with the titleDTO so that we can finally build
 * out our navigation for the player.
 * 
 * @param {Object} titleDTO - An object that contains all the necessary information for this title.
 */
function getTitleById_Result(pTitleDTO) {
	//I should never get null back but if there are special characters in the description this returns null.  So I handle this case.
	if(pTitleDTO != null) {
		if(bc_gFirstVideo && (bc_gArgs == null || bc_gArgs.bctid == null)) {
			bc_gFirstVideo = false;
			
			document.getElementById('bc_currentTitle').innerHTML = pTitleDTO.displayName;
			document.getElementById('bc_currentTitleDesc').innerHTML = pTitleDTO.shortDescription;
			
			document.getElementById('bc_currentTitleDesc').style.height= "54px";
			document.getElementById('bc_currentTitleText').style.display = "block";
		}
	
		bc_buildVideoContainer(pTitleDTO);
	} else {
		bc_gNumOfVidsReceived++;
	}
}

/**
 * Called when a new video starts playing which allows us to update the UI with
 * the now playing title.  However, we still need to find out what the current title
 * is so we make a call to the player to find this out.
 * 
 */
function bc_onMediaStart(pObj) {
	callFlash("getCurrentTitle");	
}

/**
 * The callback for the above request to get the current Title, this gives us our
 * id which allows us to see if it is a new title.  If it is then we want to make
 * the old one the white, then set color of the title orange for this one.  We are 
 * able to get the element because when we created these elements we used the titleID
 * as part of our naming convention.
 * 
 * @param {Object} titleDTO - the titleDTO which provides the id of this title.
 */
function getCurrentTitle_Result(pTitleDTO) {
	if(pTitleDTO.id != bc_gCurrentTitleId && bc_gCurrentTitleId != null) {
		document.getElementById('bc_playingDiv_' + bc_gCurrentTitleId  + '_' + bc_gCurrentPlayingLineupId).style.zIndex = -3;
		document.getElementById('bc_vidCont_' + bc_gCurrentTitleId  + '_' + bc_gCurrentPlayingLineupId).className = "bc_videoContainerFade";
	}
	
	if(bc_gNewCurrentTab != null) {
		document.getElementById('bc_playingDiv_' + pTitleDTO.id + '_' + bc_gNewCurrentTab).style.zIndex = 98;
		document.getElementById('bc_vidCont_' + pTitleDTO.id  + '_' + bc_gNewCurrentTab).className = "bc_videoContainer";
		bc_gCurrentPlayingLineupId = bc_gNewCurrentTab; 
	} else {
		document.getElementById('bc_playingDiv_' + pTitleDTO.id + '_' + bc_gCurrentPlayingLineupId).style.zIndex = 98;
		document.getElementById('bc_vidCont_' + pTitleDTO.id  + '_' + bc_gCurrentPlayingLineupId).className = "bc_videoContainer";
	}
	
	bc_gCurrentTitleId = pTitleDTO.id;
	bc_scrollTo();
}

/**
 * The callback for the event listener we registered at the top for when video has completed
 * We use this event to enable continous play.  Once this has fired we check the current title id
 * and compare it to our array we created when we created the navigation and then play the next
 * title.
 * 
 * @param {Object} pObj
 */
function bc_mediaComplete(pObj) {
	var lineupDTO = bc_getCurrentLineUpDTO();
	for(var i=0; i < lineupDTO.videoIds.length; i++) {
		if(lineupDTO.videoIds[i] + "" == bc_gCurrentTitleId + "") {
			bc_playTitle(lineupDTO.videoIds[++i], null);
			return;
		}
	}
}

/****************************************************************************************************
 * The below functions actually build the UI elements on the page.
 ****************************************************************************************************/
/**
 * This will create the tab for this lineup.
 * @param {Object} pName - The name of the lineup which will appear on the tab.
 * @param {Object} pId - This is the unique id of this lineup which we will use as IDs for the html elements.
 */
function bc_createLineupTab(pName, pId, pFeatured) {
	var tabWidth = bc_getWidth(pName) - 10;
	
	//create the normal tab
	var tab = document.createElement('div');
	tab.id = pId + "_tabNormal";
	
	tab.className = "bc_tab";
	tab.style.width = tabWidth + "px";
	tab.style.left = bc_gTotalWidth + "px";
	tab.onclick = function () {bc_showLineUp(pId);}
	tab.onmouseover = function () {bc_tabRollover(pId, (pFeatured == "featured") ? true : false);}
	tab.onmouseout = function () {bc_tabRollout(pId);}
	tab.innerHTML = "<div class='bc_tabLeft'><img src='" + bc_ew_tabLeft + "'/></div><div id='bc_tabText" + pId + "' class='bc_tabText'>" + pName 
	+ "</div><div class='bc_tabRight'><img src='" + bc_ew_tabRight + "'/></div>";
	
	document.getElementById('bc_innerTabContainer').appendChild(tab);
	//set the first tab as active.
	if(pId == bc_gCurrentSelectedTab) {
		tab.style.display = "none";
	}
	
	//create the selected tab
	tab = document.createElement('div');
	tab.id = pId + "_tabSelected";
	tab.className = "bc_selectedTab";
	tab.style.width = tabWidth + "px";
	tab.style.left = bc_gTotalWidth + "px";
	tab.innerHTML = "<div class='bc_tabLeft'><img src='" + bc_ew_tabSelectedLeft + "'/></div><div class='bc_tabText'>" + pName 
	+ "</div><div class='bc_tabRight'><img src='" + bc_ew_tabSelectedRight + "'/></div>";
	document.getElementById('bc_innerTabContainer').appendChild(tab);
	//set the first tab as active.
	if(pId == bc_gCurrentSelectedTab) {
		tab.style.display = "block";
	}
	
	//2 is for padding between tabs
	bc_gTotalWidth = bc_gTotalWidth + tabWidth + 14;
}

/**
 * This will build the featured video area at the bottom.  Since we do not yet know which lineups these titles link to we will make another pass
 * later to update these elements with the correct links.
 * @param {Object} pTitleDTO - The title DTO which contains the necessary information.
 */
function bc_buildFeaturedVideos(pTitleDTO) {
	var div = document.createElement('div');
	if(bc_gFeaturedTitleCount === 0) {
		div.className = 'bc_newLeftVideo';
	} else if (bc_gFeaturedTitleCount === 5) {
		div.className = 'bc_newRightVideo';
		if(bc_gArgs == null || bc_gArgs.bctid == null) {
			document.getElementById('bc_newestVideos').style.display = "block";
		}
	} else {
		div.className = 'bc_newVideo';
	}
	
	//162 is the width of the containers.
	div.style.left = (bc_gFeaturedTitleCount * 162) + "px";
	div.innerHTML = "<div id='bc_featuredThumb_" + pTitleDTO.id + "' class='bc_featuredThumbContainer'><img class='bc_featuredThumbnail' src='" + pTitleDTO.thumbnailURL 
	+ "'/></div><div class='bc_featuredTitleText'><div id='bc_catName_" + pTitleDTO.id + "' class='bc_featuredCategory'></div><div id='bc_featTitle_" + 
	pTitleDTO.id + "' class='bc_featuredTitle'><a href='javascript:bc_cssLink()'>" 
	+ pTitleDTO.displayName + "</a></div></div>";
	document.getElementById('bc_featuredVideoContainer').appendChild(div);
	bc_gFeaturedTitleCount++;
	
	//If we have gotten all of the featured videos then we can get the first lineup.
	if(bc_gNumFeatured == bc_gFeaturedTitleCount) {
		bc_gBuildFeatured = false;
		callFlash("getPlayerLineups");
	}
}

function bc_cssLink() {
	
}

/**
 * This is where we actually create html navigation elements.
 * @param {Object} pTitleDTO - The titleDTO object for this element.
 */
function bc_buildVideoContainer(pTitleDTO) {
	var firstVideo = false;
	//We do not want null showing up for a related link so if it is null we set it to empty strings.
	if(pTitleDTO.linkURL != null) {
		var linkUrl = pTitleDTO.linkURL;
		var linkText = (pTitleDTO.linkText != null) ? pTitleDTO.linkText : "";
	} else {
		var linkUrl = "";
		var linkText = "";
	}
	
	/*
	 * We need to keep the title information so that when the video is playing we can display this.  Instead of storing the entire 
	 * titleDTO I create a new object.
	 */
	var obj = new Object();
	obj.title = pTitleDTO.displayName;
	obj.desc = pTitleDTO.shortDescription;
	obj.linkUrl = linkUrl;
	obj.linkText = linkText;
	bc_gTitleInfoArray[pTitleDTO.id] = obj
	
	var bc_lineUpContainer = document.getElementById(bc_gCurrentLineUpId);
	if(bc_lineUpContainer == null) {
		firstVideo = true;
		var bc_lineUpContainer = document.createElement('div');
		bc_lineUpContainer.id = bc_gCurrentLineUpId;
		bc_lineUpContainer.className = "bc_lineUpDivContainer";
		if(bc_gCurrentLineUpId == bc_gFirstLineUp  && ((bc_gArgs == null || bc_gArgs.bctid == null)||(bc_gFirstTabLinked))) {
			bc_lineUpContainer.style.display = "block";
		}
		document.getElementById('brightcovePlayerContainer').appendChild(bc_lineUpContainer);
	}
	
	var div = document.createElement('div');
	div.id = "bc_vidCont_" + pTitleDTO.id + "_" + bc_gCurrentLineUpId;
	div.className = 'bc_videoContainerFade';
	
	//If there are less then 6 videos then there will be no scroll bar.
	if(bc_gNumVids <= 5) {
		div.style.width = "455px";
	} else if(BrowserDetect.browser + "" == "Firefox" && BrowserDetect.version < 2) {
		div.style.width = "436px";
	} else if(BrowserDetect.OS == "Mac") {
		div.style.width = "440px";
	}
	
	var shortDesc = pTitleDTO.shortDescription;
	if(shortDesc.length > 160) {
		shortDesc = shortDesc.substring(0, 157) + "...";
	}
	
	//Put in the rollover states.
	div.onmouseover = function () {this.className = "bc_videoContainer";}
	div.onmouseout = function () {if(this.id != "bc_vidCont_" + bc_gCurrentTitleId  + "_" + bc_gCurrentPlayingLineupId) {this.className = "bc_videoContainerFade";}}
	
	
	div.innerHTML = "<div id='bc_thumb_" + pTitleDTO.id + "_" + bc_gCurrentLineUpId + "' class='bc_thumbContainer' onclick='bc_playTitle(" 
	+ pTitleDTO.id + ", " + bc_gCurrentLineUpId + ")'><img class='bc_thumbnail' src='" + pTitleDTO.thumbnailURL 
	+ "'/></div><div class='" + bc_getClassName() + "' id='bc_playingDiv_" + pTitleDTO.id + "_" + bc_gCurrentLineUpId 
	+ "'></div><div class='bc_textArea'><div id='bc_title_" + pTitleDTO.id + "_" + bc_gCurrentLineUpId 
	+ "' class='bc_videoTitle'><a href='javascript:bc_playTitle(" + pTitleDTO.id + ", " + bc_gCurrentLineUpId + ")'>" + pTitleDTO.displayName 
	+ "</a></div><div class='bc_videoDesc'>" + shortDesc + "</div></div><div class='bc_videoPlay' onclick='bc_playTitle(" + pTitleDTO.id + ", " 
	+ bc_gCurrentLineUpId + ")'><img id='bc_play_" + pTitleDTO.id + "_" + bc_gCurrentLineUpId + "'src='" + bc_ew_playButton + "'/></div>" + 
	"<div class='bc_relatedLink'><a href='" + linkUrl + "' target='_blank'><img src='" + bc_ew_buyButton + "' border=0/></a></div>";
	
	
	bc_lineUpContainer.appendChild(div);
	
	//determine if we have finished this lineup, if we have try to get next lineup.
	bc_gNumOfVidsReceived++;
	if(bc_gNumOfVidsReceived == bc_gNumVids) {
		div.style.borderStyle = "none";
		bc_gNumOfVidsReceived = 0;
		bc_getNextLineup();
	}
}

/**
 * Once we have finished making the UI we need to update the featured area with the corresponding lineup and title so that the user can click them.
 * @param {Object} pId
 */
function bc_updateFeaturedVideos(pId) {
	document.getElementById('bc_featuredThumb_' + pId).onclick = function () {bc_playTitle(pId, bc_gFeaturedTitles[pId].lineupId);}
	document.getElementById('bc_featTitle_' + pId).onclick = function () {bc_playTitle(pId, bc_gFeaturedTitles[pId].lineupId);}
	document.getElementById('bc_catName_' + pId).innerHTML = bc_gFeaturedTitles[pId].lineupName.toUpperCase();
	document.getElementById('bc_newestVideos').style.display = "block";
}

/****************************************************************************************************
 * The below functions deal with the interaction with UI
 ****************************************************************************************************/

/**
 * A function that tells the player to play the specified video.
 * @param {Object} titleId - Id of the title.
 * @param {Object} lineup - id of the lineup (optional with one lineup)
 */
function bc_playTitle(pTitleId, pLineupId) {
	if(!bc_gAdPlaying) {
		document.getElementById('bc_currentTitle').innerHTML = bc_gTitleInfoArray[pTitleId].title;
		document.getElementById('bc_currentTitleDesc').innerHTML = bc_gTitleInfoArray[pTitleId].desc;
	
		if(pLineupId != null) {
			bc_gNewCurrentTab = pLineupId;
			bc_showLineUp(pLineupId);
		} else {
			bc_gNewCurrentTab = null;
		}
		callFlash("loadTitleById", pTitleId, "full");
	}
}

/**
 * Handles the switching the tabs within the HTML navigation.
 * @param {Object} pId - The id of this lineup.  Each HTML nav has an id that uses the unique id.
 */
function bc_showLineUp(pId) {
	//If this tab is already selected or this UI has not been built yet do not allow the user to switch to it.
	if(pId != bc_gCurrentSelectedTab && document.getElementById(pId) != null) {
		document.getElementById("bc_tabText" + pId).className = "bc_tabText";
		document.getElementById(pId + "_tabNormal").style.display = "none";
		document.getElementById(pId + "_tabSelected").style.display = "block";
		
		document.getElementById(bc_gCurrentSelectedTab + "_tabSelected").style.display = "none";
		document.getElementById(bc_gCurrentSelectedTab + "_tabNormal").style.display = "block";
		
		document.getElementById(bc_gCurrentSelectedTab).style.display = "none";
		document.getElementById(pId).style.display = "block";
		bc_gCurrentSelectedTab = pId;
	}
	
}

function bc_tabRollover(pId, pIsFeatured) {
	if(pId != bc_gCurrentSelectedTab && document.getElementById(pId) != null) {
		document.getElementById("bc_tabText" + pId).className = (pIsFeatured) ? "bc_tabTextFeaturedOver" :"bc_tabTextOver";
	}
}

function bc_tabRollout(pId) {
	if(pId != bc_gCurrentSelectedTab && document.getElementById(pId) != null) {
		document.getElementById("bc_tabText" + pId).className = "bc_tabText";
	}
}

/****************************************************************************************************
 * The below functions deal with the custom AD integration for TIME
 ****************************************************************************************************/

/**
 * This function is called by the player because it does not know what to do with the XML it was passed by the
 * ad server.  In this funciton we parse the xml, populate the 300x250 ad, the banner ad and the create a new
 * ad object to pass back to the player so that it will play the ad.
 *   
 * @param {Object} pXML - The xml we received from doubleclick for this ad.
 */
function playAd(pXML) {
	try {
		pXML = bc_replaceChars(pXML, "&", "%26");
		bc_gAdPlaying = true;
		if (window.ActiveXObject) {
			//parses the XML for IE browsers
			var adXML = new ActiveXObject("Microsoft.XMLDOM");
			adXML.async = false;
			adXML.loadXML(pXML);
		} else if (window.XMLHttpRequest) {
			//parses the XML for Mozilla browsers
			var adXML = (new DOMParser()).parseFromString(pXML, "text/xml"); 
		}
	
		var ad = new Object();
	
		var nodeItems = adXML.firstChild.childNodes.length; //the number of items in the XML
		var currentNode = adXML.firstChild.firstChild; //sets the first node in the XML as the current node
		
		//checks to see the duration was set and sets the variable
		if(adXML.firstChild.getAttribute("duration") !== "") ad.duration = adXML.firstChild.getAttribute("duration");
		if(adXML.firstChild.getAttribute("trackStartURLs") !== "") ad.trackStartURLs = adXML.firstChild.getAttribute("trackStartURLs");

		for(var i = 0; i < nodeItems; i++) {
			//checks to see if the current nodes are in our Rich Media Templates and assigns them if they exist
			if(currentNode.nodeName == "videoURL") 
				ad.videoURL = currentNode.firstChild.nodeValue; 
			
			if(currentNode.nodeName == "videoClickURL") 
				ad.videoClickURL = currentNode.firstChild.nodeValue;
				
			if(currentNode.nodeName == "expandedBannerURL")	
				ad.expandedBannerURL = currentNode.firstChild.nodeValue;
				
			if(currentNode.nodeName == "expandedBannerClickURL") 
				ad.expandedBannerClickURL = currentNode.firstChild.nodeValue;
				
			if(currentNode.nodeName == "collapsedBannerURL") 
				ad.collapsedBannerURL = currentNode.firstChild.nodeValue;
			
			if(currentNode.nodeName == "collapsedBannerClickURL") 
				ad.collapsedBannerClickURL = currentNode.firstChild.nodeValue;
		
			//move to the next node for the next pass of the loop
			currentNode = currentNode.nextSibling; 
		}
		//Call function to show 300x250 ad.
		bc_show300Ad(ad.expandedBannerURL, ad.expandedBannerClickURL);
		
		//call funciton to show the banner ad.
		bc_updateBannerAd(ad.collapsedBannerURL, ad.collapsedBannerClickURL);
		
		//force it to be of type "video ad", a type the single title can understand.
		ad.type = "videoAd"; 
		callFlash("playAd", ad);
		
		//We don't want the playing state still set for a title so if it is in that state we hide it.
		if(bc_gCurrentTitleId != null) {
			document.getElementById('bc_title_' + bc_gCurrentTitleId + '_' + bc_gCurrentPlayingLineupId).style.color = "#093B6C";
			document.getElementById('bc_play_' + bc_gCurrentTitleId + '_' + bc_gCurrentPlayingLineupId).src = bc_ew_playButton;
			document.getElementById('bc_playingDiv_' + bc_gCurrentTitleId  + '_' + bc_gCurrentPlayingLineupId).style.zIndex = -3;  
		}
	} catch (e) {
		callFlash("endExternalAd");
		bc_adComplete();
	}
}

/**
 * Helper function to replace a character in a string with another character.
 * @param {Object} pString - String soure.
 * @param {Object} pOut - character that will replace the pAdd character.
 * @param {Object} pAdd - character that will be replaced by the pOut character.
 */
function bc_replaceChars(pString, pOut, pAdd) {
	while (pString.indexOf(pOut)>-1) {
		var pos= pString.indexOf(pOut);
		pString = "" + (pString.substring(0, pos) + pAdd + pString.substring((pos + pOut.length), pString.length));
	}
	return pString;
}

/**
 * The callback for the event we registered onTemplateLoad to alert us when an ad has completed.  It is here
 * that we tear down the AD overlay and if it is on a mac then we also show the scrollbar again.
 * @param {Object} evt
 */
function bc_adComplete(evt) {
	bc_gAdPlaying = false;
	//I used zIndex instead of display:none because you cannot change element styles crossbrowser when an object is not displayed at all
	document.getElementById('bc_adOverlay').style.zIndex = -1;
	document.getElementById('bc_adContainer').style.zIndex = -1;
	document.getElementById('bc_adContainer').innerHTML = "";
	
	//On a Mac the scrollbars are not covered up by the overlay so we simply hide the scrollbars.  here we show them again.
	if(BrowserDetect.OS == "Mac") {
		for(var i=0; i < bc_gLineUpArray.length -1; i++) {
			try {
				document.getElementById(bc_gLineUpArray[i].id).style.overflow = "auto";
			} catch (e) {
				//gulp
			}
		}
	}
}

/**
 * This funciton will put the ad overlay over the nav and play the ad in that area.
 * 
 * @param {Object} pAdUrl - The url to the ad image or swf for this ad.
 * @param {Object} pClickUrl - The url that the user should be taken to if they click on this.
 */
function bc_show300Ad(pAdUrl, pClickUrl) {
	//If the user is on a Mac then we want hide the scrollbars since they appear over the overlay.
	if(BrowserDetect.OS == "Mac") {
		for(var i=0; i < bc_gLineUpArray.length -1; i++) {
			try {
				document.getElementById(bc_gLineUpArray[i].id).style.overflow = "hidden";
			} catch (e) {
				//gulp
			}
			
		}
	}
	
	/*I used zIndex because setting the innerHTML of element that is not yet displayed causes problem crossbrowser issues*/
	document.getElementById('bc_adOverlay').style.zIndex = 99;
	document.getElementById('bc_adContainer').style.zIndex = 100;
	
	var expandedBanner = document.getElementById("bc_adContainer");
	if(pAdUrl.substr((pAdUrl.length -3), 3) == "swf") {
		var objectTag = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="300" height="250" id="expandedBanner" align="middle">';
		objectTag += '<param name="allowScriptAccess" value="always" />';
		objectTag += '<param name="movie" value="' + pAdUrl + '" />';
		objectTag += '<param name="quality" value="high" />';
		objectTag += '<param name="bgcolor" value="#ffffff" />';
		objectTag += '<param name="FlashVars" value="clickTag=' + pClickUrl + '" />';
		objectTag += '<embed src="' + pAdUrl + '" quality="high" bgcolor="#ffffff" width="300" height="250" name="expandedBanner" align="middle" allowScriptAccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" FlashVars="clickTag=' + pClickUrl + '" />';
		objectTag += '</object>';
		expandedBanner.innerHTML = objectTag; //writes out the object tag we just built to the expandedBanner div
	} else {
		expandedBanner.innerHTML = "<a href='" + pClickUrl + "' target='_blank' ><img src='" + pAdUrl + "' /></a>"; //writes out the regular anchor/tag to the expandedBanner div
	}
}

/**
 * Sets the banner ad to the one returned to us by doubleclick.
 * @param {Object} pAdUrl - The url to the ad image or swf for this ad.
 * @param {Object} pClickUrl - The url that the user should be taken to if they click on this.
 */
function bc_updateBannerAd(pAdUrl, pClickUrl) {
	document.getElementById(BC_ID_OF_BANNER_AD).innerHTML = "<a target='_blank' href='" + pClickUrl + "'><img border=0 src='" 
	+ pAdUrl +"'/></a>";
}
	
/****************************************************************************************************
 * Helper functions for TIME
 ****************************************************************************************************/

/**
 * This allows us to hide the Related Story if we do not have a link to show them.
 * @pText - The text that woudl go between the link. 
 */
function bc_getRelatedText(pText) {
	return (pText != "") ? "Related:" : "";
}

/**
 * We need a different class name if this is IE 6 so we do the check here and return the right classname.
 */
function bc_getClassName() {
	if(bc_isIE) {
		return "bc_playingDivIE6";
	} else {
		return "bc_playingDiv";
	}
}

/**
 * When we play a video we want to scroll to the correct video so we see which video this is in the list and
 * then set it to be in the middle of the scroll area.
 */
function bc_scrollTo() {
	var div = document.getElementById(bc_gCurrentSelectedTab);
	var children = div.childNodes;
	//if there are 5 or less then there is no scroll bar.
	if(children.length > 5) {
		for(var i = 0; i < children.length; i++) {
			if(children[i].id == "bc_vidCont_" + bc_gCurrentTitleId + "_" + bc_gCurrentPlayingLineupId) {
				//104 is the height of each nav area.
				div.scrollTop = (i - 2) * 104;
			}
		}
	}
}

/**
 * If this is one of the featured titles then we should populate the array we are keeping to track these.
 * @param {Object} pTitleId - The id of the current title we are working with.
 * @param {Object} pLineupId - The lineup id of the lineup we are working with.
 * @param {Object} pLineupName - The Name of the lineup so that we can show it in the UI.
 */	
function bc_isFeatured(pTitleId, pLineupId, pLineupName) {
	//If this title is not featured then it will not be in our associate array.
	if(bc_gFeaturedTitles[pTitleId]) {
		var obj = new Object();
		obj.lineupId = pLineupId;
		obj.lineupName = pLineupName;
		bc_gFeaturedTitles[pTitleId] = obj;
	}
}

/**
 * Since we only know the id of the current line up we need to go through the array of lineups to get the
 * DTO.
 */
function bc_getCurrentLineUpDTO() {
	for(var i = 0; i < bc_gLineUpArray.length; i++) {
		if(bc_gLineUpArray[i].id + "" == bc_gCurrentPlayingLineupId) {
			return bc_gLineUpArray[i];
		}
	}
	return null;	
}

/**
 * A helper function to get the width of the name so that we can have the correct width for each tab.
 * @param {Object} pName - The name that is going to appear on the tab.
 */
function bc_getWidth(pName) {
	//Create a span to put the text in so that I can determine the width of the text
	var span = document.createElement('span');
	span.style.color = "#ffffff";
	span.innerHTML = pName;
	document.getElementById('brightcovePlayerContainer').appendChild(span);
	//the width of the tab is calculated by the text width + 24 for the padding of 12 on each side.
	var tabWidth = span.offsetWidth + 24;
	//since we only created this to get the width we should remove it now.
	document.getElementById('brightcovePlayerContainer').removeChild(span);
	
	return tabWidth;
}

/**
 * A helper function to get the query parameters for this url.  
 * @ returned - an array that contains the name value pairs for this array.
 */
function bc_getArgs() {
	var args = new Object( );
 	var query = location.search.substring(1);
	if(query === "")
		return null;
 	var pairs = query.split("&");
 	for(var i = 0; i < pairs.length; i++) {
 		var pos = pairs[i].indexOf('=');
 		if (pos == -1)
 		continue;
	
 		var argname = pairs[i].substring(0,pos);
 		var value = pairs[i].substring(pos+1);
 		args[argname] = unescape(value);
 	}
 	return args;
}

 
 