/**
 * @author Brandon Aaskov
 * @author Jesse Streb
 * @author Matt Congrove
 * 
 */

var BCGannett;

window.onload = function()
{
	BCGannett = new BrightcoveGannett();
	BCGannett.init();
};

function BrightcoveGannett()
{
	//------------------------------------------- CONFIGURABLE ON A SITE-BY-SITE BASIS
	this.token = "q5_Y4xoa5cxoQzjXmWp0Ks1vFKO6Q5ImYpTo8dZ0r_cfc0UeDKs6qw..";
	this.navigationXMLFile = "http://www.usatoday.com/_common/_scripts/_video/navigation.xml";
	this.customPlaylistIDForTab = 41809992001;
	this.nextUpPlaylistIDForOverride;
	this.nextUpAutoAdvanceDelay = 15; //in seconds
	this.descriptionOverlayDelay = .5; //in seconds
	this.gridEnabled = false; //(bc_getInternetExplorerVersion() != -1 && bc_getInternetExplorerVersion() < 7) ? false : true;
	this.numberOfGridVideosToLoad = 36;
	this.debug = false;
	this.imageUrl = "http://i.usatoday.net/video/images/";
	this.trainingOn = true;
	this.trainingTime = 10; //in seconds
	//-------------------------------------------
		
	//------------------------------------------- PLEASE DO NOT MODIFY THESE
	this.navigationItems = new Array();
	this.navStartingOffset = 0;
	this.navItemOffset = 0; //keeps track of how many navigation items we've scrolled to
	this.navigationAnimating = false;
	this.videoIDToCue;
	this.videoOrRefID = "id";
	this.nextUpPlaylistID;
	
	//the current section is the section in the nav and its name (needed all over the place)
	this.currentSection = {
		id: null,
		name: null,
		sstsCode: null
	};
	this.currentVideo;
	this.firstVideoPlayed = false;
	this.initialSSTSCode;
	this.changeSSTSCode = false;
	this.playlistsNavHTML;
	this.gridPlaylistsHTML;
	this.topicsToAppend = new Array();
	this.playlists = new Array(); //store playlists here so that we don't have to retrieve it later via an API call
	this.relatedVideos = []; //store videos here so that we don't have to retrieve them later via an api call
	this.videoGridVideos = []; //master array for lazy-loading the videos in the video grid
	this.videoGridVideosCopy = []; //array we can manipulate and still keep the master version intact
	this.mediaAPIURL = "http://api.brightcove.com/services/library";
	this.pushDownContainerOpen = false;
	this.sliderAnimatingLeft = false;
	this.sliderAnimatingRight = false;
	this.currentSliderPageNumber = 1;
	this.currentSliderTotalPages;
	this.searchTerm;
	this.baseURL;
	this.lazyLoading = false;
	this.descriptionOverlayTimeout;
	this.descriptionMouseOverEvent;
	this.lazyLoadingTimeout;
	this.originalFlashVars;
	this.trainingTimeout;
	this.isFading = false;
	this.isIE6 = (bc_getInternetExplorerVersion() != -1 && bc_getInternetExplorerVersion() < 7);
	this.isIE7 = (bc_getInternetExplorerVersion() != -1 && bc_getInternetExplorerVersion() == 7);
	
	//coordinates to track the mouse move events on rollover
	this.coordinates;
	//-------------------------------------------
}

BrightcoveGannett.prototype = 
{	
	init: function()
	{
		if(this.token) 
		{
			if(window.location.toString().indexOf("#/") == -1) 
			{
				this.baseURL = window.location.toString();
			} 
			else 
			{
				this.baseURL = window.location.toString().split("#/")[0];
				BCGannett.digForDeepLink(window.location.toString());
			}

			// Parse URL looking for bctid parameter and set baseURL and videoIDToCue if found
			var queryPairs = window.location.search.substr(1).split("&");
			var deepLinked = (window.location.toString().indexOf("#/") == -1) ? false : true;
			
	        for (var i = 0; i < queryPairs.length; i++)
	        {
			    var paramSplit = queryPairs[i].split('=');
			    
			    if (paramSplit[0].toLowerCase() == "bctid" && !deepLinked) 
			    {
					BCGannett.videoIDToCue = paramSplit[1];
		    	}
		    	
		    	if (paramSplit[0].toLowerCase() == "bcrefid" && !deepLinked) 
			    {
			    	BCGannett.videoOrRefID = "referenceId";
			    	BCGannett.videoIDToCue = paramSplit[1];
			    }
		    	
		    	//setting the sstscode from the URL if it's found
		    	if(paramSplit[0].toLowerCase() == "sstscode")
		    	{
		    		BCGannett.initialSSTSCode = paramSplit[1];
		    	}
			}
			
			if(bc_getInternetExplorerVersion() != -1 && bc_getInternetExplorerVersion() < 7) BCGannett.trainingOn = false;
			var trainingCookie = this.getCookie('training') == 'training=1' ? true : false;
			
			if (!this.videoIDToCue && BCGannett.trainingOn && !trainingCookie)
			{
			    //Initiate "training" mode where the pushdown container will be open for 5 seconds, 
			    //then close slowly to show the user it's there.
			    Sizzle("#left")[0].style.visibility = "hidden";
			    Sizzle("#right")[0].style.visibility = "hidden";
			    BCGannett.pushDownContainerOpen = true;
			    
			    //Need to set the display since we are now hiding it due to a player issue.
			    document.getElementById('pushDownContainer').style.display = "block";
			    
			    Sizzle("#pushDownContainer")[0].style.height = "390px";
			    this.setCookie('training', '1');
			    this.trainingTimeout = setTimeout("BCGannett.closeSlideContainer(2000)", (BCGannett.trainingTime * 1000));			    
			}
			
			if(BCGannett.gridEnabled) Sizzle("#videoGrid")[0].style.display = "block"; //shows the grid if it's been enabled
			
			//sets up or removes the editorially controlled playlist tab
			if(BCGannett.customPlaylistIDForTab) BCGannett.getPlaylistByID(BCGannett.customPlaylistIDForTab, "BCGannett.onEditorialPlaylistRetrieved");
			else Sizzle("li.editorial")[0].style.display = "none";
		
			if(this.navigationXMLFile)
			{
				new Brightcove_AjaxRequest(this.navigationXMLFile, {
					method: 'get',
					onSuccess: function(pResponse)
					{
						//builds the navigation items into an array off of the XML file
						var navigation = new Array();
						
						var navXML = BCGannett.createXMLObject(pResponse);
						var sectionTags = navXML.getElementsByTagName("section");
						
						for(var i = 0; i < sectionTags.length; i++)
						{
							var topicTags = sectionTags[i].getElementsByTagName("topic");
							
							var section = {
								name: sectionTags[i].getAttribute("name"),
								id: sectionTags[i].getAttribute("id"),
								sstsCode: sectionTags[i].getAttribute("sstsCode"),
								topics: []
							};
						
							for(var j = 0; j < topicTags.length; j++)
							{
								var topic = {
									name: topicTags[j].getAttribute("name"),
									id: topicTags[j].getAttribute("id")
								};
								
								section.topics.push(topic);
							}
							
							//setup the current section information (especially helpful for deep linked videos)
							if(!BCGannett.currentSection.id) BCGannett.currentSection.id = section.id;
							if(!BCGannett.currentSection.name) 	BCGannett.currentSection.name = section.name;
							if(!BCGannett.currentSection.sstsCode) BCGannett.currentSection.sstsCode = section.sstsCode;
							if(!BCGannett.currentSection.tempSSTSCode) BCGannett.currentSection.tempSSTSCode = section.sstsCode;
							
							else if(!BCGannett.currentSection.name) //was deep linked. the name doesn't get set on occasions when the video is deep linked, so we need to get it here
							{
								if(BCGannett.currentSection.id == section.id) 
								{
									BCGannett.currentSection.name = section.name;
									
									//only if this wasn't set via the URL already
									if(!BCGannett.currentSection.sstsCode) BCGannett.currentSection.sstsCode = section.sstsCode;
								}
							}
							
							navigation.push(section);
						}
						
						BCGannett.navigationItems = navigation; //store this for later use when adding nested topics
						BCGannett.buildNavigation(BCGannett.navigationItems);
						BCGannett.displayPlaylistsInSlider(BCGannett.currentSection.id); //default load the first player's items
					}
				});
			}
		}
		else
		{
			throw new Error("The read token hasn't been defined");
		}
		
		Sizzle("#navigationTop span.leftArrow")[0].onclick = function()
		{
			BCGannett.onLeftNavArrowClicked();
		};
		
		Sizzle("#navigationTop span.rightArrow")[0].onclick = function()
		{
			BCGannett.onRightNavArrowClicked();
		};
		
		Sizzle("#search form input")[0].value = "Search Videos"; //resets this for browsers like firefox that override it
		Sizzle("#search form input")[0].onfocus = function()
		{
			BCGannett.clearTrainingTimeout();
			if(this.value.toLowerCase() == "search videos") this.value = "";
		};
		
		//overrides the search functionality so that the page doesn't turn
		Sizzle("#search form")[0].onsubmit = function()
		{
			BCGannett.onSearchInitiated(this);
			return false;
		};
		
		Sizzle("#searchSubmit")[0].onclick = function()
		{
			BCGannett.onSearchInitiated(this);
			return false;
		};
		
		
		Sizzle("#left")[0].onclick = function()
		{
			BCGannett.onLeftSliderArrowClicked();
		};		
		
		Sizzle("#right")[0].onclick = function()
		{
			BCGannett.onRightSliderArrowClicked();
		};	
		
		Sizzle("#searchResults .close")[0].onclick = function()
		{
			BCGannett.changeDisplayForSearch(false);
			
			Sizzle("#left")[0].style.visibility = "hidden";
			Sizzle("#right")[0].style.visibility = "hidden";
			Sizzle("#slideContainer .videos:first")[0].innerHTML = BCGannett.getAjaxLoader();
			Sizzle("#searchInputBox")[0].value = "";
			Sizzle("#pushDownContainer span.numberOfResults")[0].innerHTML = "";
			BCGannett.displayPlaylistsInSlider(BCGannett.currentSection.id);
			BCGannett.searchTerm = "";
			
		};
		
		//Adding event listener to slider box to track whether or not their was a mouse over so that we can cancel the slide back up.
		document.getElementById("slideContainer").onmouseover = function() 
		{
			BCGannett.clearTrainingTimeout();
		}
	},
	
	fixPNG: function(selector)
	{
	    if (typeof(DD_belatedPNG) != "undefined"){
			//DD_belatedPNG was defined by inclusion in conditional comments in HTML
			DD_belatedPNG.fix(selector);
	    }
	},
	
	onSearchInitiated: function(pEvent)
	{
		BCGannett.changeDisplayForSearch(true);
		Sizzle("#slideContainer .videos:first").innerHTML = BCGannett.getAjaxLoader("light", "searched");
		BCGannett.openSlideContainer();
		BCGannett.searchForVideos(Sizzle("#searchInputBox")[0].value);
	},
	
	getSliderInfo: function()
	{
		var amountOfThumbnails = (BCGannett.searchTerm) ? 10 : 8;
		var sliderInfo = {};
		sliderInfo.currentLeftPosition = BCGannett.getStyle(Sizzle("#slideContainer .videos:first")[0], "left");
		sliderInfo.totalGrids = Sizzle("#slideContainer .video").length/amountOfThumbnails;
		sliderInfo.totalItemWidth = Math.ceil(sliderInfo.totalGrids) * (BCGannett.fullWidth(Sizzle("#slideContainer")[0]) + BCGannett.getStyle(Sizzle("#slideContainer .videos:first")[0], "marginRight"));
		sliderInfo.newLeftPosition =  BCGannett.getStyle(Sizzle("#slideContainer .videos:first")[0], "left") - BCGannett.fullWidth(Sizzle("#slideContainer")[0]);
		return sliderInfo;
	},

	buildNavigation: function(navigationItems)
	{
		var topNavHTML = "<ul class='sections'>\n";
		var sideNavHTML = "";
		
		for(var i = 0; i < navigationItems.length; i++)
		{
			var section = navigationItems[i];
			
			var sectionClass = "section";
			
			if(i == 0) sectionClass += " first";
			else if(i == navigationItems.length - 1) sectionClass += " last";
			
			topNavHTML += "<li class='" + sectionClass + "' id='"+section.id+"' name='" + section.name.replace(/'/g, "") + "' sstsCode='" + section.sstsCode + "'>";
			topNavHTML += "<div class='left'></div>";
			topNavHTML += "<div class='middle'>"+section.name+"</div>";
			topNavHTML += "<div class='right'></div>";
			topNavHTML += "</li>\n";
		}
				
		Sizzle("#navigationItems")[0].innerHTML = topNavHTML;
		
		var sections = Sizzle("#navigationItems ul.sections li.section");
		var leftEndWidth = BCGannett.fullWidth(Sizzle("#navigationTop span.leftEdge")[0]);
		var rightEndWidth = BCGannett.fullWidth(Sizzle("#navigationTop span.rightEdge")[0]);
		var itemLeftWidth = BCGannett.fullWidth(Sizzle("#navigationItems ul.sections li.section:first div.left")[0]);
		var itemRightWidth = BCGannett.fullWidth(Sizzle("#navigationItems ul.sections li.section:first div.right")[0]); 
		var navigationItemsWidth = 0;
		var navBarWidthSet = false;
		var maxWidth = 680;
		
		for(var i = 0; i < sections.length; i++)
		{
			var section = sections[i];
			
			//-------------------- setting the nav bar width
			var textWidth = parseInt(BCGannett.fullWidth(section.childNodes[1]));
			var overallWidthToCheck = navigationItemsWidth + textWidth + itemLeftWidth + itemRightWidth + leftEndWidth + rightEndWidth;

			if(overallWidthToCheck > maxWidth && !navBarWidthSet) 
			{
				navBarWidthSet = true;
			}
			else if(!navBarWidthSet)
			{
				var sectionName = section.getAttribute("name");
				navigationItemsWidth += itemLeftWidth + textWidth + itemRightWidth;
				BCGannett.navItemOffset++;
				BCGannett.navStartingOffset++;
			}
			//--------------------
			
			section.onclick = function()
			{
				//clearing timeout.
                BCGannett.clearTrainingTimeout();
				BCGannett.searchTerm = "";
				
                var selectedItem = Sizzle("#navigationTop ul.sections li.active")[0];
                if(selectedItem)
                { 
                    BCGannett.removeClass(selectedItem, "active");
                }

				if(BCGannett.currentSection.id == this.id && BCGannett.pushDownContainerOpen)
				{
					BCGannett.closeSlideContainer();
				}
				else
				{
					BCGannett.addClass(this, "active");

					Sizzle("#navigationLeft")[0].innerHTML = "";
					Sizzle("#pushDownContainer span.numberOfResults:first")[0].innerHTML = "";
					Sizzle("#slideContainer .videos:first")[0].innerHTML = BCGannett.getAjaxLoader();
								
					BCGannett.openSlideContainer();
					BCGannett.changeDisplayForSearch(false);
					
					//update the current section values
					BCGannett.currentSection.id = this.id;
					BCGannett.currentSection.name = this.getAttribute("name");
					BCGannett.currentSection.tempSSTSCode = this.getAttribute("sstsCode");
					
					BCGannett.displayPlaylistsInSlider(BCGannett.currentSection.id);			

					if(BCGannett.gridEnabled) BCGannett.addPlaylistsToGrid(BCGannett.currentSection.id); //adds the same playlists to the grid view

                    BCGannett.fixPNG('#close, #left, #right, #navigationLeft, .video, .thumbBorder');
				}
			}
		}


        Sizzle("#navigationItems")[0].style.width = navigationItemsWidth - itemLeftWidth + "px";
        Sizzle("#navigationTop span.rightArrow")[0].style.left = navigationItemsWidth + rightEndWidth + 14 + "px";

        if (overallWidthToCheck < maxWidth)
        {
            Sizzle("#navigationTop span.rightArrow")[0].style.display = "none";
            Sizzle("#navigationTop span.leftArrow")[0].style.display = "none";
            Sizzle("#navigationTop span.rightEdge")[0].style.left = navigationItemsWidth - itemLeftWidth + "px";
        }
        else 
        { 
            Sizzle("#navigationTop span.rightEdge")[0].style.left = navigationItemsWidth + rightEndWidth - itemLeftWidth - 6 + "px";
        } 
		
		Sizzle("#close")[0].onclick = function()
		{
			BCGannett.closeSlideContainer();
		}
	},

    updateNavigationButtonsDisabled: function()
    {
         if (BCGannett.navItemOffset > BCGannett.navStartingOffset)
         {
             BCGannett.removeClass(Sizzle("#navigationTop span.leftArrow")[0], "left_deactivated");
         }
         else
         {
             BCGannett.addClass(Sizzle("#navigationTop span.leftArrow")[0], "left_deactivated");
         }

         if (BCGannett.navItemOffset < Sizzle('#navigationItems ul.sections li.section').length)
         {
             BCGannett.removeClass(Sizzle("#navigationTop span.rightArrow")[0], "right_deactivated");
         }
         else
         {
             BCGannett.addClass(Sizzle("#navigationTop span.rightArrow")[0], "right_deactivated");
         }
    },
	
	onLeftNavArrowClicked: function()
	{
		if(BCGannett.navItemOffset > BCGannett.navStartingOffset && !BCGannett.navigationAnimating)
		{
			var nextNavItem = Sizzle("#navigationItems ul.sections li.section")[BCGannett.navItemOffset-1];
			var widthToSlide = BCGannett.fullWidth(nextNavItem.childNodes[0]) + 
				BCGannett.fullWidth(nextNavItem.childNodes[1]) + 
				BCGannett.fullWidth(nextNavItem.childNodes[2]);
				
			var newLeft = BCGannett.getStyle(Sizzle("#navigationItems ul.sections")[0], "left") + widthToSlide;
			BCGannett.navItemOffset--;
			BCGannett.navigationAnimating = true;
			
			vorpal.ui.animate(Sizzle("#navigationItems ul.sections")[0], 300, newLeft, "left", function()
			{
				//calback
				BCGannett.navigationAnimating = false;
                BCGannett.updateNavigationButtonsDisabled();
			});
		}
	},
	
	onRightNavArrowClicked: function()
	{
		if(BCGannett.navItemOffset < Sizzle("#navigationItems ul.sections li.section").length && !BCGannett.navigationAnimating)
		{
			var nextNavItem = Sizzle("#navigationItems ul.sections li.section")[BCGannett.navItemOffset];
			var widthToSlide = BCGannett.fullWidth(nextNavItem.childNodes[0]) + 
				BCGannett.fullWidth(nextNavItem.childNodes[1]) + 
				BCGannett.fullWidth(nextNavItem.childNodes[2]);
			var newLeft = BCGannett.getStyle(Sizzle("#navigationItems ul.sections")[0], "left") - widthToSlide;
			
			BCGannett.navItemOffset++;
			BCGannett.navigationAnimating = true;
			
			vorpal.ui.animate(Sizzle("#navigationItems ul.sections")[0], 300, newLeft, "left", function()
			{
				//callback
				BCGannett.navigationAnimating = false;
                BCGannett.updateNavigationButtonsDisabled();
			});
		}
	},
	
	openSlideContainer: function(pCallback)
	{
		//We are now hiding the push down container because it caused problem with the player in FF on windows.
		document.getElementById('pushDownContainer').style.display = "block";
		
		Sizzle("#left")[0].style.visibility = "hidden";
		Sizzle("#right")[0].style.visibility = "hidden";
		BCGannett.pushDownContainerOpen = true;
			
		vorpal.ui.animate(Sizzle("#pushDownContainer")[0], 500, 390, 'height', function()
		{
			//callback
			if(pCallback) pCallback(); 
		});
	},
	
	closeSlideContainer: function(pSpeed)
	{	
		var animationSpeed = (pSpeed) ? pSpeed : 500;
		BCGannett.pushDownContainerOpen = false;
		
		scrollTo(0,0); //jump back to the top of the page, otherwise redrawing of the player makes some weird display issues
		
		//make sure we hide the short description overlay
		var shortDescriptionDiv = Sizzle("#shortDescriptionOverlay")[0];
		BCGannett.fadeOut(shortDescriptionDiv);
		
		vorpal.ui.animate(Sizzle("#pushDownContainer")[0], animationSpeed, 0, 'height', function()
		{
			document.getElementById('pushDownContainer').style.display = "none";
			//callback
		});
	},
	
	displayPlaylistsInSlider: function(pPlayerID)
	{
		if(pPlayerID)
		{
			var urlVariables = 
			{
				callback: "BCGannett.createTopLevelTopics",
				command: "find_playlists_for_player_id",	
				playlist_fields: "id,name,videos",
				video_fields: "id,name,shortDescription,length,tags,thumbnailURL",
				player_id: pPlayerID,
				token: this.token				
			}

			BCGannett.addScriptTag(BCGannett.mediaAPIURL, urlVariables);
		}
	},
	
	createTopLevelTopics: function(pResponse)
	{	
		//---------------------------------------------------- PLAYLISTS SETUP
		var playlists = pResponse.items;
		
		BCGannett.playlistsNavHTML = "<ul class='playlists container'>\n";
		BCGannett.videoGridVideos = new Array();
							
		for(var i = 0; i < playlists.length; i++)
		{
			var playlist = playlists[i];
			
			playlist.playerID = BCGannett.currentSection.id;
			playlist.videos = BCGannett.getModifiedVideosArray(playlist.videos, playlist);
			BCGannett.playlists[playlist.id] = playlist;
			
			BCGannett.playlistsNavHTML += "<li class='playlist' id='"+playlist.id+"'>"+playlist.name+"</li>";
			
			var videos = playlist.videos;
			BCGannett.videoGridVideos = BCGannett.videoGridVideos.concat(videos, BCGannett.videoGridVideos);
			
			if(i == 0) 
			{
				if(BCGannett.pushDownContainerOpen) BCGannett.displayVideosInSlider(playlist.videos);
				
				if(!BCGannett.nextUpPlaylistIDForOverride && !BCGannett.nextUpPlaylistID) //for the first, default nextUp playlist
				{
					BCGannett.addVideosToTab(playlist.videos, "nextUp");
					BCGannett.nextUpPlaylistID = playlist.id;
				}
				else //will only get here if it's been deep linked and there's a nextUpPlaylistID already stored
				{
					if(BCGannett.nextUpPlaylistIDForOverride) //if the next up playlist is overriden in the config
					{
						BCGannett.nextUpPlaylistID = BCGannett.nextUpPlaylistIDForOverride;
					} 	
					
					if(BCGannett.playlists[BCGannett.nextUpPlaylistID]) 
					{
						BCGannett.addVideosToTab(BCGannett.playlists[BCGannett.nextUpPlaylistID].videos, "nextUp");
					}
					else //the playlist DTO isn't stored yetd
					{
						BCGannett.getPlaylistByID(BCGannett.nextUpPlaylistID, "BCGannett.onNextUpPlaylistRetrieved");
					}
				}
				
				if(!BCGannett.videoIDToCue)
				{
					BCGannett.videoIDToCue = videos[0].id;
					if(BCGannett.experienceModule && BCGannett.experienceModule.getReady() && BCGannett.videoPlayerModule)
					{
						BCGannett.videoPlayerModule.loadVideo(BCGannett.videoIDToCue, BCGannett.videoOrRefID);
						BCGannett.videoOrRefID = "id";
						BCGannett.createDeepLink(BCGannett.videoIDToCue);
					}
				}
			}
		}
		
		for(var i = 0; i < BCGannett.navigationItems.length; i++)
		{
			var section = BCGannett.navigationItems[i];
			
			if(section.id == BCGannett.currentSection.id)
			{
				for(var j = 0; j < section.topics.length; j++)
				{
					//topics are nested
					var topic = section.topics[j];
					BCGannett.topicsToAppend.push(topic);
				}
			}
		}
		
		BCGannett.queueAppendedPlaylists();
	},
	
	queueAppendedPlaylists: function()
	{
		if(BCGannett.topicsToAppend.length > 0)
		{
			//topics are nested
			var topic = BCGannett.topicsToAppend.reverse().pop();
			BCGannett.playlistsNavHTML += "<li class='playlist parent'>"+topic.name;
			
			var urlVariables = 
			{
				command: "find_playlists_for_player_id",
				playlist_fields: "id,name,videos",
				video_fields: "id,name,shortDescription,length,tags,thumbnailURL",
				callback: "BCGannett.appendPlaylists",	
				player_id: topic.id,
				token: BCGannett.token				
			}
			
			BCGannett.addScriptTag(BCGannett.mediaAPIURL, urlVariables);
		}
		else
		{
			BCGannett.playlistsNavHTML += "</ul>\n";
			Sizzle("#navigationLeft")[0].innerHTML = BCGannett.playlistsNavHTML;
			if(BCGannett.gridEnabled) BCGannett.addPlaylistsToGrid(BCGannett.currentSection.id); //adds the same playlists to the grid view
			
			var playlists = Sizzle("#navigationLeft ul.playlists li.playlist");
			
			for(var i = 0; i < playlists.length; i++)
			{
				var playlist = playlists[i];
				BCGannett.videoGridVideos = BCGannett.videoGridVideos.concat(playlist.videos, BCGannett.videoGridVideos);
				
				if(playlist.id)
				{
					playlist.onclick = function()
					{
						//remove the active class from anything that's currently there
						for(var j = 0; j < playlists.length; j++)
						{
							var parents = Sizzle("#navigationLeft ul.playlists li.parent");
							for(var k = 0; k < parents.length; k++)
							{
								if(parents[k].style.color = "rgb(255, 255, 255)") parents[k].style.color = "#5F5F5F";
							}
							BCGannett.removeClass(playlists[j], "active");
						}
						
						BCGannett.onPlaylistClicked(this.id);
						BCGannett.addClass(this, "active");
						if(BCGannett.hasClass(this, "nested")) this.parentNode.parentNode.style.color = "#ffffff";
					};
				}
			}
			
			//---------- checks to see if a playlist is active, and if it isn't defaults to the first playlist
			var playlistActive = false;
			
			for(var i = 0; i < playlists.length; i++)
			{
				var playlist = playlists[i];
				if(BCGannett.hasClass(playlist, "active")) playlistActive = true;
			}
			
			if(!playlistActive && playlists.length > 0) BCGannett.addClass(Sizzle("#navigationLeft ul.playlists li.playlist")[0], "active");
			//-----------
			for(var i = 0; i < playlists.length; i++)
			{
				var playlist = playlists[i];
			}			
			//----------------------------------------------------
		}
	},
	
	appendPlaylists: function(pResponse)
	{					
		var playlists = pResponse.items;
										
		BCGannett.playlistsNavHTML += "<ul class='playlists'>\n";
		
		for(var i = 0; i < playlists.length; i++)
		{
			var playlist = playlists[i];
			playlist.playerID = BCGannett.currentSection.id; //using the main section ID since that's really the containing element
			playlist.videos = BCGannett.getModifiedVideosArray(playlist.videos, playlist);
			BCGannett.playlists[playlist.id] = playlist;
			BCGannett.playlistsNavHTML += "<li class='playlist nested' id='"+playlist.id+"'>"+playlist.name+"</li>";
		}

		BCGannett.playlistsNavHTML += "</ul>\n";
		BCGannett.playlistsNavHTML += "</li>";
		
		BCGannett.queueAppendedPlaylists();
	},
	
	getPlaylistByID: function(pPlaylistID, pCallback)
	{
		var urlVariables = 
		{
			command: "find_playlist_by_id",
			callback: pCallback,	
			playlist_id: pPlaylistID,
			token: BCGannett.token				
		}
		
		BCGannett.addScriptTag(BCGannett.mediaAPIURL, urlVariables);
	},
	
	onNextUpPlaylistRetrieved: function(pResponse)
	{
		var playlist = pResponse;
		playlist.videos = BCGannett.getModifiedVideosArray(playlist.videos, playlist);
		BCGannett.playlists[playlist.id] = playlist;
		BCGannett.addVideosToTab(playlist.videos, "nextUp");
	},
	
	onEditorialPlaylistRetrieved: function(pResponse)
	{
		var playlist = pResponse;
		playlist.playerID = null;
		playlist.videos = BCGannett.getModifiedVideosArray(playlist.videos, playlist);
		BCGannett.playlists[playlist.id] = playlist;
		
		Sizzle("ul.tabs li.editorial h3")[0].innerHTML = playlist.name;
		BCGannett.addVideosToTab(playlist.videos, "editorial");
	},
	
	onPlaylistClicked: function(pPlaylistID)
	{
        //Disable previously selected
        var selectedItem = Sizzle("#navigationLeft ul.playlists li.active")[0];
        if (selectedItem){
            BCGannett.removeClass(selectedItem, "active");
        }
        //Make clicked selected
        BCGannett.addClass(Sizzle("#" + pPlaylistID)[0], "active");

		Sizzle("#left")[0].style.visibility = "hidden";
		Sizzle("#right")[0].style.visibility = "hidden";
		Sizzle("#pushDownContainer span.numberOfResults:first").innerHTML = "";
		BCGannett.displayVideosInSlider(BCGannett.playlists[pPlaylistID].videos);
	},
	
	addOnClickEventForVideo: function(pElements, pChangeSSTSCode)
	{
		for(var i = 0; i < pElements.length; i++)
		{
			pElements[i].onclick = function(pEvent)
			{
				BCGannett.onVideoClicked(this, pChangeSSTSCode);
			};
		}
	},
	
	onVideoClicked: function(pElementClicked, pChangeSSTSCode)
	{	
		if(BCGannett.nextUpVideoTimeout)
		{
			clearTimeout(BCGannett.nextUpVideoTimeout);
			BCGannett.nextUpVideoTimeout = null;
		}
		
		var liveStream = pElementClicked.getAttribute("liveStream");
		var playlistID = pElementClicked.getAttribute("playlistID");
		var videoID = pElementClicked.getAttribute("videoID");
		
		if(BCGannett.nextUpPlaylistID !== playlistID)
		{
			if(!BCGannett.nextUpPlaylistIDForOverride) BCGannett.nextUpPlaylistID = playlistID;
			BCGannett.addVideosToTab(BCGannett.playlists[BCGannett.nextUpPlaylistID].videos, "nextUp");	
		}
		
		if(BCGannett.currentSection.tempSSTSCode && pChangeSSTSCode) 
		{
			BCGannett.currentSection.sstsCode = BCGannett.currentSection.tempSSTSCode;
		}
		
		BCGannett.changeSSTSCode = pChangeSSTSCode;
		
		BCGannett.loadVideo(videoID, BCGannett.videoOrRefID);
		BCGannett.videoOrRefID = "id";
		BCGannett.createDeepLink(videoID);
		
		BCGannett.closeSlideContainer();
	},
	
	//adds playlist info to each video DTO which can be helpful, mostly for things
	//like making the next up playlist autoadvance work properly
	getModifiedVideosArray: function(pVideos, pPlaylist)
	{
		var videos = [];
		
		for(var i = 0; i < pVideos.length; i++)
		{
			var video = pVideos[i];
			video.liveStream = (BCGannett.hasTag(video.tags, "live=true")) ? true : false;
			
			var playlist = {
				id: pPlaylist.id,
				name: pPlaylist.name
			};
			
			video.playlist = playlist;
			videos.push(video);
		}
		
		return videos;
	},
	
	displayVideosInSlider: function(pVideos)
	{
		var videosHTML = "";
		for(var i = 0; i < pVideos.length; i++) 
		{
			var video = pVideos[i];
				
			if (video) 
			{
				var playlistID = (video.playlist) ? video.playlist.id : BCGannett.nextUpPlaylistID;
				var liveStream = (video.liveStream) ? video.liveStream : BCGannett.hasTag(video.tags, "live=true");
				var thumbnail = (video.thumbnailURL) ? video.thumbnailURL : BCGannett.imageUrl + "clear.gif";
			
				var videoHTML = "<div class='video' id='"+video.id+"' videoID='" + video.id + "' playlistID='" + playlistID +"' liveStream='" + liveStream + "'>\n";
				videoHTML += "<span class='hoverContainer'></span>\n";
				videoHTML += "<span class='thumbBorder'></span>\n";
				if(liveStream) videoHTML += "<span class='liveBorder'><strong>LIVE</strong></span>\n";
				videoHTML += "<img src='" + thumbnail + "' />\n";
				videoHTML += "<h5>" + video.name + "</h5>\n";
				videoHTML += "<span class='time'> " + BCGannett.getDateForDisplay(video) + "</span>\n";
				videoHTML += "</div>\n";
			}
			videosHTML += videoHTML;
		}
		
		Sizzle("#slideContainer .videos:first")[0].innerHTML = videosHTML;

		BCGannett.fixPNG('.thumbBorder');

		BCGannett.addOnClickEventForVideo(Sizzle("#slideContainer div.videos div.video"), true);
		BCGannett.repositionSliderVideos();
		
		var videos = Sizzle("#slideContainer div.videos div.video span.hoverContainer");
		for(var i = 0; i < videos.length; i++)
		{
			var video = videos[i];
			video.onmouseover = function(pEvent)
			{
				this.coordinates = BCGannett.findPos(document.getElementById("bcImmersivePlayerContainer"));
				BCGannett.descriptionMouseOverEvent = this;
				BCGannett.descriptionOverlayTimeout = setTimeout("BCGannett.showDescriptionOverlay()", BCGannett.descriptionOverlayDelay * 1000);
			};
			
			video.onmouseout = function(pEvent)
			{
				clearTimeout(BCGannett.descriptionOverlayTimeout);
				var shortDescriptionDiv = Sizzle("#shortDescriptionOverlay")[0];
				BCGannett.fadeOut(shortDescriptionDiv);
			};
			
			video.onmousemove = function(pEvent)
			{	
				try 
				{
					var shortDescriptionDiv = Sizzle("#shortDescriptionOverlay")[0];
					if(bc_getInternetExplorerVersion() != -1 && bc_getInternetExplorerVersion() < 7) {
						shortDescriptionDiv.style.top = BCGannett.mouseY(pEvent) - 145 - this.coordinates[1] + "px";
						shortDescriptionDiv.style.left = BCGannett.mouseX(pEvent) - 158 - this.coordinates[0] + "px";
					} else {
						shortDescriptionDiv.style.top = BCGannett.mouseY(pEvent) - 130 - this.coordinates[1] + "px";
						shortDescriptionDiv.style.left = BCGannett.mouseX(pEvent) - 155 - this.coordinates[0] + "px";
					}
				
				} catch (pError) 
				{
					//swalling error as I don't want to throw anything just to move the desc.
				}
			};
		}
		
		BCGannett.currentSliderPageNumber = 1;
		BCGannett.changeSliderPageDisplay(BCGannett.currentSliderPageNumber);
	},
	
	displayNoResultsMessage: function() 
	{
		Sizzle("#slideContainer .videos:first")[0].innerHTML = "<div id=''>There were no results for search request</div>";
	},
	
	onLeftSliderArrowClicked: function(pEvent)
	{
		var currentLeftPosition = BCGannett.getStyle(Sizzle("#slideContainer .videos:first")[0], "left");
		if(currentLeftPosition < 0 && !BCGannett.sliderAnimatingLeft) 
		{
			var newLeftPosition = BCGannett.getStyle(Sizzle("#slideContainer .videos:first")[0], "left") + BCGannett.fullWidth(Sizzle("#slideContainer")[0]);
			BCGannett.sliderAnimatingLeft = true;
			
			Sizzle("#right")[0].style.visibility = "visible";
			BCGannett.toggleSliderArrow("#right", true);
			
			vorpal.ui.animate("#slideContainer .videos:first", 500, newLeftPosition, 'left', function()
			{
				BCGannett.sliderAnimatingLeft = false;
				BCGannett.currentSliderPageNumber--;
				BCGannett.changeSliderPageDisplay(BCGannett.currentSliderPageNumber);
				
				if(BCGannett.currentSliderPageNumber <= 1) BCGannett.toggleSliderArrow("#left");
			});
		}
	},
	
	onRightSliderArrowClicked: function(pEvent)
	{
		var sliderInfo = BCGannett.getSliderInfo();
		var newLeftPosition = sliderInfo.newLeftPosition;
		
		if(newLeftPosition >= -sliderInfo.totalItemWidth && !BCGannett.sliderAnimatingRight) 
		{
			BCGannett.sliderAnimatingRight = true;
			Sizzle("#left")[0].style.visibility = "visible";
			BCGannett.toggleSliderArrow("#left", true);
			
			vorpal.ui.animate("#slideContainer .videos:first", 500, newLeftPosition, 'left', function()
			{
				//sometimes the slider is off by a pixel, so this corrects it
				var currentLeft = BCGannett.getStyle(Sizzle("#slideContainer .videos:first")[0], "left");
				var currentLeftString = currentLeft.toString();
				var lastDigit = Number(currentLeftString.charAt(currentLeftString.length-1));
				if (lastDigit == 9) Sizzle("#slideContainer .videos:first")[0].style.left = currentLeft - 1 + "px";
				else if (lastDigit == 1) Sizzle("#slideContainer .videos:first")[0].style.left = currentLeft + 1 + "px";
				
				
				BCGannett.sliderAnimatingRight = false;
				BCGannett.currentSliderPageNumber++;
				BCGannett.changeSliderPageDisplay(BCGannett.currentSliderPageNumber);
				
				if(BCGannett.currentSliderTotalPages <= BCGannett.currentSliderPageNumber) BCGannett.toggleSliderArrow("#right");
			});
		}
	},
	
	toggleSliderArrow: function(pSelector, pEnabled)
	{
		var arrow = Sizzle(pSelector)[0];
		var arrowParent = arrow.parentNode;
		
		if(!pEnabled)
		{
			arrow.onclick = function() { return false; };
		
			BCGannett.addClass(arrow, "inactive");
			
			if (pSelector == "#left") 
			{
				arrow.style.backgroundImage = "url(" + BCGannett.imageUrl + "pushdown-left-inactive.png)";
			} 
			else 
			{
				arrow.style.backgroundImage = "url(" + BCGannett.imageUrl + "pushdown-right-inactive.png)";
			}	
		}
		else
		{
			var clickFunction = (pSelector == "#left") ? BCGannett.onLeftSliderArrowClicked : BCGannett.onRightSliderArrowClicked;
			arrow.onclick = clickFunction;
	
			BCGannett.removeClass(arrow, "inactive");
			
			if (pSelector == "#left") 
			{
				arrow.style.backgroundImage = "url(" + BCGannett.imageUrl + "pushdown-left.png)";	
			} 
			else 
			{
				arrow.style.backgroundImage = "url(" + BCGannett.imageUrl + "pushdown-right.png)";
			}
			
		}
	},
	
	repositionSliderVideos: function()
	{
		var leftEdgeTracker = 0;
		
		var sliderVideos = Sizzle("#slideContainer div.videos div.video");
		var itemsPerPage = (!BCGannett.searchTerm) ? 8 : 10;
		BCGannett.currentSliderTotalPages = Math.ceil(sliderVideos.length/itemsPerPage);
		
		for(var i = 0; i < sliderVideos.length; i++)
		{
			var video = sliderVideos[i];
			BCGannett.removeClass(video, "bottomVideo");
			video.style.left = leftEdgeTracker + "px";
			
			if(i % 2 != 0) //for every other video to go on the bottom
			{
				BCGannett.addClass(video, "bottomVideo");
				leftEdgeTracker += BCGannett.fullWidth(video) + BCGannett.getStyle(video, "marginRight");
			}
		}
		
		Sizzle("#left")[0].style.visibility = "visible";
		Sizzle("#right")[0].style.visibility = "visible";
		
		BCGannett.toggleSliderArrow("#left");
		
		Sizzle("#slideContainer .videos:first")[0].style.left = "-3px";
		
		var sliderInfo = BCGannett.getSliderInfo();
		
		//enable or disable the right arrow depending on how many videos exist
		if(BCGannett.currentSliderTotalPages <= 1 || !BCGannett.currentSliderTotalPages) BCGannett.toggleSliderArrow("#right");
		else BCGannett.toggleSliderArrow("#right", true)
	},
	
	changeSliderPageDisplay: function(pPageNumber)
	{
		var numberOfVideos = Sizzle("#slideContainer div.videos div.video").length;
		var itemsPerPage = (!BCGannett.searchTerm) ? 8 : 10;
		var startNumber = (pPageNumber * itemsPerPage) - itemsPerPage + 1;
		var endNumber = (pPageNumber * itemsPerPage < numberOfVideos) ? pPageNumber * itemsPerPage : numberOfVideos;
		
		//BCGannett.currentSliderTotalPages = Math.ceil(numberOfVideos/itemsPerPage);
		
		if(endNumber > 0 && numberOfVideos)
		{
			Sizzle("#pushDownContainer span.numberOfResults")[0].innerHTML = startNumber + "-" + endNumber + "<em> of </em>" + numberOfVideos + " Results";
		}
		else
		{
			if(!numberOfVideos)
			{
				numberOfVideos = (Sizzle("#slideContainer div.videos div.video").length) ? 1 : 0;
			}
			
			var results = numberOfVideos + " Result";
			if(numberOfVideos !== 1) results += "s"; //just being grammatically correct
			Sizzle("#pushDownContainer span.numberOfResults")[0].innerHTML = results;
		}
	},
	
	getPlaylistVideos: function(pPlaylistID)
	{
		Sizzle("#slideContainer .videos:first")[0].innerHTML = BCGannett.getAjaxLoader();

		var urlVariables = 
		{
			command: "find_playlist_by_id",	
			playlist_id: pPlaylistID,
			token: BCGannett.token				
		}
		
		new Brightcove_AjaxRequest(BCGannett.mediaAPIURL, {
			parameters: urlVariables,
			onSuccess: function(pEvent)
			{
				BCGannett.displayVideosInSlider(pEvent.videos);
			}
		});
	},
	
	showDescriptionOverlay: function()
	{
		clearTimeout(BCGannett.descriptionOverlayTimeout);

		var shortDescriptionDiv = Sizzle("#shortDescriptionOverlay")[0];

		var shortDescription;
        var parent = BCGannett.descriptionMouseOverEvent.parentNode;
        var videoId = parent.getAttribute("videoid");
        if (!videoId) videoId = parent.id;

		if(videoId)
		{
			//digs up the short description to use
			for(var playlistID in BCGannett.playlists)
			{
				var playlist = BCGannett.playlists[playlistID];
				
				if(playlist.videos) //otherwise for loop fails in safari 4
				{
					for(var i = 0; i < playlist.videos.length; i++)
					{
						var video = playlist.videos[i];
						if(video.id == videoId) shortDescription = video.shortDescription;
					}
				}
			}
			
			if(!shortDescription)
			{
				for(var i = 0; i < BCGannett.relatedVideos.length; i++)
				{
					var video = BCGannett.relatedVideos[i];
					if(video.id == videoId) shortDescription = video.shortDescription;
				}
			}
			
			if(shortDescription)
			{
				Sizzle("#shortDescriptionOverlay p")[0].innerHTML = shortDescription;
				BCGannett.fadeIn(shortDescriptionDiv);
			}
			else
			{
				throw new Error("Could not find the short description for this video: " + video.id);
			}
		}
		else
		{
			throw new Error("There was no video ID to use to find the short description.");
		}
	},
	
	//------------------------------------------------------------------- FADE FUNCTIONS
	setOpaque: function(elem, level) 
	{
		elem.style.opacity = level / 100;
	},
	
	fadeIn: function(elem) {
		if(BCGannett.isIE6) {
			elem.style.display = 'block';
			
			return;
		}
		
		if(BCGannett.isFading) {
			return;
		} else {
			BCGannett.isFading = true;
		}
		
    	elem.style.display = 'block';
		
		for(var i = 0; i <= 100; i += 20) {
			(function() {
				var opacity = i;
				
				setTimeout(function() {
					BCGannett.setOpaque(elem, 0 + opacity);

					if(opacity == 100) {
                    	BCGannett.isFading = false;
                    }
				}, (i + 1) * 2);
			})();
		}
	},
	
	fadeOut: function(elem) {
		if(BCGannett.isIE6) {
			elem.style.display = 'none';
			
			return;
		}
		
		if(BCGannett.isFading) {
			return;
		} else {
			BCGannett.isFading = true;
		}
		
		for(var i = 0; i <= 100; i += 20) {
			(function() {
				var opacity = i;
				
				setTimeout(function() {
					BCGannett.setOpaque(elem, 100 - opacity);
					
					if(opacity == 100) {
                    	elem.style.display = 'none';
                    	BCGannett.isFading = false;
                    }
				}, (i + 1) * 2);
			})();
		}
	},
	
	//------------------------------------------------------------------- TAB RELATED FUNCTIONS
	addVideosToTab: function(pVideos, pTabID)
	{
		var playlistHTML = "";
		
		for(var i = 0; i < pVideos.length; i++)
		{
			var video = pVideos[i];
			
			var playlistID = (video.playlist) ? video.playlist.id : BCGannett.nextUpPlaylistID;
			var liveStream = (video.liveStream) ? video.liveStream : BCGannett.hasTag(video.tags, "live=true");
			
			playlistHTML += "<li videoID='" + video.id + "' playlistID='" + playlistID + "' liveStream=" + liveStream +" viewed='false'>\n";
			playlistHTML += "<span class='thumbBorder'></span>\n";
			playlistHTML += "<img src='"+video.thumbnailURL+"' />";
			playlistHTML += "<h5>"+video.name+"<span class='time'> " + BCGannett.getDateForDisplay(video) + "</span></h5>";
			playlistHTML += "</li>\n";
		}
		
		Sizzle("#"+pTabID)[0].innerHTML = playlistHTML; //adds the list items to the UL container for the playlist

        BCGannett.fixPNG('.thumbBorder');

		BCGannett.addOnClickEventForVideo(Sizzle("#"+pTabID + " li"), false);
		
		var tabItems = Sizzle("ul.tabs li");
		
		for(var i = 0; i < tabItems.length; i++) //loops through each of the tabs
		{
			var listItem = tabItems[i];
			listItem.onclick = function()
			{
				//changes the display of the tabs to deselected
				for(var j = 0; j < tabItems.length; j++)
				{
					var tabItem = tabItems[j];
					BCGannett.removeClass(tabItem, "selected");
				}
				
				BCGannett.addClass(this, "selected"); //makes the clicked tab display correctly
				
				//populates the related videos tab if it's empty 
				//(that's checked in the getRealtedVideos() function)
				if(this.getAttribute("name").toLowerCase() == "relatedvideos") BCGannett.getRelatedVideos(); 
				
				var unorderedLists = Sizzle(".videoList ul");
				
				//hides all of the UL containers for the playlists
				for(var j = 0; j < unorderedLists.length; j++)
				{
					var ul = unorderedLists[j];
					BCGannett.removeClass(ul, "selected");
					BCGannett.addClass(ul, "hidden");
				}
			
				//shows the UL container for the clicked tab based the name attribute
				var listID = "#" + this.getAttribute("name");
				BCGannett.removeClass(Sizzle(listID)[0], "hidden");
				BCGannett.addClass(Sizzle(listID)[0], "selected"); //shows the right UL container
			}
		}
		
		if(pTabID == "nextUp" && BCGannett.currentVideo) BCGannett.removeVideoFromNextUp(BCGannett.currentVideo.id);
	},
	//------------------------------------------------------------------- 	
	
	
		
	//------------------------------------------------------------------- NEXT UP VIDEO LOGIC
	getNextUpVideo: function()
	{
		var nextUpVideos = Sizzle("#nextUp li");
		var nextVideo;
		var defaultVideo;
		
		for(var i = 0; i < nextUpVideos.length; i++)
		{
			var video = nextUpVideos[i];
			if(video.getAttribute("videoID") == BCGannett.currentVideo.id && video.getAttribute("viewed") == "true" && i+1 < nextUpVideos.length)
			{
				nextVideo = nextUpVideos[i+1];
				
				//jump to the video in the list that's next up
				var tabItemHeight = BCGannett.fullHeight(Sizzle("#nextUp li")[0]);
				var offsetToJump = i+1;
				Sizzle("#nextUp")[0].scrollTop = tabItemHeight * offsetToJump;
				
				break;
			}
			else if(video.getAttribute("viewed") == "false" && !defaultVideo)
			{
				//if the video doesn't get found in the if block, we try and grab the first non-viewed video we can find
				defaultVideo = video;
				nextVideo = defaultVideo;
			}
		}
		
		//show the "next up" tab regardless of what tab we're in
		var nextUpTab = Sizzle("#related ul.tabs li.nextUp")[0];
		nextUpTab.onclick();
		
		if(nextVideo) BCGannett.onVideoClicked(nextVideo, false);
	},
	
	removeVideoFromNextUp: function(pVideoID)
	{ 
		var nextUpVideos = Sizzle("#nextUp li");
		for(var i = 0; i < nextUpVideos.length; i++)
		{
			var video = nextUpVideos[i];
			var videoID = video.getAttribute("videoID");
			if(videoID == pVideoID)
			{
				video.setAttribute("viewed", "true");
			}
		}
	},
	//------------------------------------------------------------------- 

	
	getRelatedVideos: function()
	{
		//------------------------------------ RELATED VIDEOS UPDATE
		if(Sizzle("#relatedVideos li").length == 0)
		{
			Sizzle("#relatedVideos")[0].innerHTML = BCGannett.getAjaxLoader("dark");
			
			var urlVariables = 
			{
				command: "find_related_videos",	
				video_id: BCGannett.currentVideo.id,
				video_fields: "id,name,length,tags,shortDescription,thumbnailURL",
				page_size: 12,
				token: BCGannett.token,
				callback: "BCGannett.onRelatedVideos"	
			}
	
			BCGannett.addScriptTag(BCGannett.mediaAPIURL, urlVariables);
		}
		//------------------------------------
	},
	
	onRelatedVideos: function(pResponse)
	{
		if(pResponse.items[0])
		{
			BCGannett.addVideosToTab(pResponse.items, "relatedVideos");
			BCGannett.relatedVideos = BCGannett.relatedVideos.concat(pResponse.items);
		}
		else
		{
			BCGannett.addVideosToTab(BCGannett.playlists[BCGannett.nextUpPlaylistID].videos, "relatedVideos");
		}
	},
	
	getAjaxLoader: function(pTheme, pClass)
	{
		var image;
		switch(pTheme)
		{
			case "dark":
				image = "ajax-loader-dark.gif";
				break;
			case "light":
				image = "ajax-loader-light.gif";
				break;
			default:
				image = "ajax-loader-light.gif";
		}
		
		var loaderClass = "ajaxLoader";
		if(pClass) loaderClass += " " + pClass;
		
		return "<img src='" + BCGannett.imageUrl + image + "' class='" + loaderClass + "' />";
	},
	
	//----------------------------------------------------------------- SEARCH FUNCTIONS
	searchForVideos: function(pSearchTerm)
	{		
		if(pSearchTerm)
		{
			BCGannett.searchTerm = pSearchTerm;
			
			var urlVariables = 
			{
				command: "find_videos_by_text",
				text: pSearchTerm.replace(/ /g, "+"),
				video_fields: "id,name,shortDescription,tags,length,thumbnailURL",
				callback: "BCGannett.onSearchComplete",
				get_item_count: true,
				token: this.token
			}
			
			this.addScriptTag(BCGannett.mediaAPIURL, urlVariables);
			
			Sizzle("#pushDownContainer .numberOfResults:first")[0].innerHTML = "";
			Sizzle("#slideContainer .videos:first")[0].innerHTML = BCGannett.getAjaxLoader("light", "searched");

		}
	},
	
	onSearchComplete: function(pResponse)
	{
		//If there are no results due to an error we should handle the exception
		
		BCGannett.fixPNG('#slideContainer, #navigationLeft, #close, #left, #right, .video, .button');
		
		//BCGannett.changeDisplayForSearch(true);
		BCGannett.openSlideContainer(function ()
		{ 
			BCGannett.changeDisplayForSearch(true);
		});
			
		if(pResponse.items) 
		{
			BCGannett.relatedVideos = BCGannett.relatedVideos.concat(pResponse.items);
			BCGannett.displayVideosInSlider(pResponse.items);
			
		} 
		else 
		{
			BCGannett.displayNoResultsMessage();
		}
		
	},
	
	changeDisplayForSearch: function(pDisplayForSearch)
	{
		if(pDisplayForSearch)
		{	
			//added to resolve IE 6 wackyness
			Sizzle("#left")[0].style.left = 15;
			Sizzle("#close")[0].style.display = "none";
			Sizzle("#navigationLeft")[0].style.display = "none";
			// end wackyness
			
			Sizzle("#searchResults")[0].style.display = "block";
			Sizzle("#close")[0].style.visibility = "hidden";
			Sizzle("#searchResults div.close")[0].style.visibility = "visible";
			Sizzle("#navigationLeft")[0].style.visibility = "hidden";
			
			BCGannett.addClass(Sizzle("#pushDownContainer span.numberOfResults")[0], "searched");
			BCGannett.addClass(Sizzle("#slideContainer")[0], "searched");
			BCGannett.addClass(Sizzle("#left")[0], "searched");
			
			
		}
		else
		{
			//added to resolve IE 6 wackyness
			Sizzle("#left")[0].style.left = 186;
			Sizzle("#close")[0].style.display = "block";
			Sizzle("#navigationLeft")[0].style.display = "block";
			// end wackyness
			
			Sizzle("#searchResults")[0].style.display = "none";
			Sizzle("#close")[0].style.visibility = "visible";
			Sizzle("#searchResults div.close")[0].style.visibility = "hidden";
			Sizzle("#navigationLeft")[0].style.visibility = "visible";
			
			BCGannett.removeClass(Sizzle("#pushDownContainer span.numberOfResults")[0], "searched");
			BCGannett.removeClass(Sizzle("#slideContainer")[0], "searched");
			BCGannett.removeClass(Sizzle("#left")[0], "searched");
		}
	},
	//----------------------------------------------------------------- 
	
	
	//----------------------------------------------------------------- DEEP LINK FUNCTIONS
	createDeepLink: function(pVideoID, pVideo)
	{
		if(this.videoPlayerModule.getContentTypeDisplayed().toLowerCase() !== "ad")
		{
			var newExtension;
		
			for(var playlistID in BCGannett.playlists)
			{
				var playlist = BCGannett.playlists[playlistID];
				
				if(playlist.videos) //to keep this working in IE
				{
					for(var j = 0; j < playlist.videos.length; j++)
					{
						var video = playlist.videos[j];
						
						if(video.id == pVideoID)
						{
							if(playlist.playerID && playlist.id && video.id)
							{
								newExtension = "#/" + BCGannett.urlEncode(playlist.name) +
									"/" + BCGannett.urlEncode(video.name) +
									"/" + playlist.playerID + 
									"/" + playlist.id + 
									"/" + video.id;
								
								window.location = BCGannett.baseURL + newExtension;
								return;
							}
						}
					}	
				}
			}
		
			//if the full deep link couldn't be created, just use the video name and ID
			for(var i = 0; i < BCGannett.relatedVideos.length; i++)
			{
				var video = BCGannett.relatedVideos[i];
				
				if(video.id == pVideoID)
				{
					newExtension = "#/" + BCGannett.urlEncode(video.name) + "/" + video.id;
					window.location = BCGannett.baseURL + newExtension;
					return;
				}
			}
			
			if(pVideo) //if we've made it this far, we can use the optional video DTO param to make the URL
			{
				newExtension = "#/" + BCGannett.urlEncode(pVideo.displayName) + "/" + pVideo.id;
				window.location = BCGannett.baseURL + newExtension;
				return;
			}
		}
	},
	
	digForDeepLink: function(pURL)
	{
		if(pURL.indexOf("#") == -1)
		{
			return false;
		}
		else
		{
			var urlPieces = pURL.split("#/")[1].split("/");
			if(urlPieces.length > 2) //the full deep link 
			{
				/*
				 * 0: Economy
				 * 1: Meet+the+Experts%3A+Catherine+Reagor
				 * 2: 32618510001 - player id
				 * 3: 32229584001 - playlist id
				 * 4: 34536544001 - video id
				 */
				
				//BCGannett.defaultPlaylistID = urlPieces[3];
				BCGannett.videoIDToCue = (urlPieces[4] !== "null") ? urlPieces[4] : null;
				BCGannett.nextUpPlaylistID = (urlPieces[3] !== "null") ? urlPieces[3] : null;
				BCGannett.currentSection.id = (urlPieces[2] !== "null") ? urlPieces[2] : null;
			}
			else //only the video name and id
			{
				BCGannett.videoIDToCue = urlPieces[1];
			}
		}
	},
	//----------------------------------------------------------------- 
	
	
	//----------------------------------------------------------------- GRID VIEW FUNCTIONS
	addPlaylistsToGrid: function(pPlayerID)
	{
		Sizzle("#videoGridHeader h3")[0].innerHTML = "All " + BCGannett.currentSection.name + " Videos";
		Sizzle("#videoGridPlaylists ul.playlists")[0].innerHTML = BCGannett.playlistsNavHTML;
		
		BCGannett.lazyLoading = true;
		BCGannett.videoGridVideosCopy = BCGannett.videoGridVideos.slice(0);
		BCGannett.addVideosToGrid(true);
		
		var playlists = Sizzle("#videoGridPlaylists ul.playlists li.playlist");
		for(var i = 0 ; i < playlists.length; i++)
		{
			var playlist = playlists[i];
			
			if(!BCGannett.hasClass(playlist, "parent"))
			{				
				playlist.onclick = function()
				{
					BCGannett.filterVideoGridVideos(this);
				};
			}
		}
	},
	
	addVideosToGrid: function(clearVideosFirst)
	{
		if(BCGannett.lazyLoadingTimeout)
		{
			clearTimeout(BCGannett.lazyLoadingTimeout);
			BCGannett.lazyLoadingTimeout = null;
			Sizzle("#videoGridVideos ul")[0].removeChild(Sizzle("#videoGridVideos ul div.ajaxLoader")[0]);
		}
		
		var videosHTML = "";
		
		if(clearVideosFirst) //basically, is true when a user clicks the all videos header and "resets" the grid
		{
			BCGannett.videoGridVideosCopy = BCGannett.videoGridVideos.slice(0);
			BCGannett.lazyLoading = true;
			Sizzle("#videoGridVideos")[0].scrollTop = 0;
			Sizzle("#videoGridVideos")[0].innerHTML = ""; //makes sure we empty the grid first
		}
		
		if(Sizzle("#videoGridVideos ul.videos li").length <= 0) Sizzle("#videoGridVideos")[0].innerHTML += "<ul class='videos'></ul>\n";
        
        //adds videos to the grid if there are still videos to add
        for(var i = 0; i < BCGannett.numberOfGridVideosToLoad; i++)
        {
        	if(BCGannett.videoGridVideosCopy.length > 0)
        	{
        		var videoItem = BCGannett.videoGridVideosCopy.reverse().pop();  
        		if(videoItem)
        		{
        			videosHTML += BCGannett.createVideoGridListItem(videoItem);
        		}        
        	}
        	else
        	{
        		break;
        	}
        }
        
		
		if(clearVideosFirst) Sizzle("#videoGridVideos ul")[0].innerHTML = videosHTML;
		else Sizzle("#videoGridVideos ul")[0].innerHTML += videosHTML;
		
		BCGannett.updateVideoGridDisplay();
		BCGannett.fixPNG('#videoGridVideos');
	},
	
	filterVideoGridVideos: function(pElem)
	{			
		playlistID = pElem.id;
		
		//remove the selected playlist if exists
		try 
		{ 
			var selectedItem = Sizzle("#videoGridPlaylists ul.playlists li.active")[0];
            if (selectedItem)
            { 
            	BCGannett.removeClass(selectedItem, "active");
            }
            
            BCGannett.addClass(pElem, "active");

		} 
		catch(pError) 
		{
			//gulp
		}
		
		var videosHTML = "";
		var videos = (BCGannett.playlists[playlistID]) ? BCGannett.playlists[playlistID].videos : [];
		
		for(var i = 0; i < videos.length; i++)
		{
			var video = videos[i];
			
			videosHTML += BCGannett.createVideoGridListItem(video);
		}
		
		Sizzle("#videoGridVideos ul")[0].innerHTML = videosHTML;
		var currentTotalHeight = Sizzle("#videoGridVideos ul.videos li").length/4 * BCGannett.fullHeight(Sizzle("#videoGridVideos ul.videos li.video:first")[0]);
		
		BCGannett.lazyLoading = false;
		BCGannett.updateVideoGridDisplay(currentTotalHeight);
		Sizzle("#videoGridVideos")[0].scrollTop = 0;
	},
	
	updateVideoGridDisplay: function(pHeight)
	{		
		var videos = Sizzle("#videoGridVideos ul.videos li.video");
		var hoverSpans = Sizzle("#videoGridVideos ul.videos li.video span.hoverContainer");
		for(var i = 0; i < videos.length; i++)
		{
			var video  = videos[i];
                        var hoverSpan = hoverSpans[i];
			video.onclick = function(pEvent)
			{
				BCGannett.onVideoClicked(this, true);
			};
                        hoverSpan.onmouseover = function(pEvent)
			{
                                this.coordinates = BCGannett.findPos(document.getElementById("bcImmersivePlayerContainer"));
				BCGannett.descriptionMouseOverEvent = this;
				BCGannett.descriptionOverlayTimeout = setTimeout("BCGannett.showDescriptionOverlay()", BCGannett.descriptionOverlayDelay * 1000);                                
			};
                        hoverSpan.onmouseout = function(pEvent)
			{
				clearTimeout(BCGannett.descriptionOverlayTimeout);
				var shortDescriptionDiv = Sizzle("#shortDescriptionOverlay")[0];
				BCGannett.fadeOut(shortDescriptionDiv);
			};
                        hoverSpan.onmousemove = function(pEvent)
			{	
				try {
					var shortDescriptionDiv = Sizzle("#shortDescriptionOverlay")[0];
					shortDescriptionDiv.style.top = BCGannett.mouseY(pEvent) - 130 - this.coordinates[1] + "px";
					shortDescriptionDiv.style.left = BCGannett.mouseX(pEvent) - 155 - this.coordinates[0] + "px";
				} catch (e) {
					//swalling error as I don't want to throw anything just to move the desc.
				}
			};
		}
		
		Sizzle("#videoGridVideos")[0].onscroll = function(pEvent)
		{
			var containerHeight = BCGannett.fullHeight(Sizzle("#videoGridVideos ul")[0]);
			var threshold = (this.scrollTop + containerHeight)/this.scrollHeight;
			
			if(threshold > .9 && BCGannett.lazyLoading && !BCGannett.lazyLoadingTimeout && (BCGannett.videoGridVideosCopy.length > 0))
			{
				BCGannett.lazyLoadingTimeout = setTimeout("BCGannett.addVideosToGrid()", 625); //important to have this first (timing issues)
				Sizzle("#videoGridVideos")[0].scrollTop = this.scrollHeight; //makes sure the user sees the loading icon
				Sizzle("#videoGridVideos ul")[0].innerHTML += "<div class='ajaxLoader' style='clear: both;'>" + BCGannett.getAjaxLoader("dark") + "</div>";
			}
		};
	},
	
	createVideoGridListItem: function(video)
	{
        if(this.debug && typeof(video) == "undefined")
        {
            //console.log(arguments.callee.caller + " passed an undefined video")
        }
        
        var thumbnail = (video.thumbnailURL) ? video.thumbnailURL : BCGannett.imageUrl + "clear.gif";

		var videoHTML = "";
		videoHTML += "<li class='video' videoID='" + video.id + "' playlistID='" + video.playlist.id + "' liveStream='" + video.liveStream + "'>\n";
		videoHTML += "<span class='corner topLeft'></span>\n";
		videoHTML += "<span class='corner topRight'></span>\n";
		videoHTML += "<span class='corner bottomLeft'></span>\n";
		videoHTML += "<span class='corner bottomRight'></span>\n";
		videoHTML += "<span class='hoverContainer'></span>\n";
		videoHTML += "<span class='thumbBorder'></span>\n";
		videoHTML += "<img src='" + thumbnail + "' />\n";
		videoHTML += "<p>" + video.name + "</p>\n";
		videoHTML += "<span class='time'>" + BCGannett.getDateForDisplay(video) + "</span>\n";
		videoHTML += "</li>\n";
		
		return videoHTML;
	},
	//-----------------------------------------------------------------
	
	
	
	//----------------------------------------------------------------- HELPER FUNCTIONS
	getStyle: function(pElement, pStyleName) 
	{
	    if(pElement.style[pStyleName]) // If the property exists in style[], then it's been set recently (and is current)
	    {
	    	return Number(pElement.style[pStyleName].split("px")[0]);
		}
	    else if(pElement.currentStyle) // Otherwise, try to use IE's method
	    {
	        return Number(pElement.currentStyle[pStyleName].split("px")[0]);
		}
	    else if(document.defaultView && document.defaultView.getComputedStyle) // Or the W3C's method, if it exists
	    {
	        // It uses the traditional 'text-align' style of rule writing, instead of textAlign
	        pStyleName = pStyleName.replace(/([A-Z])/g,"-$1");
	        pStyleName = pStyleName.toLowerCase();
	
	        // Get the style object and get the value of the property (if it exists)
	        var styles = document.defaultView.getComputedStyle(pElement, "");
	        return styles && Number(styles.getPropertyValue(pStyleName).split("px")[0]);
	    } 
	    else // Otherwise, we're using some other browser
	    {
	    	return null;
	    }    
	},
	
	// Get the actual height (using the computed CSS) of an element
	getHeight: function(pElement) 
	{
	    // Gets the computed CSS value and parses out a usable number
	    return parseInt(BCGannett.getStyle(pElement, 'height'));
	},
	
	// Get the actual width (using the computed CSS) of an element
	getWidth: function(pElement) 
	{
	    // Gets the computed CSS value and parses out a usable number
	    return parseInt(BCGannett.getStyle(pElement, 'width'));
	},

	fullHeight: function(pElement) 
	{
		//Find the full, possible, height of an element (not the actual, current, height)
	
	    // If the element is being displayed, then offsetHeight
	    // should do the trick, barring that, getHeight() will work
	    if(BCGannett.getStyle(pElement, "display") !== "none")
	    {
	    	return pElement.offsetHeight || BCGannett.getHeight(pElement);
		}
		
	    // Otherwise, we have to deal with an element with a display
	    // of none, so we need to reset its CSS properties to get a more
	    // accurate reading
	    var originalStyles = resetCSS(pElement, {
	        display: "",
	        visibility: "hidden",
	        position: "absolute"
	    });
	
	    // Figure out what the full height of the element is, using clientHeight
	    // and if that doesn't work, use getHeight
	    var height = pElement.clientHeight || BCGannett.getHeight(pElement);
	
	    // Finally, restore the CSS properties back to what they were
	    BCGannett.restoreCSS(pElement, originalStyles);
	
	    // and return the full height of the element
	    return height;
	},
	
	// Find the full, possible, width of an element (not the actual, current, width)
	fullWidth: function(pElement) 
	{
	    // If the element is being displayed, then offsetWidth
	    // should do the trick, barring that, getWidth() will work
	    if(BCGannett.getStyle(pElement, "display") !== "none") return pElement.offsetWidth || BCGannett.getWidth(pElement);
	
	    // Otherwise, we have to deal with an element with a display
	    // of none, so we need to reset its CSS properties to get a more
	    // accurate reading
	    var originalStyles = BCGannett.resetCSS(pElement, {
	        display: "",
	        visibility: "hidden",
	        position: "absolute"
	    });
	
	    // Figure out what the full width of the element is, using clientWidth
	    // and if that doesn't work, use getWidth
	    var width = pElement.clientWidth || BCGannett.getWidth(pElement);
	
	    // Finally, restore the CSS properties back to what they were
	    BCGannett.restoreCSS(pElement, originalStyles);
	
	    // and return the full width of the element
	    return width;
	},
	
	//A function used for setting a set of CSS properties, which can then be restored back again later
	resetCSS: function(pElement, pProperty) 
	{
	    var originalStyles = {};
		   
	    for(var property in pProperty) //Go through each of the properties
	    {
	        originalStyles[property] = pElement.style[property]; //Remember the old property value
	        pElement.style[property] = pProperty[property]; //And set the new value
	    }
	
	    return originalStyles;  //Retun the set of changed values, to be used by restoreCSS
	},
	
	restoreCSS: function(pElement, pProperty) //A function for restoring the side effects of the resetCSS function
	{
	    // Reset all the properties back to their original values
	    for (var property in pProperty) pElement.style[property] = pProperty[property];
	},
	
	hasClass: function(pElement, pClassName)
	{
		if(pElement.className.indexOf(pClassName) !== -1) return true;
		else return false;
	},
	
	addClass: function(pElement, pClassName)
	{
		if(pElement.className.indexOf(pClassName) == -1)
		{
			var newClassName = (pElement.className) ? pElement.className + " " + pClassName : pClassName;
			
			pElement.className = newClassName;
		}
	},
	
	removeClass: function(pElement, pClassName)
	{
		if(pElement.className && pElement.className.indexOf(pClassName) !== -1)
		{
			var classToRemove = new RegExp('\\b' + pClassName + '\\b');
			pElement.className = pElement.className.replace(classToRemove, "");
		}
	},
	
	setOpacity:function (pElement, pOpacityLevel) 
	{
	    if (pElement.filters) pElement.filters.alpha.opacity = pOpacityLevel; //If filters exist, then this is IE, so set the Alpha filter
	    else pElement.style.opacity = pOpacityLevel / 100; //Otherwise use the W3C opacity property
	},
	
	mouseX: function(evt)
	{
		if (!evt) evt = window.event;
		if (evt.pageX)
		return evt.pageX;
		else if (evt.clientX)
		return evt.clientX +(document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft);
		else return 0;
	},
	
	mouseY: function (evt) {
		if (!evt) evt = window.event;
		if (evt.pageY)
		return evt.pageY;
		else if (evt.clientY)
		return evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop);
		else return 0;
	},
	
	//Adding helper function to get the coordinates of particular element
	findPos: function (obj) {
		if(obj == null) {
        	return null;
    	}
    	
    	var curleft = curtop = 0;
    	if (obj.offsetParent) {
        	curleft = obj.offsetLeft
        	curtop = obj.offsetTop
        	while (obj = obj.offsetParent) {
            	curleft += obj.offsetLeft
            	curtop += obj.offsetTop
        	}
    	}
    	return [curleft,curtop];
	},
	
	getDateForDisplay: function(pVideo)
	{
		var date = new Date(pVideo.length);
		var dateOrLive = (BCGannett.hasTag(pVideo.tags, "live=")) ? "(Live)" : "("+date.getMinutes()+"m"+date.getSeconds()+"s)";
		
		return dateOrLive;
	},	
	
	hasTag: function(pTags, pTagToFind)
	{
		for(var j = 0; j < pTags.length; j++)
		{
			var tag = pTags[j];
			if(tag.indexOf(pTagToFind) !== -1) return true;
		}
		
		return false;
	},
	
	createXMLObject: function(pString)
	{
		var adXML;
		
		if (window.ActiveXObject)
	  	{
			//parses the XML for IE browsers
			adXML = new ActiveXObject("Microsoft.XMLDOM");
			adXML.async = false;
			adXML.loadXML(pString);
		}
		else if (window.XMLHttpRequest)
		{
			adXML = (new DOMParser()).parseFromString(pString, "text/xml"); //parses the XML for Mozilla browsers
		}
		
		return adXML;
	},
	
	addScriptTag: function(pURL, pURLVariables)
	{
		var url = pURL + "?";
	
		for(var item in pURLVariables)
		{
			url += item + "=" + pURLVariables[item] +"&";
		}
		
		var scriptElem = document.createElement('script'); 
	    scriptElem.setAttribute('src', url); 
	    scriptElem.setAttribute('type','text/javascript'); 
	    document.getElementsByTagName('head')[0].appendChild(scriptElem);
		
	},
	
	urlEncode: function(clearString)
	{
		//pulled from: http://cass-hacks.com/articles/code/js_url_encode_decode/
		var output = '';
		var x = 0;
		clearString = clearString.toString();
		var regex = /(^[a-zA-Z0-9_.]*)/;
		while (x < clearString.length) 
		{
			var match = regex.exec(clearString.substr(x));
			if (match != null && match.length > 1 && match[1] != '') 
			{
				output += match[1];
				x += match[1].length;
			} 
			else 
			{
				if (clearString[x] == ' ')
					output += '+';
				else 
				{
					var charCode = clearString.charCodeAt(x);
					var hexVal = charCode.toString(16);
					output += '%' + ( hexVal.length < 2 ? '0' : '' ) + hexVal.toUpperCase();
				}
				x++;
			}
		}
		return output;
	},
	//-----------------------------------------------------------------
	
	recommend: function()
	{
		if(typeof gReactions == "function") gReactions(); //for recommendations
	},
	
	getSSTSCode: function()
	{
		if(BCGannett.initialSSTSCode)
		{
			var code = BCGannett.initialSSTSCode;
			return code;
		}
		return BCGannett.currentSection.sstsCode;
	},
	
	getAdServerURL: function(pAdServerURLBegin, pAdServerURLEnd)
	{
		return pAdServerURLBegin + BCGannett.getSSTSCode() + pAdServerURLEnd;
	},
	
	//----------------------------------------------------------------- BRIGHTCOVE PLAYER API STUFF
	playerAPIInit: function(pExperienceID) 
	{
		this.bcPlayer;
		this.experienceModule;
		this.videoPlayerModule;
		this.advertisingModule;
		this.socialModule;
		this.menuModule;
		
		this.mediaCompleted;
		
		this.bcPlayer = brightcove.getExperience(pExperienceID);
		this.experienceModule = this.bcPlayer.getModule(APIModules.EXPERIENCE);
		this.experienceModule.addEventListener(BCExperienceEvent.TEMPLATE_READY, this.onTemplateReady);
		
		this.videoPlayerModule = this.bcPlayer.getModule(APIModules.VIDEO_PLAYER);
		this.videoPlayerModule.addEventListener(BCMediaEvent.PLAY, BCGannett.onMediaPlay);
		this.videoPlayerModule.addEventListener(BCMediaEvent.BEGIN, BCGannett.onMediaBegin);
		this.videoPlayerModule.addEventListener(BCMediaEvent.CHANGE, BCGannett.onMediaChange);
		this.videoPlayerModule.addEventListener(BCMediaEvent.COMPLETE, BCGannett.onMediaComplete);
		
		this.advertisingModule = this.bcPlayer.getModule(APIModules.ADVERTISING);
		this.advertisingModule.addEventListener(BCAdvertisingEvent.EXTERNAL_AD, BCGannett.onExternalAd);
		
		this.socialModule = this.bcPlayer.getModule(APIModules.SOCIAL);
		this.socialModule.addEventListener(BCSocialEvent.EMBED_CODE_RETRIEVED, BCGannett.onEmbedCodeRetrieved);
		
		this.menuModule = this.bcPlayer.getModule(APIModules.MENU);
		this.menuModule.addEventListener("menuPageOpen", BCGannett.handleEndScreenInteraction);
		this.menuModule.addEventListener("menuPageClose", BCGannett.handleEndScreenMenuClose)
	},
	
	onTemplateReady: function(pEvent)
	{	
		BCGannett.advertisingModule.enableExternalAds();
		
		//setup event listeners here when needed
		if(BCGannett.videoIDToCue) 
		{
			BCGannett.videoPlayerModule.loadVideo(BCGannett.videoIDToCue, BCGannett.videoOrRefID);
			BCGannett.videoOrRefID = "id";
			BCGannett.createDeepLink(BCGannett.videoIDToCue);
		}
	},
	
	loadVideo: function(pVideoID)
	{
		if(this.videoPlayerModule.getContentTypeDisplayed() != "ad") 
		{
			this.videoPlayerModule.loadVideo(pVideoID, BCGannett.videoOrRefID);
			BCGannett.videoOrRefID = "id";
			BCGannett.createDeepLink(pVideoID);
		}
	},
	
	onMediaPlay: function(pEvent)
	{
		if(BCGannett.mediaCompleted)
		{
			BCGannett.mediaCompleted = false;
			
			if(BCGannett.nextUpVideoTimeout)
			{
				clearTimeout(BCGannett.nextUpVideoTimeout);
				BCGannett.nextUpVideoTimeout = null;
			}
		}
	},
	
	onMediaBegin: function(pEvent)
	{
		if(!BCGannett.firstVideoPlayed) BCGannett.firstVideoPlayed = true;
	},
	
	onMediaChange: function(pEvent)
	{	
		//prevent the next up video playing automatically in case someone chose a video on their own
		if(BCGannett.nextUpVideoTimeout)
		{
			clearTimeout(BCGannett.nextUpVideoTimeout);
			BCGannett.nextUpVideoTimeout = null;
		}
		
		BCGannett.menuModule.closeMenuPage(); //keep the video from playing back in the tiny window
		
		//update our global video object
		var video = BCGannett.videoPlayerModule.getCurrentVideo();
		BCGannett.currentVideo = video;
		
		BCGannett.createDeepLink(video.id, video);
		BCGannett.socialModule.getEmbedCode();
		BCGannett.socialModule.setLink(window.location.toString());
		
		try
		{
			//update the ad server url
			var adPolicy = new Object();
			adPolicy.adServerURL = BCGannett.getAdServerURL(
				BCGannett.experienceModule.getPlayerParameter("adServerURLBegin"), 
				BCGannett.experienceModule.getPlayerParameter("adServerURLEnd"));
			adPolicy.prerollAds = true;
			BCGannett.advertisingModule.setAdPolicy(adPolicy);
		}
		catch(pError)
		{
			//gulp
			//likely that the adServerURL wasn't set in the player parameters
		}
		
		if(BCGannett.firstVideoPlayed && BCGannett.changeSSTSCode) BCGannett.currentSection.sstsCode = BCGannett.currentSection.tempSSTSCode;
		if(BCGannett.firstVideoPlayed && BCGannett.initialSSTSCode) BCGannett.initialSSTSCode = null;
		
		//updates the video info below the player
		Sizzle("#videoInfo h2:first")[0].innerHTML = video.displayName;
		Sizzle("#videoInfo p:first")[0].innerHTML = video.shortDescription;

		if(video.linkURL && video.linkText) 
		{
			var relatedLink = "<a href='" + video.linkURL + "' target='_blank'>" + video.linkText + "</a>";
			Sizzle("#videoInfo span.relatedLink:first")[0].innerHTML = relatedLink;
		}
		else Sizzle("#videoInfo span.relatedLink:first")[0].innerHTML = "";
		
		//updates the related videos tab
		Sizzle("#relatedVideos")[0].innerHTML = ""; //now i can check to see if it's empty before making an API call to fill it
		if(BCGannett.hasClass(Sizzle("#relatedVideos")[0], "selected")) BCGannett.getRelatedVideos();
		
		//marks this video as "viewed" in the next up tab
		BCGannett.removeVideoFromNextUp(video.id);
		BCGannett.recommend();
	},
	
	onMediaComplete: function(pEvent)
	{
		BCGannett.mediaCompleted = true;
		BCGannett.nextUpVideoTimeout = setTimeout("BCGannett.getNextUpVideo()", BCGannett.nextUpAutoAdvanceDelay * 1000);
	},
	
	handleEndScreenInteraction: function(pEvent)
	{
		try 
		{
			if(BCGannett.mediaCompleted) 
			{
			
				if(pEvent.args.page === "Email" || pEvent.args.page == "Link" || pEvent.args.page == "Embed") 
				{
					if(BCGannett.nextUpVideoTimeout)
					{
						clearTimeout(BCGannett.nextUpVideoTimeout);
						BCGannett.nextUpVideoTimeout = null;
					}
				} else if(pEvent.args.page === "Info") {
					if(BCGannett.nextUpVideoTimeout == null)
					{
						BCGannett.nextUpVideoTimeout = setTimeout("BCGannett.getNextUpVideo()", BCGannett.nextUpAutoAdvanceDelay * 1000);
					}
				}
			}
		} catch(e) {
			//gulp.  I don't want to cause any errors for a safeguarding feature.
		}
		
	},
	
	handleEndScreenMenuClose: function(pEvent)
	{
		if(BCGannett.mediaCompleted && BCGannett.nextUpVideoTimeout == null)
		{
			BCGannett.nextUpVideoTimeout = setTimeout("BCGannett.getNextUpVideo()", BCGannett.nextUpAutoAdvanceDelay * 1000);
		}
		
	},
	
	onExternalAd: function(pAdString, callback)
	{
		/*
		* Options that can be passed in:
		* type: [expandedBanner, collapsedBanner, both] (defaults to expandedBanner)
		* expandedId: the element ID of where the expanded banner should be placed
		* collapsedId: the element ID of where the collapsed banner should be placed
		* 
		* "Expanded Banner": This is a throwback to the older monolithic templates we used to use, but the terminology
		* remained because that's what it still says in the ad XML, but typically an expanded banner is a 300x250 unit,
		* although it could be anything. It's called the expanded banner because in the larger templates you can click
		* an "expand" button to reshow the 300x250 at any point.
		* 
		* "Collapsed Banner": Also a throwback, but the collapsed banner is usually a 728x90 but could be any unit. It's 
		* called so because the collapsed banner had a relationship to the expanded banner where when the 300x250 animated
		* off screen, it looked like it "collapsed" into the 728x90.
		*/
		new ExternalAd(pAdString, BCGannett.currentSection.sstsCode, {});
	},
	
	onEmbedCodeRetrieved: function(pEvent)
	{
		//adds the custom flash vars to the current embed code so that it travels with the player as well
		var snippet = pEvent.snippet;
		
		if(!BCGannett.originalFlashVars)
		{
			//need to save this globally, otherwise we keep appending the values over and over when videos change
			BCGannett.originalFlashVars = snippet.split('flashVars="')[1].split('"')[0];
		}
		
		var newFlashVars = 'omnitureAccountID=' + BCGannett.experienceModule.getPlayerParameter("omnitureAccountID") + '&' + 
			'pageContentCategory=' + BCGannett.experienceModule.getPlayerParameter("pageContentCategory") + '&' + 
			'pageContentSubcategory=' + BCGannett.experienceModule.getPlayerParameter("pageContentSubcategory") + '&' + 
			'marketName=' + BCGannett.experienceModule.getPlayerParameter("marketName") + '&' + 
			'revSciZip=' + BCGannett.experienceModule.getPlayerParameter("revSciZip") + '&' + 
			'revSciAge=' + BCGannett.experienceModule.getPlayerParameter("revSciAge") + '&' + 
			'revSciGender=' + BCGannett.experienceModule.getPlayerParameter("revSciGender") + '&' + 
			'division=' + BCGannett.experienceModule.getPlayerParameter("division") + '&' + 
			'SSTSCode=' + BCGannett.currentSection.sstsCode + '&' + 
			BCGannett.originalFlashVars + '\"';
			
		var objectFlashVars = '<param name="flashVars" value="' + newFlashVars;
		var embedFlashVars = 'flashVars="' + newFlashVars;
			
		snippet = snippet.replace(new RegExp('<param name="flashVars" value="[^ \t\v\n\r\f]*"'), objectFlashVars);
		snippet = snippet.replace(new RegExp('flashVars="[^ \t\v\n\r\f]*"'), embedFlashVars);
		
		BCGannett.socialModule.setEmbedCode(snippet);
	},
	
	clearTrainingTimeout: function()
	{
		if (BCGannett.trainingTimeout){
        	clearTimeout(BCGannett.trainingTimeout);
         }
	},

	getCookie: function(name)
	{
	    var cookies = document.cookie.split(/[; ]+/);
	    for (var i = 0 ; i < cookies.length; i++) {
	        if (cookies[i].substring(0,cookies[i].indexOf('=')) == name) {
	            return cookies[i];
	        }
	    }
	},
	
	setCookie: function(name, value)
	{
	    var expires = new Date();
	    expires.setDate(expires.getDate() + 365);
	    var curCookie = name + "=" + escape(value) + ((expires) ? "; expires=" + expires.toGMTString() : "");
	    document.cookie = curCookie;
	    return curCookie;
	}
	//-----------------------------------------------------------------
};

function onTemplateLoaded(pExperienceID)
{
	BCGannett.playerAPIInit(pExperienceID);
}

Brightcove_AjaxRequest = function(url, options)
{
	if(url) this.url = url;
	else throw new Error("You did not provide a URL for the Ajax request");
	
	var callback;
	
	if(options)
	{
		if(options.parameters) this.parameters = options.parameters;
		if(options.method) this.method = options.method;
		callback = (options.callback) ? options.callback : null;
		callback = (options.onSuccess) ? options.onSuccess : null;

		if(!this.method) this.method = "get";
	} 
	
	var ajaxRequest;

	if(this.parameters)
	{
		var urlVariables = "?";
		for(var item in this.parameters)
		{
			urlVariables += item + "=" + this.parameters[item] + "&";
		}
		this.url += urlVariables;
	}
	
     
	if (window.ActiveXObject) 
	{
		ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
		if (ajaxRequest) 
		{
			ajaxRequest.onreadystatechange = function(pEvent)
			{
				if (ajaxRequest.readyState == 4) 
				{
					if (ajaxRequest.status == 200) 
					{
						callback(ajaxRequest.responseText);
					} 
					else 
					{
						throw new Error("The Ajax request failed: "+ajaxRequest.statusText);
					}
				}
			};
			
			ajaxRequest.open(this.method, this.url, true);
			ajaxRequest.send();
		}
	}
	else if(window.XMLHttpRequest) 
	{
		ajaxRequest = new XMLHttpRequest();
		ajaxRequest.onreadystatechange = function(pEvent)
		{
			if(ajaxRequest.readyState == 4) 
			{
				if (ajaxRequest.status == 200) 
				{
					callback(ajaxRequest.responseText);
				} 
				else 
				{
					throw new Error("The Ajax request failed: "+ajaxRequest.statusText);
				}
			}
		};
		
		ajaxRequest.open(this.method, this.url, true);
		ajaxRequest.send(null);
	}
}

// Returns the version of Internet Explorer or a -1
// (indicating the use of another browser).
function bc_getInternetExplorerVersion() {
  var rv = -1; // Return value assumes failure.
  if (navigator.appName == 'Microsoft Internet Explorer')
  {
    var ua = navigator.userAgent;
    var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
    if (re.exec(ua) != null)
      rv = parseFloat( RegExp.$1 );
  }
  return rv;
}

function REV_SCI_NOTIFICATION(REV_SCI_ZIP, REV_SCI_AGE, REV_SCI_GENDER, SSTS_CODE)
{
	DM_addToLoc("zipcode", escape(s_ut.prop30));
	DM_addToLoc("age", escape(s_ut.prop31));
	DM_addToLoc("gender", escape(s_ut.prop32));
	DM_addToLoc("country", escape(s_ut.prop35));
	DM_addToLoc("job", escape(s_ut.prop33));
	DM_addToLoc("industry", escape(s_ut.prop34));
	DM_addToLoc("company size", escape(s_ut.prop39));
	DM_addToLoc("csp code", escape(s_ut.getQueryParam('csp')));
	DM_addToLoc("hhi", escape(RDBIncRange));

	var gci_ssts = SSTS_CODE;

	gci_ssts = gci_ssts.replace(/\//g,' > ');

	DM_cat(gci_ssts);
	DM_tag();
}
