// Initialize some global variables.
nowPlayingVideoID = 0;
nowPlayingSequence = "";
nowPlayingLive = false;
autoLive = "";
RSSurl = "";
currentVideo = 0;  // ID of the currently playing video.
activeCarousel = ""; // Name of the carousel whose video is currently playing (if relevant).
visibleCarousel = ""; // Name of the carousel currently visible, which may not be the active one.
activePlaylist = 0; // ID of a playlist whose videos are currently playing (if relevant)
schedWarningResponse = 0; // Track user response to pop-up notification of impending scheduled playlist. Used to avoid repeat warnings (and perhaps avoid all warnings later).
schedWarningResponse2 = 0; // Track user response to pop-up notification of impending scheduled video. Used to avoid repeat warnings (and perhaps avoid all warnings later).
carouselLeftPxSpacing = 178; // This width is used by the carousel code and might need to be changed if the size of our panels in the carousel change.
debugStr = "";
scheduledVideosPlaylistID = 111; // ID of playlist with scheduled videos; checked periodically via Ajax.
checkInterval = 60000;

//var carouselPos = new Array();
//carouselPos["customCarousel"] = 1;
//carouselPos["scheduledCarousel"] = 1;
//carouselPos["myplaylistCarousel"] = 1;
//carouselPos["liveCarousel"] = 1;
//carouselPos["featuredCarousel"] = 1;

function alertScheduledVideo(VideoID, VideoTitle) {
	// Show an alert for a scheduled video.
	//alert(VideoID+":"+nowPlayingVideoID);
	if (VideoID != nowPlayingVideoID) {
		alertScheduledVideoStart(VideoTitle, autoLive, scheduledVideosPlaylistID, VideoID);
	}
}

function monitorScheduledVideos() {
	// Checks the CCASTPLAYLISTSCHEDULE table against the current time and notifies the user if a new theme is starting. This function is meant to be called periodically.
	// Does not check while the "live" carousel is the active one.
	if (activeCarousel != "live") {
		var url = "ccast-micro.cfm?action=returnscheduledvideo";
		url = url + "&dummy=" + new Date().getTime();
		//alert(url);
		request.open("GET", url, true);
		request.onreadystatechange = monitorScheduledVideosResponse;
		request.send(null);
	}
}

function monitorScheduledVideosResponse() {
	if (request.readyState == 4) {
		if (request.status == 200) {
			var xmlDoc = request.responseXML;
			//alert(request.responseText);
			var xmlTemp = xmlDoc.getElementsByTagName("VideoID")[0];
			var xmlVideoID = xmlTemp.firstChild.nodeValue;
			var xmlTemp = xmlDoc.getElementsByTagName("VideoTitle")[0];
			var xmlVideoTitle = xmlTemp.firstChild.nodeValue;
			//alert(xmlVideoID);
			//alert(nowPlayingVideoID);
			//alert(schedWarningResponse2);
			//alert(nowPlayingVideoID);
			if ((xmlVideoID != nowPlayingVideoID) && (schedWarningResponse2 != nowPlayingVideoID)) {
				alertScheduledVideoStart(xmlVideoTitle, autoLive, scheduledVideosPlaylistID, xmlVideoID);
			}
		}
	}
}

function monitorSchedule() {
	// Checks the CCASTPLAYLISTSCHEDULE table against the current time and notifies the user if a new theme is starting. This function is meant to be called periodically.
	// Does not check while the "live" carousel is the active one.
	if (activeCarousel != "live") {
		var url = "ccast-micro.cfm?action=checkschedule&activeplaylist="+activePlaylist;
		url = url + "&dummy=" + new Date().getTime();
		//alert(url);
		request.open("GET", url, true);
		request.onreadystatechange = monitorScheduleResponse;
		request.send(null);
	}
}

function monitorScheduleResponse() {
	if (request.readyState == 4) {
		if (request.status == 200) {
			var xmlDoc = request.responseXML;
			//alert(request.responseText);
			var xmlTemp = xmlDoc.getElementsByTagName("PlaylistID")[0];
			var xmlPlaylistID = xmlTemp.firstChild.nodeValue;
			var xmlTemp = xmlDoc.getElementsByTagName("SchedTitle")[0];
			var xmlSchedTitle = xmlTemp.firstChild.nodeValue;
			var xmlTemp = xmlDoc.getElementsByTagName("SchedID")[0];
			var xmlSchedID = xmlTemp.firstChild.nodeValue;
			// A playlist ID of zero indicates no match on the schedule for the current time.
			if ((activePlaylist != xmlPlaylistID) && (xmlPlaylistID > 0) && (schedWarningResponse != xmlPlaylistID)) {
				// Repopulate the carousel with the new theme if the user wants to view it and has not already seen the warning for it.
				alertScheduledVideoStart(xmlSchedTitle, autoLive, xmlPlaylistID, xmlSchedID);
			}
		}
	}
}

function alertScheduledVideoStart(eventTitle, skipAlert, playlistID, videoID) {
	// Show viewer an alert when a scheduled video is about to start.
	// This is triggered by a periodic JavaScript function that monitors a schedule.
	if (skipAlert == 0) {
		document.getElementById('schedAlert').title = playlistID+","+videoID;
		document.getElementById('schedTitle').innerHTML = eventTitle;
		document.getElementById('schedAlert').style.display = "block";
		setTimeout("hideSchedWarning()", 30000);
	}
	if (skipAlert == 1) {
		playAll('id', playlistID, 'scheduled');
		activePlaylist = playlistID;
	}
}

function updateNowPlayingOverlay(videoID) {
	// Find all the "now playing transparencies" and remove them when the video changes, then add them to the video that now is playing.
	// Loop through all page's span elements; remove all the nowPlaying classnames; if the element has the notPlaying classname and matching title of the video's ID then change the classname to nowPlaying.
	var spans = document.getElementsByTagName("span");
	for (var i = 0; i < spans.length; i++) {
		if (spans[i].className == "nowPlaying") {
			spans[i].className = "notPlaying";
			spans[i].innerHTML = "";
		}
		if (spans[i].title == videoID) {
			spans[i].className = "nowPlaying";
			spans[i].innerHTML = "now playing";
		}
	}
}

function updatePlaylistButtons(videoID, action) {
	// Find all the "add to playlist" icons and change them to "already in playlist" when the video is added to the playlist. Or vice-versa.
	var linksCarousel = document.getElementById("carousel").getElementsByTagName("a");
	var showTooltips = true;
	updatePlaylistButtonLinks(videoID, action, linksCarousel, showTooltips);
	var linksBrowse = document.getElementById("findmore").getElementsByTagName("a");
	var showTooltips = false;
	updatePlaylistButtonLinks(videoID, action, linksBrowse, showTooltips);
}

function updatePlaylistButtonLinks(videoID, action, links, showTooltips) {
	// Loop through some of the page's A elements; if the element has an onclick and matching video ID, then toggle it and display the tooltip if so directed.
	if (action == "add") {
		for (var i = 0; i < links.length; i++) {
			if ((typeof(links[i].onclick) != "undefined") && (links[i].onclick !== null)) {
				//alert(links[i].onclick);
				//alert(links[i].attributes["onclick"].value);
				var onclick = links[i].attributes["onclick"].value;
				if (onclick.indexOf("addToPlaylist") > -1) {
					var re = /addToPlaylist\(.(\d+)/;
					var match = re.exec(onclick);
					//alert("*"+match[1]+"**"+videoID+"*");
					if (match[1] == videoID) {
						links[i].parentNode.className = "inPlaylist";
						links[i].className = "inPlaylist";
						if (showTooltips) {
							links[i].title = "cssbody=[tooltip] header=[] body=[already in my playlist]";
						}
						links[i].attributes["onclick"].value = "alreadyInPlaylist('"+videoID+"')";
						scanBO(links[i]); // Force Box Over to restyle the title / tooltip.
					}
				}
			}
		}
	}
	if (action == "remove") {
		for (var i = 0; i < links.length; i++) {
			if ((typeof(links[i].onclick) != "undefined") && (links[i].onclick !== null)) {
				//alert(links[i].attributes["onclick"].value);
				var onclick = links[i].attributes["onclick"].value;
				if (onclick.indexOf("alreadyInPlaylist") > -1) {
					var re = /alreadyInPlaylist\(.(\d+)/;
					var match = re.exec(onclick);
					//alert("*"+match[1]+"**"+videoID+"*");
					if (match[1] == videoID) {
						links[i].parentNode.className = "playlistAdd";
						links[i].className = "playlistAdd";
						if (showTooltips) {
							links[i].title = "cssbody=[tooltip] header=[] body=[add to my playlist]";
						}
						links[i].attributes["onclick"].value = "addToPlaylist('"+videoID+"')";
						scanBO(links[i]); // Force Box Over to restyle the title / tooltip.
					}
				}
			}
		}
	}
}

function switchToLiveVideo() {
	// Switch to the live carousel and start playing a live video, i.e., the first one in its queue.
	hideLiveWarning();
	showCarousel("live");
	nowPlayingLive = true;
	var url = "ccast-micro.cfm?action=returnlivevideo";
	url = url + "&dummy=" + new Date().getTime();
	//alert(url);
	request.open("GET", url, true);
	request.onreadystatechange = switchToLiveVideoResponse;
	request.send(null);
}

function switchToLiveVideoResponse() {
	if (request.readyState == 4) {
		if (request.status == 200) {
			var xmlDoc = request.responseXML;
			//alert(request.responseText);
			var xmlTemp = xmlDoc.getElementsByTagName("VideoID")[0];
			var xmlVideoID = xmlTemp.firstChild.nodeValue;
			var xmlTemp = xmlDoc.getElementsByTagName("VideoTitle")[0];
			var xmlVideoTitle = xmlTemp.firstChild.nodeValue;
			//alert(xmlVideoID);
			if (xmlVideoID == -1) {
				//alert(xmlVideoID);
				nowPlayingVideoID = -1;
				nowPlayingLive = false;
			}
			else {
				nowPlayingLive = true;
				loadVideo(xmlVideoID, 'live', 'Yes');
			}
			// Update the Live carousel's first panel to show properly formatted item with a clickable link (the order of innerHTML replacements is important). Don't add the "now playing" transparency unless the user actually watches it.
			var firstItem = document.getElementById("liveCarouselBelt").childNodes[1];
			//alert(firstItem.innerHTML);
			
			var updatedHTML = "<span class=\"nowPlaying\" title=\"516\">now playing</span><span class=\"liveEvent\"><a href=\"JavaScript:void(0)\" onClick=\"loadVideo('" + xmlVideoID + "', 'live', 'Yes')\"><img src=\"http://www.cornell.edu/img/video/thumbs/live-96x80.jpg\" alt=\"\"> <p>"+xmlVideoTitle+"</p></a></span>";
			
			//alert($("#liveCarouselBelt div:first-child").html());

			$("#liveCarouselBelt div:first-child").html(updatedHTML);
			
			//alert($("#liveCarouselBelt div:first-child").html());
			
			//firstItem.innerHTML = updatedHTML;
			
			//alert(firstItem.innerHTML);
			
			//firstItem.innerHTML = firstItem.innerHTML.replace(/<a href/, "</a><a href");
			
			//firstItem.innerHTML = firstItem.innerHTML.replace(/alt="" ?.> <p>/, "alt=\"\" /></a> <p><a href=\"JavaScript:void(0)\" onClick=\"loadVideo('" + xmlVideoID + "', 'live', 'Yes')\">");
			
			//firstItem.innerHTML = firstItem.innerHTML.replace(/<span class="scheduledEvent">/, "<span class=\"liveEvent\"><a href=\"JavaScript:void(0)\" onClick=\"loadVideo('" + xmlVideoID + "', 'live', 'Yes')\">");
			
			
		}
	}
}

function switchToSchedVideo() {
	// Switch to the scheduled carousel and start playing a video according to its schedule.
	hideSchedWarning();
	var playlistID = document.getElementById('schedAlert').title.replace(/,\d+$/, "");
	nowPlayingVideoID = document.getElementById('schedAlert').title.replace(/^\d+,/, "");
	schedWarningResponse = playlistID;
	schedWarningResponse2 = nowPlayingVideoID;
	activePlaylist = playlistID;
	activeCarousel = "scheduled";
	nowPlayingSequence = nowPlayingSequence.replace(/,$/, "");
	//setTimeout("playAll('id', "+playlistID+", 'scheduled')", 2000);
	playAll('id', playlistID, 'scheduled');
	setTimeout("loadVideo("+nowPlayingVideoID+", 'scheduled', false, 1)", 2000);
}

function hideLiveWarning() {
	// Hide the warning that informs a live event is about to start.
	document.getElementById('liveAlert').style.display = "none";
}

function hideSchedWarning() {
	// Hide the warning that informs a scheduled video is about to start.
	document.getElementById('schedAlert').style.display = "none";
	var playlistID = document.getElementById('schedAlert').title.replace(/,\d+$/, "");
	schedWarningResponse = playlistID;
	schedWarningResponse2 = nowPlayingVideoID;
}

function alreadyInPlaylist(videoID) {
	// Kind of a placeholder for items already in the playlist.
	// We need to keep this function even if we don't want it to do anything.
	//alert("That video is already in your playlist.");
}

function videoTabShow(name,log) {
	if(log===undefined){
		log = 1;
	}
	
	// Show one of the video info details tabs as active, and show its contents; hide the others and make them inactive.
	//alert('video'+name+'Tab');
	//alert(document.getElementById('video'+name+'Tab').className);
	document.getElementById('videoBookmarksTab').className = "";
	document.getElementById('videoInfoTab').className = "";
	document.getElementById('videoRelatedLinksTab').className = "";
	var tabName = 'video'+name+'Tab';
	document.getElementById(tabName).className = "chosen";
	// The above line is not executed/effected by IE 6, unless there's a bit of a delay.
	if (/msie 6/i.test(navigator.userAgent)) {
		pause(250);
	}
	document.getElementById('videoBookmarksBox').style.display = "none";
	document.getElementById('videoInfoBox').style.display = "none";
	document.getElementById('videoRelatedLinksBox').style.display = "none";
	document.getElementById('video'+name+'Box').style.display = "block";
	
	if(log){
		//logHistory('videotab',name);
	}
}

function alertLiveEventStart(eventTitle, skipAlert) {
	// Show viewer an alert when a live event is about to start.
	// This is triggered by a delayed JavaScript function written by the ColdFusion page, based on time until the next live event.
	if (skipAlert == 0) {
		document.getElementById('liveTitle').innerHTML = eventTitle;
		document.getElementById('liveAlert').style.display = "block";
		setTimeout("hideLiveWarning()", 30000);
	}
	if (skipAlert == 1) {
		switchToLiveVideo();
	}
}

function updateHREF(videoID, startSecs, endSecs) {
	// John Teal's Flash player launcher.
	if (flashMovie) {
		flashMovie.updatePlaylist(videoID, startSecs, endSecs);
	}
}

function callJavascript(str) {
	// John Teal's function that calls our function to return the value of the next video to be played, or zero if none queued.
	//alert("Got to John's callJavaScript function.");
	alert(nowPlayingVideoID);
	alert(nowPlayingSequence);
	var nextVideoID = tellFlashPlayerNextVideoID();
	alert(nextVideoID); 
	return nextVideoID;
}

function pause(millis) {
	// Wait a little before proceeding. Helps sequential Ajax calls work.
	var date = new Date();
	var curDate = null;
	do {
		curDate = new Date();
	}
	while(curDate-date < millis);
}

function tellFlashPlayerNextVideoID() {
	// Return a video ID to the Flash player.
	// The ID returned specifies the next video to be played. This is determined by tracking and testing the ID of the currently playing video against the sequence of videos currently being viewed, whether it's a set one or an ad-hoc one.
	// Return a value of zero to specify that the player is to show an end-of-video screen rather than play another video.
	var nextVideoID = 0;
	var prevVideoID = nowPlayingVideoID;
	
	// If a live video was streaming and has now ended, check for any more live events and/or determine where we are in the scheduled playlist sequence according to its schedule.
	if (nowPlayingLive) {
		debugStr += "1: " + new Date().getTime() + "\n";
		// Try to switch to next live video.
		switchToLiveVideo();
		//pause(2000);
		// If no live stream, switch to scheduled playlist.
		// Return prefix "live_" if we're streaming a live event.
		nextVideoID = "live_" + nowPlayingVideoID;
		//alert("We've got a live one!");
		
		// After working on the next section of code for nearly two days, we're going to go with a simple page reload in order to effect the switch to the scheduled playlist. The code does not return the correct video ID unless an alert box is used to display its value. Very strange.
		
		if ((!nowPlayingLive) || (nowPlayingVideoID == prevVideoID)) {
			if (autoLive == 1) {
				window.location = "index.cfm";
			}
			//pause(3000);
			//alert("Switching to current scheduled video.");
			//alert(nowPlayingVideoID);
			//nowPlayingVideoID = 474;
//			debugStr += "2: " + new Date().getTime() + "\n";
//			switchToScheduledVideo();
			//alert(nowPlayingVideoID);
//			debugStr += "3: " + new Date().getTime() + "\n";
			//alert(debugStr);
			//exit;
//			pause(2000);
//			nextVideoID = nowPlayingVideoID;
//			setTimeout("loadVideo("+nowPlayingVideoID+", 'scheduled', 'Yes')", 10000);
		}
	}
	else {
		// Load the list of videos to be played, which is stored in a global variable.
		var videos = new Array();
		videos = nowPlayingSequence.split(",");
		for (var i=0; i<videos.length; i++) {
			//alert(nowPlayingVideoID+" "+videos[i]);
			if (nowPlayingVideoID == videos[i]) {
				nextVideoID = parseInt(videos[i+1], 10);
				if (isNaN(nextVideoID)) {
					nextVideoID = 0;
				}
				// If in scheduled carousel and at end of cycle, wrap to beginning.
				if ((nextVideoID == 0) && (visibleCarouselID.indexOf('eature') > -1)) {
					nextVideoID = parseInt(videos[0], 10);
				}
				nowPlayingVideoID = nextVideoID;
				//alert("The next video to play has ID "+nextVideoID);
				break;
			}
		}
		if (nextVideoID > 0) {
			// Automatically advance the carousel (find which carousel is active so we know which one to advance).
			stepcarousel.stepBy(activeCarousel+"Carousel", 1);
			
			// Update page to show video that's now playing and fetch its details.
			updateNowPlayingOverlay(nextVideoID);
			//setTimeout("updateVideoInfo("+nextVideoID+")", 9000);
			updateVideoInfo(nextVideoID);
			//alert("1: " + nextVideoID);
		}
	}
	//pause(3000);
	//alert("2: " + nextVideoID);
	//alert("The next video to play has ID "+nextVideoID);
	return nextVideoID;
}

function showShowcase(catalogName, subnavID) {
	// Display the contents of the specified showcasee.
	document.getElementById('choicesvideosList').innerHTML = document.getElementById('showcase-'+catalogName).innerHTML;
	document.getElementById('videos-'+catalogName).innerHTML = document.getElementById('showcase-'+catalogName).innerHTML
	document.getElementById('pagingcontrols').innerHTML = "";
	document.getElementById('nav-'+catalogName).innerHTML = "";
	setSelectedSubNav(catalogName, subnavID);
}

function showCatalog(catalogName, displayShowcase) {
	// Update "more videos" area to display sets of topics links and matching videos.
	// Do this via DOM by swapping in pre-loaded page sections based on user choice.
	catalogName = catalogName.toLowerCase();

	// Special behavior for the tags areas: clear the results areas.
	if (catalogName == "tag") {
		//document.getElementById('choicesvideos').innerHTML = "";
		//document.getElementById('pagingcontrols').innerHTML = "";
		document.getElementById('videos-'+catalogName).innerHTML = "";
		document.getElementById('nav-'+catalogName).innerHTML = "";
	}

	// Recall saved video result set and its nav controls.	
	document.getElementById('pagingcontrols').innerHTML = document.getElementById('nav-'+catalogName).innerHTML;
	document.getElementById('choicesvideosList').innerHTML = document.getElementById('videos-'+catalogName).innerHTML;
	
	// Hide all topic subnav menus and show just the one we want.
	// Most browsers use the first part; IE needs the second part.
	if (document.getElementsByClassName) {
		var subNavTopics = document.getElementsByClassName("topicsSubNav");
		for (var i=0; i<subNavTopics.length; i++) {
			document.getElementById(subNavTopics[i].id).style.display = "none";
		}
	}
	else {
		var i = 0;
		var a = document.getElementsByTagName("div");
		while (element = a[i++]) {
			if (element.className == "topicsSubNav") {
				document.getElementById(element.id).style.display = "none";
			}
		}
	}
	document.getElementById('topics-'+catalogName).style.display = "block";
	
	// Update tabs to make the selected one look selected.
	document.getElementById("categoryTab").className = "";
	document.getElementById("seriesTab").className = "";
	document.getElementById("playlistTab").className = "";
	document.getElementById("contributorTab").className = "";
	document.getElementById("tagTab").className = "";
	document.getElementById("videoSearch").className = "";

	if (catalogName != "text") {
		document.getElementById(catalogName + "Tab").className = "chosen";
	}
	else {
		document.getElementById("videoSearch").className = "chosen";
	}
	
	// Default the view to showcase if we don't have an already-saved result set in the area.
	if (displayShowcase) {
		if (document.getElementById('videos-'+catalogName).innerHTML.length < 10) {
			showShowcase(catalogName, 'subNav'+catalogName.substr(0, 1).toUpperCase() + catalogName.substr(1)+'Showcase');
		}
	}
	
	// Special behavior for the tags areas: the subnav area grows to full width with weighted text when first viewed.
	document.getElementById('choicestopics').className = "";
	if (catalogName == "tag") {
		document.getElementById('choicestopics').className = "tagCloudNav";
		// Make all tag subnav items variable size.
		var i = 0;
		var fontSize = "";
		var a = document.getElementsByTagName("a");
		while (element = a[i++]) {
			if (element.className.indexOf("tag") == 0) {
				fontSize = element.className.replace(/tag/, "");
				element.style.fontSize = fontSize;
			}
		}
	}
}

function checkCarouselArrows(carousel) {
	// If the specified carousel does not contain enough items to warrant the controlling arrow buttons then disable them.
	var itemCount = 0;
	var maxItems = 5;
	
	var beltID = carousel + "CarouselBelt";
	var itemCount = document.getElementById(beltID).getElementsByTagName("div").length;
	//alert(document.getElementById(beltID).innerHTML);
	//alert(beltID+": "+itemCount);

	if (itemCount <= maxItems) {
		//document.getElementById(carousel + 'Buttons').style.display = "none";
		//alert(beltID+": inactive: "+itemCount);
		document.getElementById(carousel + 'Buttons').className = "inactiveCarouselArrow";
	}
	else {
		//alert(beltID+": active: "+itemCount);
		document.getElementById(carousel + 'Buttons').className = "";
	}
}

function showCarousel(carouselName, log) {
	// Hide the active carousel and its arrow buttons and then show the desired one.
	if (log===undefined) {
		log = 1;
	}
	visibleCarousel = carouselName;
	
	//alert(carouselName);
	document.getElementById('scheduledCarousel').style.display = "none";
	document.getElementById('myplaylistCarousel').style.display = "none";
	document.getElementById('liveCarousel').style.display = "none";
	document.getElementById('customCarousel').style.display = "none";
	document.getElementById('featuredCarousel').style.display = "none";
	document.getElementById('myplaylistClear').style.display = "none";
	document.getElementById('scheduleHelp').style.display = "none";

	document.getElementById(carouselName + "Carousel").style.display = "block";
	
	document.getElementById('scheduledButtons').style.display = "none";
	document.getElementById('myplaylistButtons').style.display = "none";
	document.getElementById('liveButtons').style.display = "none";
	document.getElementById('customButtons').style.display = "none";
	document.getElementById('featuredButtons').style.display = "none";

	document.getElementById(carouselName + "Buttons").style.display = "inline";
	
	// Update tabs to make the selected one look selected.
	document.getElementById("scheduledTab").className = "";
	document.getElementById("myplaylistTab").className = "";
	document.getElementById("liveTab").className = "";
	document.getElementById("customTab").className = "";
	document.getElementById("featuredTab").className = "";

	document.getElementById(carouselName + "Tab").className = "chosen";
	document.getElementById(carouselName + "Tab").style.display = "block";
	
	if (carouselName == "myplaylist") {
		document.getElementById('myplaylistClear').style.display = "inline";
	}
	if (carouselName == "scheduled") {
		document.getElementById('scheduleHelp').style.display = "inline";
	}
	else { // Setup value to check against for monitoring scheduled playlists.
		activeCarousel = 0;
	}
	if (log) {
		//logHistory('carousel',carouselName);
	}
	setTimeout("checkCarouselArrows('"+carouselName+"')", 500);
}

function clearPlaylist() {
	// Clear the My Playlist entirely.
	if (confirm("Are you sure that you want to clear your playlist?")) {
		removeAddPlaylistButtons("remove");
		setCookie("CornellCastMyPlaylist", "", 365);
		var myplaylistCookieNew = getCookie("CornellCastMyPlaylist");
		var tempArray = myplaylistCookieNew.split(",");
		updatePlaylistTabCount();
		if (document.getElementById('myplaylistCarousel').style.display != "none") {
			loadMyPlaylistVideos(true);
		}
		document.getElementById('myplaylistCarouselBelt').innerHTML = "<div id=\"myplaylistEmpty\"><p>Add items to your playlist by clicking their <span>icons</span>.</p></div>";
		stepcarousel.stepTo('myplaylistCarousel', 1);
	}
}

function addToPlaylist(VideoID) {
	// Add a video's ID to the user's playlist, which is stored in a cookie.
	// Check for cookie; if missing then create.
	// Then append videoID to playlist cookie.
	var myplaylistCookie = getCookie("CornellCastMyPlaylist");
	if (myplaylistCookie == "") {
		setCookie("CornellCastMyPlaylist", VideoID, 365);
	}
	else {
		setCookie("CornellCastMyPlaylist", myplaylistCookie + "," + VideoID, 365);
	}
	var myplaylistCookieNew = getCookie("CornellCastMyPlaylist");
	var tempArray = myplaylistCookieNew.split(",");
	updatePlaylistTabCount();
	if (document.getElementById('myplaylistCarousel').style.display != "none") {
		loadMyPlaylistVideos(true);
	}
	updatePlaylistButtons(VideoID, "add");
	//loadMyPlaylistVideos(false);
	//stepcarousel.configholder['myplaylistCarousel'].contenttype[1] = xxx;
	//stepcarousel.getremotepanels($,stepcarousel.configholder['myplaylistCarousel']);
}

function removeFromPlaylist(VideoID) {
	// Remove a video's ID from the user's playlist, which is stored in a cookie.
	var myplaylistCookie = getCookie("CornellCastMyPlaylist");
	myplaylistCookieNew = "," + myplaylistCookie + ",";
	var re = new RegExp("," + VideoID + ",");
	myplaylistCookieNew = myplaylistCookieNew.replace(re, ",");
	myplaylistCookieNew = myplaylistCookieNew.replace(/^,/, "");
	myplaylistCookieNew = myplaylistCookieNew.replace(/,$/, "");
	var tempArray = myplaylistCookieNew.split(",");
	setCookie("CornellCastMyPlaylist", myplaylistCookieNew, 365);
	updatePlaylistTabCount();
	loadMyPlaylistVideos(true);
	updatePlaylistButtons(VideoID, "remove");
}

function updatePlaylistTabCount() {
	// Update the playlist tab count.
	var numVideos = 0;
	var cookie = getCookie("CornellCastMyPlaylist");
	//alert("My Playlist cookie: " + cookie);
	if (cookie != "") {
		var tempArray = cookie.split(",");
		numVideos = tempArray.length;
	}
	document.getElementById('myplaylistCount').innerHTML = "("+numVideos+")";
}

function loadMyPlaylistVideos(display) {
	// Populate the carousel with the videos in "my playlist".
	// Get the "my playlist" cookie; send it to server to retrieve details.
	// Do the above only if there are items in the playlist, else show message how to add them.
	var myplaylistCookie = getCookie("CornellCastMyPlaylist");
	if (myplaylistCookie == "") {
		//showCarousel('myplaylist');
		if (document.getElementById('myplaylistCarouselBelt') !== null) {
			document.getElementById('myplaylistCarouselBelt').innerHTML = "<div id=\"myplaylistEmpty\"><p>Add items to your playlist by clicking their <span>icons</span>.</p></div>";
		}
	}
	else {
		timeOut = 0;
		var url = "ccast-micro.cfm?carousel=myplaylist&format=HTML&action=returnplaylist&playlist="+myplaylistCookie;
		stepcarousel.loadcontent('myplaylistCarousel', url);
//		url = url + "&dummy=" + new Date().getTime();
		//alert(url);
//		request.open("GET", url, true);
//		request.onreadystatechange = loadMyPlaylistVideosResponse;
//		request.send(null);
	}
	if (display) {
		showCarousel('myplaylist');
	}
	//loadMyPlaylistVideos(false);
}

function loadMyPlaylistVideosResponse() {
	if (request.readyState == 4) {
		if (request.status == 200) {
			var videoList = "";
			var xmlDoc = request.responseXML;
			var xmlVideos = xmlDoc.getElementsByTagName("Video");
			for (var n=0; n<xmlVideos.length; n++) {
				var xmlTemp = xmlVideos[n].getElementsByTagName("VideoID")[0];
				var VideoID = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("VideoTitle")[0];
				var VideoTitle = unencodeHTMLentities(xmlTemp.firstChild.nodeValue);
				var xmlTemp = xmlVideos[n].getElementsByTagName("VideoDuration")[0];
				var VideoDuration = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("Thumb")[0];
				var Thumb = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("IsLive")[0];
				var IsLive = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("SecondsToStart")[0];
				var SecondsToStart = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("WhenDate")[0];
				var WhenDate = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("WhenTime")[0];
				var WhenTime = xmlTemp.firstChild.nodeValue;
				var leftPx = n * carouselLeftPxSpacing;
				
				//videoList = videoList + "<div class=\"panel\" style=\"float: none; position: absolute; left: " + leftPx + "px;\">";
				videoList = videoList + "<div class=\"panel\">";
				if (nowPlayingVideoID == VideoID) {
					videoList += "<span class=\"nowPlaying\" title=\""+VideoID+"\">now playing</span>";
				}
				else {
					videoList += "<span class=\"notPlaying\" title=\""+VideoID+"\"></span>";
				}

				// Show scheduled items without links.
				if (SecondsToStart > 1) {
					videoList += "<span class=\"scheduledEvent\">";
					videoList += "<img src=\""+Thumb+"\" alt=\"\" />";
					videoList += "<p>" + VideoTitle + " " + WhenDate + " at " + WhenTime;
					//videoList += "<a href=\"JavaScript:void(0)\" onclick=\"removeFromPlaylist('"+VideoID+"')\" class=\"playlistRemove\" title=\"cssbody=[tooltip] header=[] body=[remove from my playlist]\"></a>";
					videoList += "</p> </div></span>";
				}
				else {
					videoList += "<a href=\"JavaScript:void(0)\" onclick=\"loadVideo('"+VideoID+"', 'my playlist', '"+IsLive+"')\">";
					videoList += "<img src=\""+Thumb+"\" alt=\"\" />";
					videoList += "</a> ";
					videoList += "<p>";
					videoList += "<a href=\"JavaScript:void(0)\" onclick=\"loadVideo('"+VideoID+"', 'my playlist', '"+IsLive+"')\">"+VideoTitle+"</a>";
					videoList += "<a href=\"JavaScript:void(0)\" onclick=\"removeFromPlaylist('"+VideoID+"')\" class=\"playlistRemove\" title=\"cssbody=[tooltip] header=[] body=[remove from my playlist]\"></a>";
					videoList += "</p> </div>";
				}
				
			}
			//alert('myplaylistCarousel '+videoList);
			stepcarousel.loadcontent('myplaylistCarousel', videoList);
		}
	}
}

function loadVideo(VideoID, source, IsLive, log) {
	if(log===undefined){
		log = 1;
	}
	// Tell the player to load a video and play it, optionally starting at a specific time.
	// (Do not update the video if just jumping to a bookmark of the currently playing one.)
	if (nowPlayingVideoID != VideoID) {
		// Insert the live video's ID into the current sequence.
		if ((source == "live") || (IsLive == "Yes")) {
			nowPlayingLive = true;
			var re = new RegExp(nowPlayingVideoID + ",");
			nowPlayingSequence = nowPlayingSequence.replace(re, nowPlayingVideoID+","+VideoID+",");
		}
		// Load the video into the player and track IDs.
		if ((source == "live") || (IsLive == "Yes")) {
			nowPlayingLive = true;
			updateHREF(VideoID, "live_"+VideoID);
		}
		else {
			nowPlayingLive = false;
			updateHREF(VideoID);
		}
		currentVideo = VideoID;
		nowPlayingVideoID = VideoID;
		updateNowPlayingOverlay(nowPlayingVideoID);
		// Reset the sequence of videos unless we chose an item from the Scheduled carousel or are streaming live.
		if ((source != "custom") && (source != "scheduled") && (source != "live") && (IsLive != "Yes")) {
			nowPlayingSequence = "";
		}
		// Update the video's details.
		if ((source == "live") || (IsLive == "Yes")) {
			setTimeout("updateVideoInfo("+VideoID+")", 1000);
		}
		else {
			updateVideoInfo(VideoID);
		}
		if(log){
			//logHistory('VideoID',VideoID);
		}
	}
	
	// Update the variable tracking the active carousel so that automatic advances happen in the correct one regardless of which is visible.
	if (source != "search") {
		activeCarousel = visibleCarousel;
	}
}

function alert2() {
	// Show an alert box with multiple variables' values.
	var msg = "";
	for (var i=0; i< arguments.length; i++) {
		msg += arguments[i] + ":";
	}
	msg = msg.replace(/:$/, "");
	alert(msg);
}

function unencodeHTMLentities(str) {
	// Convert encoded angle brackets and other encoded HTML entities so that browser shows their HTML.
	
	str = str.replace(/&amp;/g, "&"); // This one must be first.
	str = str.replace(/&lt;/g, "<");
	str = str.replace(/&gt;/g, ">");
	str = str.replace(/&quot;/g, '"');
	str = str.replace(/&apos;/g, "'");
	
	return str;
}

function setDescriptionHeight(){
	// Set height of #nowplayingShortDescription based on the height of #nowPlayingTitle
	var titleHeight = $("#nowplayingTitle").height();
	$("#nowplayingLongDescription").css("height",(200 - titleHeight) + 'px');
	//alert(titleHeight);
}

function updateMetaTag(tagname,tagcontent) {
	$('meta[name="'+tagname+'"]').remove();
	$('head').append('<meta name="'+tagname+'" content="' + tagcontent + '" />');
}

function updateVideoInfo(VideoID) {
	// Update the display of the currently playing video's title, description, bookmarks, etc..
	var url = "ccast-micro.cfm?action=returnvideoinfo&VideoID="+VideoID;
	url = url + "&dummy=" + new Date().getTime();
	//alert(url);
	request.open("GET", url, true);
	request.onreadystatechange = updateVideoInfoResponse;
	request.send(null);
}

function updateVideoInfoResponse() {
	if (request.readyState == 4) {
		if (request.status == 200) {
			var xmlDoc = request.responseXML;
			//alert(request.responseXML);
			//alert(request.responseText);
			// Update Title.
			var xmlTemp = xmlDoc.getElementsByTagName("FullTitle")[0];
			var xmlTitle = unencodeHTMLentities(xmlTemp.firstChild.nodeValue);
			document.title = 'Cornell University - CornellCast - ' + xmlTitle;
			document.getElementById('nowplayingTitle').innerHTML = xmlTitle;
			updateMetaTag('title',xmlTitle);
			
			// Set height of #nowplayingShortDescription based on the height of #nowPlayingTitle
			setDescriptionHeight();
			
			// Update Short Description.
			var xmlTemp = xmlDoc.getElementsByTagName("ShortDescription")[0];
			var xmlShortDescr = unencodeHTMLentities(xmlTemp.firstChild.nodeValue);
			document.getElementById('nowplayingShortDescription').innerHTML = xmlShortDescr;
			updateMetaTag('description',xmlShortDescr);

			// Update Long Description.
			var xmlTemp = xmlDoc.getElementsByTagName("LongDescription")[0];
			var xmlLongDescr = unencodeHTMLentities(xmlTemp.firstChild.nodeValue);
			document.getElementById('nowplayingLongDescription').innerHTML = xmlLongDescr;
			document.getElementById('nowplayingLongDescription').scrollTop = 0;

			// Update Duration.
			var xmlTemp = xmlDoc.getElementsByTagName("VideoDuration")[0];
			var xmlVideoDuration = xmlTemp.firstChild.nodeValue;
			document.getElementById('nowplayingDuration').innerHTML = xmlVideoDuration;

			// Update ID.
			var xmlTemp = xmlDoc.getElementsByTagName("VideoID")[0];
			var xmlVideoID = xmlTemp.firstChild.nodeValue;
			//document.getElementById('nowplayingID').innerHTML = xmlVideoID;

			// Update VideoDownloadURL.
			var xmlTemp = xmlDoc.getElementsByTagName("VideoDownloadURL")[0];
			var xmlVideoDownloadURL = xmlTemp.firstChild.nodeValue;
			if ((xmlVideoDownloadURL == "None") || (xmlVideoDownloadURL == "")) {
				document.getElementById('videoDownload').style.display = "none";
			}
			else {
				document.getElementById('nowplayingVideoDownloadURL').href = xmlVideoDownloadURL;
				document.getElementById('videoDownload').style.display = "block";
			}

			// Update AudioDownloadURL.
			var xmlTemp = xmlDoc.getElementsByTagName("AudioDownloadURL")[0];
			var xmlAudioDownloadURL = xmlTemp.firstChild.nodeValue;
			if ((xmlAudioDownloadURL == "None") || (xmlAudioDownloadURL == "")) {
				document.getElementById('audioDownload').style.display = "none";
			}
			else {
				document.getElementById('nowplayingAudioDownloadURL').href = xmlAudioDownloadURL;
				document.getElementById('audioDownload').style.display = "block";
			}

			// Update Transcript.
			var xmlTemp = xmlDoc.getElementsByTagName("Transcript")[0];
			var xmlTranscript = xmlTemp.firstChild.nodeValue;
			if ((xmlTranscript == "None") || (xmlTranscript == "")) {
				document.getElementById('transcriptDownload').style.display = "none";
			}
			else {
				document.getElementById('nowplayingTranscript').href = xmlTranscript;
				document.getElementById('transcriptDownload').style.display = "block";
			}

			// Update EventDate.
			var xmlTemp = xmlDoc.getElementsByTagName("EventDate")[0];
			var xmlEventDate = xmlTemp.firstChild.nodeValue;
			//alert(xmlEventDate);
			if (xmlEventDate == "No record") {
				document.getElementById('videoEventDate').style.display = "none";
			}
			else {
				document.getElementById('videoEventDate').style.display = "block";
				document.getElementById('nowplayingEventDate').innerHTML = xmlEventDate;
			}

			// Update DatePosted.
			var xmlTemp = xmlDoc.getElementsByTagName("DatePosted")[0];
			var xmlDatePosted = xmlTemp.firstChild.nodeValue;
			document.getElementById('nowplayingDatePosted').innerHTML = xmlDatePosted;

			// Update Tags.
			var xmlTemp = xmlDoc.getElementsByTagName("Tags")[0];
			var xmlTags = xmlTemp.firstChild.nodeValue;
			// Convert tags to an array, then to links for the search area. The links activate the tags search area and execute the search.
			var tags = new Array();
			tags = xmlTags.split(",");
			var linkedTags = "";
			for (var i=0; i<tags.length; i++) {
				linkedTags += "<a href=\"JavaScript:void(0)\" onclick=\"showCatalog('tag', false); ccastSearch('tag', '" + tags[i] + "', 1, 'subNavTag" + tags[i] + "')\">" + tags[i] + "</a>, ";
			}
			linkedTags = linkedTags.replace(/, +$/, "");
			document.getElementById('nowplayingTags').innerHTML = linkedTags;
			updateMetaTag('keywords',xmlTags);

			// Update Contributors.
			var contributorsList = "";
			var xmlContributors = xmlDoc.getElementsByTagName("Contributor");
			for (var n=0; n<xmlContributors.length; n++) {
				var xmlTemp = xmlContributors[n].getElementsByTagName("ID")[0];
				var contributorID = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlContributors[n].getElementsByTagName("Name")[0];
				var contributorName = xmlTemp.firstChild.nodeValue;
				
				contributorsList = contributorsList + "<a href=\"JavaScript:void(0)\" onclick=\"showCatalog('contributor', false); ccastSearch('contributor', '" + contributorID + "', 1, 'subNavContributor" + contributorID + "')\">" + contributorName + "</a>, ";
			}
			contributorsList = contributorsList.replace(/, +$/, "");

			if (contributorsList == "") {
				contributorsList = "<em>No record</em>";
			}
			document.getElementById('nowplayingContributors').innerHTML = contributorsList;

			// Ensure Related Links tab and panel not selected when new item loads.
			document.getElementById('videoRelatedLinksTab').className = "";
			document.getElementById('videoRelatedLinksBox').style.display = "none";
			// Update bookmarks.
			var bookmarkList = "";
			var xmlVideos = xmlDoc.getElementsByTagName("Bookmark");
			for (var n=0; n<xmlVideos.length; n++) {
				var xmlTemp = xmlVideos[n].getElementsByTagName("Time")[0];
				var Time = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("Title")[0];
				var Title = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("Seconds")[0];
				var Seconds = xmlTemp.firstChild.nodeValue;
				bookmarkList = bookmarkList + "<li>"+Time+" <a href=\"JavaScript:void(0)\" onclick=\"updateHREF(" + xmlVideoID + ", " + Seconds + ");\">" + Title + "</a></li>";
			}
			if (bookmarkList == "") {
				// Activate info tab, de-activate bookmarks tab.
				bookmarkList = "<p>There are no bookmarks for this video.</p>";
				document.getElementById('videoBookmarksTab').className = "";
				document.getElementById('videoInfoTab').className = "chosen";
				document.getElementById('videoBookmarksBox').style.display = "none";
				document.getElementById('videoInfoBox').style.display = "block";
			}
			else {
				bookmarkList = "<ul>" + bookmarkList + "</ul>";
				// Activate bookmarks tab, de-activate info tab.
				document.getElementById('videoInfoTab').className = "";
				document.getElementById('videoBookmarksTab').className = "chosen";
				document.getElementById('videoInfoBox').style.display = "none";
				document.getElementById('videoBookmarksBox').style.display = "block";
			}
			document.getElementById('bookmarkList').innerHTML = bookmarkList;
			
			// Update related links.
			var relatedLinkList = "";
			var xmlVideos = xmlDoc.getElementsByTagName("RelatedLink");
			for (var n=0; n<xmlVideos.length; n++) {
				var xmlTemp = xmlVideos[n].getElementsByTagName("URL")[0];
				var URL = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("Description")[0];
				var Description = xmlTemp.firstChild.nodeValue;
				
				relatedLinkList = relatedLinkList + "<li><a href=\"" + URL + "\" target=\"_blank\">" + Description + "</a></li>";
			}
			if (relatedLinkList == "") {
				relatedLinkList = "<p>There are no related links for this video.</p>";
			}
			else {
				relatedLinkList = "<ul>" + relatedLinkList + "</ul>";
			}
			document.getElementById('relatedLinksList').innerHTML = relatedLinkList;

			// Update non-Flash components if they are present.
			if (document.getElementById('nonFlashTitle') !== null) {
				document.getElementById('nonFlashTitle').innerHTML = xmlTitle;
				document.getElementById('nonFlashShortDescription').innerHTML = xmlShortDescr;
				document.getElementById('nonFlashDuration').innerHTML = xmlVideoDuration;
				document.getElementById('nonFlashVideoDownloadURL').href = xmlVideoDownloadURL;
	
				// Update VideoDownloadURL.
				if ((xmlVideoDownloadURL == "None") || (xmlVideoDownloadURL == "")) {
					document.getElementById('nonFlashVideoDownload').style.display = "none";
				}
				else {
					document.getElementById('nonFlashVideoDownloadURL').href = xmlVideoDownloadURL;
					document.getElementById('nonFlashVideoDownload').style.display = "block";
				}
	
				// Update AudioDownloadURL.
				if ((xmlAudioDownloadURL == "None") || (xmlAudioDownloadURL == "")) {
					document.getElementById('nonFlashAudioDownload').style.display = "none";
				}
				else {
					document.getElementById('nonFlashAudioDownloadURL').href = xmlAudioDownloadURL;
					document.getElementById('nonFlashAudioDownload').style.display = "block";
				}
	
				// Update Transcript.
				if ((xmlTranscript == "None") || (xmlTranscript == "")) {
					document.getElementById('nonFlashTranscriptDownload').style.display = "none";
				}
				else {
					document.getElementById('nonFlashTranscript').href = xmlTranscript;
					document.getElementById('nonFlashTranscriptDownload').style.display = "block";
				}
			}

		}
		else {
			var message = request.getResponseHeader("Status");
			if ((message.length == null) || (message.length <= 0)) {
				//alert("Server misbehaving. We recommend waiting a few moments and trying again.");
				alert("Error! Request status is " + request.status);
			} 
			else {
				alert(message);
			}
		}
	}
}

function filterSearch(filter) {
	// Apply a filter to the search results.
	// These are cumulative and invoked via Ajax to modify the currently showing set of results returned from an arbitrary text search conducted by the user.
	//alert(filter.id);
	//alert(filter.checked);
	ccastSearch('text', document.getElementById('searchbox').value, 1, filter.id);
}

function clearCategorySubNav(startingDiv) {
	// Clear category sub nav item marked as selected by clearing them all.
	//alert(startingDiv);
	// Most browsers use the first part; IE needs the second part.
	if (document.getElementsByClassName) {
		var subNavItems = document.getElementById(startingDiv).getElementsByClassName("selectedSubNav");
		for (var i=0; i<subNavItems.length; i++) {
			document.getElementById(subNavItems[i].id).className = "";
		}
	}
	else {
		var i = 0;
		var a = document.getElementById(startingDiv).getElementsByTagName("li");
		while (element = a[i++]) {
			if (element.className == "selectedSubNav") {
				document.getElementById(element.id).className = "";
			}
		}
	}
}

function setSelectedSubNav(searchType, subnavID) {
	// Set the current subnav menu item to be selected, and clear all others in the section.
	if (searchType != "text") {
		var navType = searchType;
		if (searchType == "latest") {
			navType = "category";
		}
		clearCategorySubNav('topics-'+navType);
		//alert(subnavID);
		document.getElementById(subnavID).className="selectedSubNav";
		}
}

function ccastSearch(searchType, searchValue, pageNumber, subnavID) {
	// Send search parameters to server and update results area.
	// Also update the RSS link to include all the elements it needs for the same results.
	
	setSelectedSubNav(searchType, subnavID);
	
	// Convert tag cloud nv back to normal subnav.
	if (searchType == "tag") {
		document.getElementById('choicestopics').className = "";
		// Make all tag subnav items normal size.
		var i = 0;
		var a = document.getElementsByTagName("a");
		while (element = a[i++]) {
			if (element.className.indexOf("tag") == 0) {
				element.style.fontSize = "100%";
			}
		}
	}
	
	var url = "ccast-micro.cfm?action=returnsearch&searchtype=" + searchType + "&searchvalue=" + searchValue + "&page=" + pageNumber + "&subnavID=" + subnavID;
	RSSurl = "ccast-micro.cfm?format=RSS&searchtype=" + searchType + "&searchvalue=" + searchValue;

	// Apply filters.
	var filterStr = "";
	// Most browsers use the first part; IE needs the second part.
	if (document.getElementsByClassName) {
		var filters = document.getElementById("choicestopics").getElementsByClassName("searchFilter");
		for (var i=0; i<filters.length; i++) {
			filterStr += filters[i].name + " " + filters[i].checked + " " + filters[i].value + "\n";
			if (filters[i].checked) {
				url += "&" + filters[i].name + "=filter";
				RSSurl += "&" + filters[i].name + "=filter";
			}
		}
	}
	else {
		var i = 0;
		var a = document.getElementById("choicestopics").getElementsByTagName("input");
		while (element = a[i++]) {
			filterStr += element.name + " " + element.checked + " " + element.value + "\n";
			if (element.checked) {
				url += "&" + element.name + "=filter";
				RSSurl += "&" + element.name + "=filter";
			}
		}
	}
	
	url = url + "&dummy=" + new Date().getTime();
	
	//alert(filterStr);
	//alert(url);
	request.open("GET", url, true);
	request.onreadystatechange = searchResponse;
	request.send(null);

}

function searchResponse() {
	if (request.readyState == 4) {
		if (request.status == 200) {
			var videoList = "";
			var xmlDoc = request.responseXML;
			
			// Keep state of previous search type and value for use in showing when no hit and incorporating into page links when there are many hits.
			var xmlTemp = xmlDoc.getElementsByTagName("SearchType")[0];
			var SearchType = xmlTemp.firstChild.nodeValue;
			var xmlTemp = xmlDoc.getElementsByTagName("SearchValue")[0];
			var SearchValue = xmlTemp.firstChild.nodeValue;
			
			// Update the "displaying" title and track any selected category.
			var xmlTemp = xmlDoc.getElementsByTagName("SearchTitle")[0];
			var SearchTitle = xmlTemp.firstChild.nodeValue;
			var xmlTemp = xmlDoc.getElementsByTagName("SubnavID")[0];
			var SubnavID = xmlTemp.firstChild.nodeValue;
			
			// Update the "Displaying x-y of N" details.
			var xmlTemp = xmlDoc.getElementsByTagName("PageFirstItem")[0];
			var PageFirstItem = parseInt(xmlTemp.firstChild.nodeValue);
			var xmlTemp = xmlDoc.getElementsByTagName("PageLastItem")[0];
			var PageLastItem = parseInt(xmlTemp.firstChild.nodeValue);
			var xmlTemp = xmlDoc.getElementsByTagName("SearchHitCount")[0];
			var SearchHitCount = parseInt(xmlTemp.firstChild.nodeValue);
			
			// Update the pagination index.
			var xmlTemp = xmlDoc.getElementsByTagName("CurrentPage")[0];
			var CurrentPage = parseInt(xmlTemp.firstChild.nodeValue);
			var xmlTemp = xmlDoc.getElementsByTagName("MaxPageHits")[0];
			var MaxPageHits = parseInt(xmlTemp.firstChild.nodeValue);
			
			// Gerate the numbers and make their links.
			var pageIndex = "";
			var pageLinkSpread = 3; // Number of individual page links before and after elipses.
			var numPages = Math.ceil(SearchHitCount / MaxPageHits);
			var lowEllipses = false;
			var highEllipses = false;

			for (var i=0; i<numPages; i++) {
				var pageNumber = i + 1;
				var showLink = false;
				if ((pageNumber == numPages) || (pageNumber == 1)) {
					showLink = true;
				}
				var minPageLink = CurrentPage - pageLinkSpread;
				var maxPageLink = CurrentPage + pageLinkSpread;
				if ((pageNumber > minPageLink) && (pageNumber < maxPageLink)) {
					//alert(pageNumber + " > " + minPageLink + " :: " + pageNumber + " < " + maxPageLink);
					showLink = true;
				}
				
				
				if ((pageNumber > CurrentPage + pageLinkSpread) && (!highEllipses)) {
					pageIndex += "<li>&hellip;</li>";
					highEllipses = true;
				}
				
				if (showLink) {
					if (pageNumber != CurrentPage) {
						pageIndex += "<li><a class=\"pages\" href=\"JavaScript:void(0)\" onclick=\"ccastSearch('" + SearchType + "', '" + SearchValue + "', " + pageNumber + ", '" + SubnavID + "')\">" + pageNumber + "</a></li>";
					}
					else {
						pageIndex += "<li><span class=\"pageSelected\">" + pageNumber + "</span></li>";
					}
				}
				
				if ((pageNumber < CurrentPage - pageLinkSpread) && (!lowEllipses) && (pageNumber > 0)) {
					pageIndex += "<li>&hellip;</li>";
					lowEllipses = true;
				}

			}
			
			// Add arrows for browsing pages.
			if (numPages > 1) {
				var prevPageNumber = CurrentPage - 1;
				var leftArrowClass = "pages";
				if (prevPageNumber == 0) {
					leftArrowClass = "pagesInactive";
					prevPageNumber = 1;
				}
				pageIndex += "<li><a class=\"" + leftArrowClass + "\" href=\"JavaScript:void(0)\" onclick=\"ccastSearch('" + SearchType + "', '" + SearchValue + "', " + prevPageNumber + ", '" + SubnavID + "')\" id=\"goPrevPage\">" + "</a></li>";
			}
			if (numPages > 1) {
				var nextPageNumber = CurrentPage + 1;
				var rightArrowClass = "pages";
				if (nextPageNumber > numPages) {
					rightArrowClass = "pagesInactive";
					nextPageNumber = numPages;
				}
				pageIndex += "<li><a class=\"" + rightArrowClass + "\" href=\"JavaScript:void(0)\" onclick=\"ccastSearch('" + SearchType + "', '" + SearchValue + "', " + nextPageNumber + ", '" + SubnavID + "')\" id=\"goNextPage\">" + "</a></li>";
			}
			if (numPages == 1) {
				pageIndex = "";
			}
			else {
				pageIndex = "<ul>" + pageIndex + "</li>";
			}
			
			// Update the nav area for the results.
			var newHTML = "<p>";
			
			// Generate text for indicating results.
			var numStr = "";
			switch(SearchHitCount) {
				case 0: numStr = "No"; break;
				case 1: numStr = "One"; break;
				case 2: numStr = "Two"; break;
				case 3: numStr = "Three"; break;
				case 4: numStr = "Four"; break;
				case 5: numStr = "Five"; break;
				case 6: numStr = "Six"; break;
				case 7: numStr = "Seven"; break;
				case 8: numStr = "Eight"; break;
				case 9: numStr = "Nine"; break;
			}
			numStr = SearchHitCount;
			numStr += " results ";
			numStr = numStr.replace(/One results/, "One result");
			numStr = numStr.replace(/1 results/, "1 result");
			
			var topicStr = "";
			switch(SearchType) {
				case "text": topicStr = " for "; break;
				case "series": topicStr = " in "; break;
				case "playlist": topicStr = " in "; break;
				case "tag": topicStr = " tagged  with "; break;
				case "contributor": topicStr = " from "; break;
				case "category": topicStr = " in "; break;
				case "latest": topicStr = " for "; break;
			}
			topicStr += "<strong>" + SearchTitle + "</strong>";
			
			// Show X of Y hits only if we have more than one page of results.
			if (SearchHitCount > 9) {
				newHTML += "Results " + PageFirstItem + "-" + PageLastItem + " of " + SearchHitCount;
			}
			else {
				newHTML += numStr;
			}
			newHTML += topicStr;
			
			// Show all filters found for the search.
			var filtersStr = "";
			var xmlFilters = xmlDoc.getElementsByTagName("Filter");
			for (var n=0; n<xmlFilters.length; n++) {
				var xmlTemp = xmlFilters[n].getElementsByTagName("Type")[0];
				var FilterType = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlFilters[n].getElementsByTagName("Value")[0];
				var FilterValue = xmlTemp.firstChild.nodeValue;
				filtersStr += FilterType+": "+FilterValue+", ";
			}
			filtersStr = filtersStr.replace(/, $/, "");
			if ((filtersStr != "None: None") && (filtersStr != "")) {
				//newHTML = newHTML + " Filters: " + filtersStr;
				newHTML = newHTML + " (filters applied)";
			}
				
			newHTML += "</p>";

			// Add RSS link.
			newHTML += " <a class=\"RSSlink\" href=\"JavaScript:void(0)\" target=\"_blank\" id=\"RSSlink\" onclick=\"this.href=RSSurl\">RSS</a>";

			// Compose "play all" links for some browse areas.
			if ((SearchHitCount > 1) && (1 == 2)) {
				if ((SearchType == "playlist") || (SearchType == "series")) {
					newHTML += " <a class=\"playAll\" onclick=\"playAll('id', " + SearchValue + ", 'custom')\">Play All</a>";
				}
				else if (SearchType == "category") {
					newHTML += " <a class=\"playAll\" onclick=\"playAll('catID', " + SearchValue + ", 'custom')\">Play All</a>";
				}
				else if (SearchType == "contributor") {
					newHTML += " <a class=\"playAll\" onclick=\"playAll('contribID', " + SearchValue + ", 'custom')\">Play All</a>";
				}
				else if (SearchType == "tag") {
					newHTML += " <a class=\"playAll\" onclick=\"playAll('tag', '" + SearchValue + "', 'custom')\">Play All</a>";
				}
			}
			
			newHTML += "<span>" + pageIndex + "</span>";
			document.getElementById('pagingcontrols').innerHTML = newHTML;
				
			// Show all video items found for this page of results.
			var xmlVideos = xmlDoc.getElementsByTagName("Video");
			for (var n=0; n<xmlVideos.length; n++) {
				var xmlTemp = xmlVideos[n].getElementsByTagName("VideoID")[0];
				var VideoID = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("VideoTitle")[0];
				var VideoTitle = unencodeHTMLentities(xmlTemp.firstChild.nodeValue);
				var xmlTemp = xmlVideos[n].getElementsByTagName("VideoDuration")[0];
				var VideoDuration = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("Thumb")[0];
				var Thumb = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("IsLive")[0];
				var IsLive = xmlTemp.firstChild.nodeValue;
				
				videoList = videoList + "<li>";
				if (nowPlayingVideoID == VideoID) {
					videoList += "<span class=\"nowPlaying\" title=\""+VideoID+"\">now playing</span>";
				}
				else {
					videoList += "<span class=\"notPlaying\" title=\""+VideoID+"\"></span>";
				}
				videoList += "<a href=\"JavaScript:void(0)\" onclick=\"loadVideo('"+VideoID+"', 'search', '"+IsLive+"')\"><img src=\""+Thumb+"\" alt=\"\" class=\"videoThumb\"/></a><span class=\"videoTitle\"><a href=\"JavaScript:void(0)\" onclick=\"loadVideo('"+VideoID+"', 'search', '"+IsLive+"')\">"+VideoTitle+"</a><span class=\"duration\"> "+VideoDuration+"</span></span><span class=\"playlistAdd\"><a href=\"JavaScript:void(0)\" onclick=\"addToPlaylist('"+VideoID+"')\"></a></span></li>";
			}
			
			// Show search terms used if no hits found.
			if (videoList == "") {
				videoList = "<span id=\"zeroSearchHitsSuggestions\"><p>But don't give up!</p><ul><li>Check for spelling errors</li><li>Try using singular words instead of plural</li><li>Still no luck? <a href=\"/video/feedback.cfm\">Tell us what you'd like to see on CornellCast</a></li></ul></span>";
			}
			
			// Update display to show the items found.
			document.getElementById('choicesvideosList').innerHTML = videoList;
			
			// Save contents to hidden area for quick swapping.
			var hiddenArea = SearchType;
			if (hiddenArea == "latest") {
				hiddenArea = "category";
			}
			document.getElementById('videos-'+hiddenArea).innerHTML = document.getElementById('choicesvideosList').innerHTML;
			//alert(document.getElementById('nav-'+hiddenArea).innerHTML);
			document.getElementById('nav-'+hiddenArea).innerHTML = document.getElementById('pagingcontrols').innerHTML;
			//alert(document.getElementById('nav-'+hiddenArea).innerHTML);
			
			// Update "add to my playlist" buttons for items already in it.
			removeAddPlaylistButtons('add');
		}
	}
}

function playAll(playlistType, playlistID, carousel) {
	// Load a playlist into a specific carousel and cause the first item to play.
	var url = "ccast-micro.cfm?action=playAll&playlistID="+playlistID;
	url = url + "&playlistType="+playlistType+"&carousel="+carousel;
	url = url + "&dummy=" + new Date().getTime();
	//alert(url);
	request.open("GET", url, true);
	request.onreadystatechange = playAllResponse;
	request.send(null);
}

function playAllResponse() {
	if (request.readyState == 4) {
		if (request.status == 200) {
			var videoList = "";
			var xmlDoc = request.responseXML;
			
			var xmlTemp = xmlDoc.getElementsByTagName("PlaylistName")[0];
			var xmlPlaylistName = xmlTemp.firstChild.nodeValue;
			var xmlTemp = xmlDoc.getElementsByTagName("PlaylistType")[0];
			var xmlPlaylistType = xmlTemp.firstChild.nodeValue;
			var xmlTemp = xmlDoc.getElementsByTagName("PlaylistID")[0];
			var xmlPlaylistID = xmlTemp.firstChild.nodeValue;
			var xmlTemp = xmlDoc.getElementsByTagName("CarouselName")[0];
			var xmlCarouselName = xmlTemp.firstChild.nodeValue;
			nowPlayingSequence = "";

			var xmlVideos = xmlDoc.getElementsByTagName("Video");
			for (var n=0; n<xmlVideos.length; n++) {
				var xmlTemp = xmlVideos[n].getElementsByTagName("VideoID")[0];
				var VideoID = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("VideoTitle")[0];
				var VideoTitle = unencodeHTMLentities(xmlTemp.firstChild.nodeValue);
				var xmlTemp = xmlVideos[n].getElementsByTagName("VideoDuration")[0];
				var VideoDuration = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("Thumb")[0];
				var Thumb = xmlTemp.firstChild.nodeValue;
				var xmlTemp = xmlVideos[n].getElementsByTagName("IsLive")[0];
				var IsLive = xmlTemp.firstChild.nodeValue;
				//var xmlTemp = xmlVideos[n].getElementsByTagName("SecondsToStart")[0];
				//var SecondsToStart = xmlTemp.firstChild.nodeValue;
				//var xmlTemp = xmlVideos[n].getElementsByTagName("WhenDate")[0];
				//var WhenDate = xmlTemp.firstChild.nodeValue;
				//var xmlTemp = xmlVideos[n].getElementsByTagName("WhenTime")[0];
				//var WhenTime = xmlTemp.firstChild.nodeValue;
				var leftPx = n * carouselLeftPxSpacing;
				
				// If on first video returned, set some variables to make it play.
				if ((n == 0) && (xmlCarouselName != "featured")) {
					nowPlayingVideoID = VideoID;
					nowPlayingLive = IsLive;
				}
				else if ((n > 0) && (xmlCarouselName != "featured")) {
					nowPlayingSequence += VideoID + ",";
				}
				
				//videoList = videoList + "<div class=\"panel\" style=\"float: none; position: absolute; left: " + leftPx + "px;\">";
				videoList = videoList + "<div class=\"panel\">";
				if (nowPlayingVideoID == VideoID) {
					videoList += "<span class=\"nowPlaying\" title=\""+VideoID+"\">now playing</span>";
				}
				else {
					videoList += "<span class=\"notPlaying\" title=\""+VideoID+"\"></span>";
				}

				//videoList += "<a href=\"JavaScript:void(0)\" onclick=\"loadVideo('"+VideoID+"', 'search', '"+IsLive+"')\"><img src=\""+Thumb+"\" alt=\"\" class=\"videoThumb\"/></a><span class=\"videoTitle\"><a href=\"JavaScript:void(0)\" onclick=\"loadVideo('"+VideoID+"', 'search', '"+IsLive+"')\">"+VideoTitle+"</a><span class=\"duration\"> "+VideoDuration+"</span></span><span class=\"playlistAdd\"><a href=\"JavaScript:void(0)\" onclick=\"addToPlaylist('"+VideoID+"')\"></a></span></li>";

				videoList += "<a href=\"JavaScript:void(0)\" onclick=\"loadVideo('"+VideoID+"', '"+xmlCarouselName+"', '"+IsLive+"')\">";
				videoList += "<img src=\""+Thumb+"\" alt=\"\" />";
				videoList += "</a> ";
				videoList += "<p>";
				videoList += "<a href=\"JavaScript:void(0)\" onclick=\"loadVideo('"+VideoID+"', '"+xmlCarouselName+"', '"+IsLive+"')\">"+VideoTitle+"</a>";
				videoList += "<a href=\"JavaScript:void(0)\" onclick=\"addToPlaylist('"+VideoID+"')\" class=\"playlistAdd\" title=\"cssbody=[tooltip] header=[] body=[add to my playlist]\"></a>";
				videoList += "</p> </div>";
			}
			//alert(videoList);
			//document.getElementById(xmlCarouselName+'CarouselBelt').innerHTML = videoList;
			if (xmlCarouselName == "custom") {
				var tabLink = "<span class=\"tab\"></span><a href=\"JavaScript:void(0)\" onClick=\"showCarousel('"+xmlCarouselName+"')\">"+xmlPlaylistName+"</a>";
				document.getElementById(xmlCarouselName + "Tab").innerHTML = tabLink;
			}
			document.getElementById(xmlCarouselName + "Tab").className = "chosen";
			// Start the new sequence playing, unless just changing to the featured tab.
			showCarousel(xmlCarouselName);
			checkCarouselArrows(xmlCarouselName);
			if (xmlCarouselName == "custom") {
				activeCarousel = xmlCarouselName;
				nowPlayingSequence = nowPlayingSequence.replace(/,$/, "");
				var temp = nowPlayingSequence;
				loadVideo(nowPlayingVideoID, xmlCarouselName, nowPlayingLive, 1);
				nowPlayingSequence = temp;
			}
			//alert(xmlCarouselName+"Carousel "+videoList);
			//stepcarousel.loadcontent(xmlCarouselName+"Carousel", videoList);
		}
	}
}

function removeAddPlaylistButtons(action) {
	// Remove the "Add to Playlist" buttons for videos already in "my playlist."
	var myplaylistCookieNew = getCookie("CornellCastMyPlaylist");
	var cookieVideos = myplaylistCookieNew.split(",");
	for (var i=0; i<cookieVideos.length; i++) {
		//alert(cookieVideos[i]);
		updatePlaylistButtons(cookieVideos[i], action);
	}
}

function executeFlashPlayer() {
	//alert("Now playing(?) " + nowPlayingVideoID);
	smh.addVariable("videoID", nowPlayingVideoID);
//	<cfif IsDefined("url.startSecs")>smh.addVariable("startSecs", "<cfoutput>#url.startSecs#</cfoutput>");</cfif>
//	<cfif IsDefined("url.endSecs")>smh.addVariable("endSecs", "<cfoutput>#url.endSecs#</cfoutput>");</cfif>
//	<cfif #playingLive# EQ true>smh.addVariable("isLIVE", "true");</cfif>
//	<cfif #playingLive# EQ true>smh.addVariable("livesname", "live_<cfoutput>#nowPlayingVideoID#</cfoutput>");</cfif>
	smh.addParam("allowScriptAccess", "always");
	smh.addParam("wmode", "transparent");
	smh.addParam("allowfullscreen", "true");
	smh.addParam("quality", "high");
	smh.write("flashcontent");
	//alert("Now playing(?) " + nowPlayingVideoID);
}

var flashMovie;
function onloadCornellCast() {
	// Load and display default contents, or contents according to incoming parameter.
	flashMovie = document.getElementById("ei_test");
	updateNowPlayingOverlay(nowPlayingVideoID);
	removeAddPlaylistButtons('add'); // Do initially for immediate results.
	showCatalog('category');
	updatePlaylistTabCount();
	ccastSearch("latest", 0, 1, "subNavCategoryLatest");
	setTimeout("removeAddPlaylistButtons('add')", 2000); // Do this again after Ajax completes.
	setDescriptionHeight();
	if (testLiveWarning) {
		alertLiveEventStart("Hello World!", 0);
	}
	//initRSH();
	//setTimeout("executeFlashPlayer()", 12000);
	//setInterval("monitorSchedule()", checkInterval);
	//setInterval("monitorScheduledVideos()", checkInterval);
}

// Cookies functions from http://www.w3schools.com/JS/js_cookies.asp
function getCookie(c_name) {
	if (document.cookie.length > 0) {
		c_start = document.cookie.indexOf(c_name + "=");
		if (c_start != -1) { 
			c_start = c_start + c_name.length + 1; 
			c_end = document.cookie.indexOf(";", c_start);
			if (c_end == -1) {c_end = document.cookie.length;}
			return unescape(document.cookie.substring(c_start, c_end));
		} 
	}
	return "";
}

function setCookie(c_name, value, expiredays) {
	var exdate = new Date();
	exdate.setDate(exdate.getDate() + expiredays);
	var cookieStr = c_name + "=" + escape(value) + ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString()+"; path=/");
	document.cookie = cookieStr;
}

function submitEnter(myfield,e) {
	// Detect enter key being pressed to execute search.
	// From http://www.htmlcodetutorial.com/forms/index_famsupp_157.html
	var keycode;
	if (window.event) keycode = window.event.keyCode;
	else if (e) keycode = e.which;
	else return true;
	
	if (keycode == 13) {
		//validateSearch();
		showCatalog('text'); 
		ccastSearch('text', document.getElementById('searchbox').value, 1, 'text');
		return false;
	}
	else {
		return true;
	}
}

