///////////////////////////////////////////////////////////////////////////////
// ajaxtitles.js - This JavaScript file will automatically update the titles //
//                 on the homepage of the C-89.5 Worldwide site.  It does    //
//                 this by using AJAX.  It reads in the file /web/livetitles //
//                 /ajaxresponse.asp, does all the time offsetting, and      //
//                 updates the display on the homepage.  It was written in   //
//                 full by Matthew Charles Cohn, November 2005.              //
//                                                                           //
//                 Last updated May 2006                                     //
//                                                                           //
//                 :: knhcsite (a) mymail (d) mattcohn (d) com ::            //
//                                                                           //
//                 No part of this code may be reused without permission     //
//                 from the author (that's me!!!) but I'm a pretty chill     //
//                 guy so why don't you just e-mail me.  If you have any     //
//                 other web-dev questions or questions about radio or       //
//                 automating for radio, I may be able to help you out       //
//                 there too.                                                //
///////////////////////////////////////////////////////////////////////////////
// NOTE:  ajaxtitles.asp is the same as ajaxtitles.js, the ASP version is    //
//        being used while we have ASP code in here checking for the         //
//        existance of the "classytitles" cookie.                            //
///////////////////////////////////////////////////////////////////////////////
	
	var XMLurl = "/web/livetitles/ajaxresponse.asp?show=all";	// The server-side script
																	// for the livetitles XML
	var HTMLurl = "/web/content/LivePlaylist.asp";	// The server-side script
													// for the playlist page
																  
	var bolUpdateLivePlaylist = false;	// Should this script update the live playlist?
										// (is set to true later if we are on the
										//  liveplaylist page)

	var baseNewHTML = '';
	var baseMostCurrentStartTime = 0;
	var baseMostCurrentEndTime = 0;
	var bolSuppressNextFade = 'false';
		
	function updateProgressBar() {
		// This function updates the progress bar (div#pagetopPlaylistInnerBar) with the
		// current position of the playing song, as is found by offsetting the starttime
		// of the playing song and using the duration field.
		
		var delay = 1000;
		// The delay, in milliseconds, is how long we wait before calling this function
		// again.
				
		if (Date.parse(Date()) < baseMostCurrentEndTime) {
			// If the song has not finnished yet (now is less than end time)
			
			// calculate the new width of the progress bar (as a percentage, 0 - 100)
			var newWidth = 100*((baseMostCurrentEndTime-Date.parse(Date()))/(baseMostCurrentEndTime-baseMostCurrentStartTime));
			
			// apply the new width to the progress bar
			document.getElementById('pagetopPlaylistInnerBar').style.width = newWidth + "%";
			
			// re-call this function after the delay
			setTimeout("updateProgressBar();", delay);
		} else if (document.getElementById('pagetopPlaylistInnerBar') != null) {
			// If the song has alraedy finnished, clear the progress bar and do not re-call
			// this function until a new song is displayed.
			document.getElementById('pagetopPlaylistInnerBar').style.width = "0px";
		}
	}
	
	function handleHTMLHttpResponse() {
		// This function is called if bolUpdateLivePlaylist is True, which meens
		// we are on the liveplaylist page.  It refreshes the entire body content
		// with the page from HTMLurl
	
		if (HTMLhttp.readyState == 4) {
			var htmldoc = HTMLhttp.responseText;
			document.getElementById('bodyContent').innerHTML = htmldoc;
		}
	}

	function handleXMLHttpResponse() {
		// This function handles the new PlayList XML file we just requested, XMLurl.
		// It does all the parsing, all the time-offsetting, all the really nifty stuff.
	
		if (XMLhttp.readyState == 4) {
			var xmldoc = XMLhttp.responseXML;
			var root = xmldoc.getElementsByTagName('PlayList').item(0);
			var pastHTML = '';
			var currentHTML = '';
			
			baseMostCurrentStartTime = 0;
			baseMostCurrentEndTime = 0;
			
			// Set a default message in case we don't have a mostcurrent Playing song
			var mostcurrentHTML = '<a id="pagetopPlaylistText" href="/web/default.asp?page=liveplaylist">C-89.5 - Seattle\'s Hottest Music</a>';
			// And set mostCurrentIsDefault to 'true', will be overwritten with 'false' later if applicable.
			var mostcurrentIsDefault = 'true';
			
			var futureHTML = '';
			
			// Set a default time delay before re-requesting the PlayList XML.
			// This value will be overwritten later if a song is currently playing,
			// or will be added to later in the program if nothing is currently
			// playing.
			var newUpdateTime = 5000;
			
			// Here we are calculating the variable 'timeOffset'.  This variable is added
			// to all the starttime values later on to get the actual start time based on
			// the local user's clock.
			var clientTime = Date();
			var localTime = root.getAttribute("localtime");
			var timeOffset = root.getAttribute("timeoffset");

			var strClientTime = Date.parse(clientTime);
			var strLocalTime = Date.parse(localTime);
			
			var newTimeOffset = strClientTime - strLocalTime;
			newTimeOffset = newTimeOffset / 1000;
			
			timeOffset = parseFloat(timeOffset) + parseFloat(newTimeOffset);
			// Done calculating timeOffset!!
												
			for (var iNode = 0; iNode < root.childNodes.length; iNode++) {
				// For Each "Entry" node in "PlayList" //
				// each time this loop runs, a new object "newEntry" is referenced below,
				// and represents one row in the LivePlaylist table / one song... glory
			
				var newEntry = root.childNodes.item(iNode);
				var newArtist = '';
				var newTitle = '';
				var newComposer = '';
				var newMusicId = '';
				var newAlbum = '';
				var newStartTime = '';
				var newStartTimeAdj = new Date();
				var newEndTimeAdj = new Date();
				var newDuration = '';
				var newType = '';
				var newIsDefault = '';
												
				for (var iNode2 = 0; iNode2 < newEntry.childNodes.length; iNode2++) {
					// For Each child node in an "Entry" //
					// each time this loop runs, a new object "attNode" references an
					// attribute of the current entry, and represents one column on the
					// current entry row.
				
					var attNode = newEntry.childNodes.item(iNode2);
					if (attNode.childNodes.length > '0') {
						switch (attNode.nodeName) {
							// Switch between all of the different nodes we would expect
							// in an "Entry" node, and assign their values to the Entry-
							// level variable.  
						
							case 'artist':		newArtist = attNode.firstChild.data; break;
							case 'title':		newTitle = attNode.firstChild.data; break;
							case 'composer':	newComposer = attNode.firstChild.data; break;
							case 'musicid':		newMusicId = attNode.firstChild.data; break;
							case 'album':		newAlbum = attNode.firstChild.data; break;
							case 'starttime':	newStartTime = attNode.firstChild.data;
												newStartTime = Date.parse(newStartTime);
												newStartTime = parseFloat(newStartTime) + parseFloat(timeOffset) * 1000;
												newStartTimeAdj.setTime(newStartTime);
												break;
							case 'duration':	newDuration = attNode.firstChild.data; break;
							case 'type':		newType = attNode.firstChild.data; break;
						}
					}
				}

				//CALCULATE END TIME//
				newEndTimeAdj.setTime(newStartTimeAdj.getTime() + parseFloat(newDuration) * 1000)

				//IF A PLAYING EVENT, MAKE IT SET THE TIMEOUT//
				//this will get overwritten by each playing event
				//so only the last playing event's timeout will
				//be created
				if (newType == 'Playing') {
					//only update if the value is positive
					if (newEndTimeAdj.getTime() > strClientTime) {
					
						baseMostCurrentStartTime = newStartTimeAdj.getTime();
						baseMostCurrentEndTime = newEndTimeAdj.getTime();
						newUpdateTime = newEndTimeAdj.getTime() - strClientTime;
						
					}
				}

				//CREATE HTML OUTPUT//
				//Title / Artist / Link//
				var newHTML = '';
				newHTML = newHTML + '<a id="pagetopPlaylistText" href="/web/default.asp?page=liveplaylist">';

				if (newArtist != '' || newTitle != '')
				{
					newHTML = newHTML + newArtist;
					newHTML = newHTML + ' - ';
					newHTML = newHTML + newTitle;
					
					// If the newEntry is NOT the default text, set newIsDefault to 'false'
					newIsDefault = 'false';
				} else
				{
					newHTML = newHTML + 'C-89.5 - Seattle\'s Hottest Music';
					
					// If the newEntry IS the default text, set newIsDefault to 'true'
					newIsDefault = 'true';
				}

				newHTML = newHTML + '</a>';
				//CD Universe Link//
				if (newMusicId != '' && IsNumeric(newMusicId))
				{
					newHTML = newHTML + '<a id="pagetopPlaylistCDUniverse" href="http://www.cduniverse.com/productinfo.asp?style=music&amp;bab=E&amp;pid=' + newMusicId + '&amp;frm=lk_c895fm">(Buy Online)</a>';
				} else if (newMusicId != '')
				{
					newHTML = newHTML + '<a id="pagetopPlaylistCDUniverse" href="http://' + newMusicId + '">(Buy Online)</a>';
				}
				
				
				//ASSIGN HTML OUTPUT TO CORRECT AREA//
				switch (newType)
				{
					case 'Played': pastHTML = pastHTML + newHTML; break;
					case 'Playing': 
									// Only counts if playing if endtime is greater than now
									if (newEndTimeAdj.getTime() > strClientTime) {
										currentHTML = currentHTML + newHTML;
										mostcurrentHTML = newHTML;
										mostcurrentIsDefault = newIsDefault;
									}
									break;
					case 'Not Played': futureHTML = futureHTML + newHTML; break;
				}
			}

			// THIS IS FOR DEBUGGING ONLY!!! //
			//document.getElementById('past').innerHTML = pastHTML;
			//document.getElementById('current').innerHTML = currentHTML;
			//document.getElementById('future').innerHTML = futureHTML;
			//document.getElementById('pagetopPlaylistText').innerHTML = mostcurrentHTML;
			// END DEBUG CODE //
			
			// Add five seconds to the end time of the last song before updating the XML
			// to give the next song time to start.
			newUpdateTime = newUpdateTime + 5000;
			// Add another random delay between 0 and 3 seconds to reduce server strain
			newUpdateTime = newUpdateTime + Math.random() * 3000;
						
			// Now set the timeout to re-load the XML file, it will be the endtime of the
			// current song (length, NOT EOM, and rounded to the second) plus a random
			// delay of between 5 and 8 seconds
			setTimeout ("updateLiveTitles();", newUpdateTime);
			
			// Add the progress bar div code to the beginning of the generated HTML for
			// the live playlist, if mostcurrentIsDefault != 'true', or if the display 
			// text is NOT just the default text.
			if (mostcurrentIsDefault != 'true') {
				mostcurrentHTML = '<div id="pagetopPlaylistOuterBar"><div id="pagetopPlaylistInnerBar"></div></div>' + mostcurrentHTML;
			}
			if (baseNewHTML != mostcurrentHTML) {
				// Finally, if the newly generated code is different than the currently
				// displayed code, call updateWebsite (which will update the liveTitles)
				// and updateLivePlaylist (which will update the livePlaylist)
				
				baseNewHTML = mostcurrentHTML;
				updateWebsite();
				updateLivePlaylist();
			}
		}
	}

	function updateWebsite() {
		// updateWebsite starts by calling the first control of the fadeText function.
		// The settings for fadeText(0, 0) are defined below, beginning with the line
		// "if (intControl == 0) { " in the fadeText function.
		//
		// Only fade the text if bolSuppressNextFade is not True.  If it is true,
		// just switch the website text.
		if (bolSuppressNextFade != 'true') {
			fadeText(0, 0);
		} else {
			switchWebsiteText();
		}
	}
	
	function fadeText(intStep, intControl) {
		var intTTLSteps = 0;
		var intDelay = 0;
		var intStartR = 0;
		var intStartG = 0;
		var intStartB = 0;
		var intFinalR = 0;
		var intFinalG = 0;
		var intFinalB = 0;
		
		if (intControl == 0) {
			intTTLSteps = 50;
			intDelay = 5;

			intStartR = 255;
			intStartG = 131;
			intStartB = 03;
			intFinalR = 0;
			intFinalG = 0;
			intFinalB = 0;
		} else if (intControl == 1) {
			intTTLSteps = 15;
			intDelay = 5;

			intStartR = 51;
			intStartG = 85;
			intStartB = 102;
			intFinalR = 255;
			intFinalG = 131;
			intFinalB = 03;
		}
		
		var intStepR = 0;
		var intStepG = 0;
		var intStepB = 0;
		
		intStepR = (intStep / intTTLSteps) * (intFinalR - intStartR) + intStartR;
		intStepG = (intStep / intTTLSteps) * (intFinalG - intStartG) + intStartG;
		intStepB = (intStep / intTTLSteps) * (intFinalB - intStartB) + intStartB;

		intStepR = Math.round(intStepR);
		intStepG = Math.round(intStepG);
		intStepB = Math.round(intStepB);

		document.getElementById('pagetopPlaylistText').style.color = 'rgb(' + intStepR + ' ,' + intStepG + ', ' + intStepB + ')';
		
		if (intTTLSteps == intStep) {
			doneFading(intControl);
		} else {
			intStep++
			setTimeout("fadeText(" + intStep + ", " + intControl + ");", intDelay);
		}
	}
	
	function doneFading(intControl) {
		if (intControl == 0) {
			switchWebsiteText();
		}
	}
	
	function switchWebsiteText() {
		document.getElementById('pagetopPlaylistBody').innerHTML = baseNewHTML;
		updateProgressBar();

		// Only fade the text if bolSuppressNextFade is not True.  If it is true,
		// just re-set the variable.
		if (bolSuppressNextFade != 'true') {
			fadeText(0, 1);
		} else {
			bolSuppressNextFade = 'false';
		}
	}
	
	
	function fadeWebsiteTextIn(intStep) {
		document.getElementById('pagetopPlaylistText').style.color = 'rgb(255, 131, 03)';
	}

	function updateLiveTitles(bolSuppressFade) {
		bolSuppressNextFade = bolSuppressFade;
	
		XMLhttp.open("GET", XMLurl, true);
		XMLhttp.onreadystatechange = handleXMLHttpResponse;
		XMLhttp.send(null);
	}

	function updateLivePlaylist() {
		if (bolUpdateLivePlaylist == true) {
			HTMLhttp.open("GET", HTMLurl, true);
			HTMLhttp.onreadystatechange = handleHTMLHttpResponse;
			HTMLhttp.send(null);
		}
	}

	function getHTTPObject() {
		// This code was not written by Matt Cohn, it is property of the public domain
		var xmlhttp;
		/*@cc_on
		@if (@_jscript_version >= 5)
			try {
				xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
			} catch (e) {
			try {
				xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (E) {
				xmlhttp = false;
			}
		}
		@else
			xmlhttp = false;
		@end @*/
		
		if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
			try {
				xmlhttp = new XMLHttpRequest();
			} catch (e) {
				xmlhttp = false;
			}
		}
			return xmlhttp;
	}

	function IsNumeric(sText) {
		// This code was not written by Matt Cohn, it is property of the public domain
		var ValidChars = "0123456789";
		var IsNumber=true;
		var Char;
		
		
		for (i = 0; i < sText.length && IsNumber == true; i++) 
		{ 
			Char = sText.charAt(i); 
			if (ValidChars.indexOf(Char) == -1) 
			{
				IsNumber = false;
			}
		}
		return IsNumber;
	}
	
	function debugAlert (strMessage) {
		//alert (strMessage);
	}
	
	
	var XMLhttp = getHTTPObject(); // We create the HTTP Object
	var HTMLhttp = getHTTPObject(); // We create another, for the playlist