/*
 * Google Analytics
 */

//var pageTracker = _gat._getTracker("UA-123456-1");


/*
 *  Stoopid global variables
 */

var upperDrawerIsClosed 	= true;

var postControllerObject 	= null;

var videoMenuObject 		= null;

var lastSearch 		= "";
var oldClickEvent 	= "";
var homePage 		= "Homepage";

var currentPage 	= "";
var currentPageType = ""; // set in page.js by seriesCallBack

var allShows 		= new Array();
var allThemes		= new Array();

var isHash = true;	// used by 

var VIDEO_MENU_ID = "selector";

var ignoreTags = new Array();
ignoreTags.push(homePage);
ignoreTags.push("s-");
ignoreTags.push("e-");


// truncate limits
var CHARACTER_MAX_TRUNCATABLE			= 170;
var CHARACTER_MAX_SHORT_TRUNCATABLE		= 30;
var CHARACTER_MAX_EPISODE_TRUNCATABLE	= 150;

/*
 * String trimming functions.
 */

String.prototype.trim = function() 
{
	return this.replace(/^\s+|\s+$/g,"");
}
String.prototype.ltrim = function() 
{
	return this.replace(/^\s+/,"");
}
String.prototype.rtrim = function() 
{
	return this.replace(/\s+$/,"");
}


/**
 * For well formed HTML, safely truncates to a limit by waiting for tag closures.
 * Note: Safety is a trade off, no garuentee for limit. Limit is a minimum. 
 * @param aMessage the text to be truncated
 * @aLimit the maximum allowable amount of characters
 * @returns 
 */
String.prototype.safeTruncate = function (aLimit)
{
	// Program definite openings and closings here
	var myPairs = [["<a", "</a>"]];

	// init 	
	var myStack = new Array();
	var lengthOfLastPop = 0;
	var result = "";

	// interate through message
	for (var i = 0; i < this.length; i++ )
	{

		// look through all pairs
		for ( var k = 0; k < myPairs.length; k++ )
		{

			// Is there a first element?
			if ( this.matchWithAt( myPairs[k][0], i ) )
			{
				// Aahhhh just push it
				myStack.push( myPairs[k][1] );
			}

			// Did I find the closing tag?
			if ( myStack.length > 0 && this.matchWithAt( myStack[myStack.length - 1], i ) )
			{
				// Pop it, don't lock it
				// Save the length because if it's the last one we'll need to include it our return
				lengthOfLastPop = myStack.pop().length;
			}

			// If there's no closing tags we're looking for and we're past our limit, return the string.
			if ( myStack.length == 0 && i >= aLimit )
			{
				// return safely truncated string.
				return this.substr( 0 , i + lengthOfLastPop);
			}

		}

	}

	// Shouldn't ever reach this. Might be something wrong with myPairs programming.
	return "SafeTruncate Error";

} // END of safeTruncate

/**
 * Matches a pattern at a specified index, for only the length of the pattern
 */
String.prototype.matchWithAt = function ( aPattern, anIndex )
{

	// Make sure there's something there to compare to
	if (!aPattern)
	{
		return false;
	}

	// See if the pattern is at the index
	if (this.substr(anIndex, aPattern.length) == aPattern)
	{
		// yes it is
		return true;
	}

	// No it isn't
	return false;
	
} // END of matchWithAt





$( function ($) 
{
	$.easing.eased = function(x, t, b, c, d) 
	{
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.7*1.5);
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;

	};
	
})


/** 
 * Returns the Y coordinate (topmost) of an object on the screen
 * @param obj an dom object
 * @return a position in pixels
  */
function getPosY ( anObjectId )
{

	var object = document.getElementById(anObjectId);

	var myPosY = object.offsetTop;

	while ( object.offsetParent )
	{

		myPosY = myPosY + object.offsetParent.offsetTop;

		if( object == document.getElementsByTagName("body")[0] )
		{
			break;
		} else
		{
			object = object.offsetParent;
		}
	}
	
	return myPosY;

} // END of findPosY



/** 
 * Returns the X coordinate (leftmost) of an object on the screen
 * @param anObject an dom object
 * @return a number in pixels
 */
function getPosX( anObject ){
	
	var myPosX = anObject.offsetLeft;
	
	while ( anObject.offsetParent )
	{
		myPosX = myPosX + anObject.offsetParent.offsetLeft;
		
		if( anObject == document.getElementsByTagName("body")[0] )
		{
			break;
		} else
		{
			anObject = anObject.offsetParent;
		}
	}
	
	return myPosX;
	
} // END of findPosX


/** 
 * Removes HTML tags from a string. 
 * Adapted from original code by Robert Nyman.
 */
String.prototype.removeHTML = function ()
{
	
	var myResult = this;

 	myResult = myResult.replace(/&(lt|gt);/g, function (strMatch, p1) {
 	 	return p1 == "lt" ? "<" : ">";
 	});
 
	myResult = myResult.replace(/<\/?[^>]+(>|$)/g, "");
 			
	return myResult;
	
}


/**
 * Hijacks clicks so they don't go to #soandso but add it to the url
 * 
 */
function clickHandler ( aClickedThing )
{

	var newHash;
	var myPair; 
	var aTagString;
	var hashVariables;
	var onePair;
	var oneHashVariable;
	var oneCommand;

	// Get the href attribute of the A tag that was just clicked.
	aTagString  = new String ( aClickedThing );

	// just the variables
	hashVariables = aTagString.getHashVariablesArray();
	
	// send the click to google analytics
	
	analyticsLink = new String( aClickedThing.target );

	analyticsLink.removeParameterStartingWith("command");

	pageTracker._trackPageview( analyticsLink );

	// Go through each known reflex
	for ( var i in hashVariables )
	{

		// handles
		//oneReflex		= myHash.myReflexes[i];
		oneHashVariable = hashVariables[i];
		onePair = oneHashVariable.split("=");

		// if it's not a command hash, update the variable in the window hash string
		if (oneHashVariable.indexOf("command") == -1)
		{
			myHash.update(onePair[0], onePair[1]);
		}

		/*
		 * If a command is found, handle it
		 */
		if (oneHashVariable.indexOf("command") != -1)
		{

			// get just command
			oneCommand = oneHashVariable.substr(7, oneHashVariable.length);

			/*
			 * Post controller
			 */

			if ( oneCommand == "PostBack" ) 
			{ 
				postControllerObject.selectBack(); 
			}

			if ( oneCommand == "PostForward" ) 
			{ 
				postControllerObject.selectForward(); 			
			}
			
			/*
			 * Video menu
			 */
			if ( oneCommand == "PlayNow" ) 
			{ 
				forcePlayImmediately = true;
			}
			
			
			if ( oneCommand == "FocusVideo" )
			{
				// If clicked object is kinda far down on the screen then make the window scroll so the user can see the video screen
				if (findPosY(clickedThing) > 500) 
				{
					$('html, body').animate({
						scrollTop: $("#topScrollStop").offset().top
						}, 500);
				}
			}
			
			if ( oneCommand == "HeaderPageLink" )
			{
				myHash.update ("hp", null);
			}
			
			
			if ( oneCommand == "CloseDrawer")
			{

				if (!upperDrawerIsClosed)
				{
					myHash.update ("hp", null);
					toggleUpperDrawer();
				}

			}
			
			// If the same topMenu button is clicked while it's open, close the drawer
			if ( oneCommand == "ToggleDrawer" )
			{
				if ( !myHash.isChanged("hp") )
				{
					if ( !upperDrawerIsClosed )
					{
						myHash.update ("hp", null);
					
					}
				
					toggleUpperDrawer();
				
				}

			
			}

		}
		
	}

	return false;

} // END of clickHandler


/*
 * Hash variables 
 */


/** 
 * Returns everything past the "#" symbol, if no "#" found returns the unaltered string.
 */
String.prototype.removePound = function ()
{
	// if "#" exists then return everything past it, otherwise return "this"
 	return ( this.indexOf("#") > -1 ) ? this.split("#")[1] : this;
} // END of removePound()


/** 
  * Takes a complete URL or just string of variables delimited by "&" and returns an array of key=value pairs.
  * @return An array of key=value pairs
  */
String.prototype.getHashVariablesArray = function ()
{
	// if I don't find a "#" reutrn array split by "&", else, split by "#" THEN split by "&".
	return ( this.indexOf("#") == -1 ) ? this.split("&") : this.split("#")[1].split("&");	
}


/** Searches a string for key=value pairs delimited by &.
  * @param 	aKey name of the key to return.
  * @return the value associated with the key searched for. 
  */
String.prototype.getValue = function ( aKey )
{

	var allPairs;
	var onePair;
	var oneValue;

	allPairs = this.split("&"); 

	for ( var i in allPairs ) 
	{

		onePair 	= allPairs[i].split("=");
		oneValue	= onePair[1];
		oneKey 		= onePair[0];

		if (oneKey == aKey) 
		{
			return oneValue;
		}

	}
	return null;

} // END of getValue()


/**
 * Returns recognized seriesKey from a group of tags delimted by commas.
 *
String.prototype.getShowKey = function()
{

	for (var i in allShows)
	{
		for ( var j in myTags )
		{
			if (myTags[j] == allShows[i].myKey)
			{
				return allShows[i].myKey;
			}
		}	
	
	}

	return "Not defined";

} // END of getShowKey
*/

/*
 * Length of videos
 */

/**
 * Returns a formatted integer with a leading 0 for all < 9.
 */
function twoDigitFormat ( anInteger ) 
{
	
	// Ensure anInteger is < 100
 	if (anInteger > 99)
	{
		anInteger = 99;
	}
	
	// tack on a 0 and call it a day.
	return ( ( anInteger > 9 ) ? "" : "0" ) + anInteger;
}


/**
 * Converts a millisecond count to "hh:mmm:ss".
 */
function millisecondsToTime ( ms ) 
{
	
	var seconds, minutes, hours, formattedTime;
	
	seconds	= Math.floor(ms / 1000);
	minutes	= Math.floor(seconds / 60);
	seconds	= seconds % 60;

	formattedTime = twoDigitFormat(seconds);

	hours	= Math.floor(minutes / 60);
	minutes = minutes % 60;
	
	formattedTime = twoDigitFormat(minutes) + ":" + formattedTime;

	hours = hours % 60;
	
	formattedTime = ( twoDigitFormat( hours ) != "00" ) ? ( ":" + formattedTime ) : formattedTime;

	return formattedTime;

} // END of millisecondsToTime


/**
 * Sets the scroll position of the video secltor menu to the Y coordinates of an object.
 * @param anObjectId Usually the div id of the playlist title.
 */
function setMenuFocus( anObjectId ) 
{

	var VIDEO_MENU_ID = "selector";

	$("#" + VIDEO_MENU_ID).scrollTo( $("#"+anObjectId), 500 , {easing:'eased'} );

	return false;

} // END of setMenuFocus


/**
 * Animates the scroll position of the window to the Y coordinates of an object.
 * @param anObjectId Usually the div id of the playlist title.
 */
function setWindowFocus( anObjectId ) 
{

	$('html, body').animate( {
		scrollTop: $("#" + anObjectId ).offset().top
	}, 500);

} // END of setWindowFocus


/**
 * Sets javascript Date object from an string in ISO8601 date and time format.
 */
Date.prototype.setISO8601 = function( iso8601String ) 
{

	if (new String(iso8601String.constructor).indexOf("Object") != -1)
	{
		this.setDate(iso8601String.getDate());
		return false;
	}

    var regexp = "([0-9]{4})(-([0-9]{2})(-([0-9]{2})" +
        "(T([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?" +
        "(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?";

	var d = iso8601String.match(new RegExp(regexp));

    var offset = 0;

    var date = new Date(d[1], 0, 1);

	if (d[3]) 	{ date.setMonth(	d[3] - 1); }
	if (d[5]) 	{ date.setDate(		d[5]); }
	if (d[7]) 	{ date.setHours(	d[7]); }
	if (d[8]) 	{ date.setMinutes(	d[8]); }
	if (d[10]) 	{ date.setSeconds(	d[10]); }
	if (d[12]) 	{ date.setMilliseconds(Number("0." + d[12]) * 1000); }
	if (d[14]) 	
	{
		offset = (Number(d[16]) * 60) + Number(d[17]);
		offset *= ((d[15] == '-') ? 1 : -1);
	}

	offset -= date.getTimezoneOffset();

	time = (Number(date) + (offset * 60 * 1000));

	this.setTime(Number(time));

} // END of setISO8601


/*
 * Share form
 */

/**
 * returns the .value property of an input item.
 */
function getFormValue ( anId )
{
	return document.getElementById( anId ).value;
} // END of getFormValue


/**
 * Tries to set an input items value property, returns false if error occured.
 * @param anId 		the id of the input item
 * @param aValue 	the value to set
 */
function setFormValue ( anId, aValue )
{

	try
	{
		document.getElementById( anId ).value = aValue;
	} catch (e)
	{
		;
	} finally
	{
		return false;
	}

} // END of setFormValue



function processShareForm()
{

	var formValid = true;
	var feedbackMarkers = new Array();
	var compiledComment = "";

	var feedbackHTML;
	var myPostData;

	/*
	 * Validate
	 */ 
	
	userEmail 			= new String(getFormValue("shareEmail"));
	userEmailConfirm 	= new String(getFormValue("shareEmailConfirm"));
	userYtLink 			= new String(getFormValue("shareYtLink"));
	userName 			= new String(getFormValue("shareName"));
	userDescription		= new String(getFormValue("shareDescription"));
	userRelated			= new String(getFormValue("shareRelated"));
	
	feedbackHTML = "<img src=\"img/exclamation.gif\" />Please correct the fields below.<ul>";
	
	// youtube link
	if ( userYtLink.indexOf("http://www.youtube.com/") == -1)
	{
		feedbackMarkers.push(0)
		feedbackHTML += "<li>YouTube Link</li>";
		formValid = false;	
	}
	
	// description. No check.
	
	// related	
	if (userRelated.length < 10)
	{
		feedbackMarkers.push(2);
		feedbackHTML += "<li>Related to education</li>";
		formValid = false;
	} 

	// email
	if ( userEmail.indexOf("@") == -1 || userEmail.indexOf(".") == -1 ) 
	{
		feedbackHTML += "<li>Invalid email address</li>";
		feedbackMarkers.push(3);
		formValid = false;
	} 
	
	if ( userEmail.trim() != userEmailConfirm.trim() ) 
	{
		feedbackHTML += "<li>Email addresses do not match</li>";
		feedbackMarkers.push(3);
		formValid = false;
	} 
	
	feedbackHTML += "</ul>";

	// fill hidden fields
	if ( formValid )
	{

		compiledComment = "YouTube link\n"+userYtLink+"\n\nDescripton of video\n"+userDescription+"\n\nRelated becuase\n"+userRelated+"\n\nName\n"+userName;

		compiledComment = escape(compiledComment.replace(/ /g, "+"));

		setFormValue("contactinfo", userEmail);
		setFormValue("commenttext", compiledComment);

		myPostData = "category=video&commenttext="+compiledComment+"&contactinfo="+userEmail+"&educat_link=&dq=&question_category=Share+form";

		bodyContent = $.ajax({
			type: "POST",
			url: "lib/shareform.php",
			data: myPostData,
			success: function( data )
			{
				$("#shareForm").html("<h2>Thank you!</h2>Please continue to enjoy After Ed.");
			},
			async: false
		}).responseText;

		

		// document.getElementById("shareForm").submit();

	} else
	{

		$("#feedbackText").html(feedbackHTML);

		var feedbackTag;
		var i = 0;

		while (feedbackTag = document.getElementById("feedback-"+i))
		{
			$("#feedback-"+i).html("");
			i++;
		}

		for ( var i in feedbackMarkers )
		{
			$("#feedback-"+feedbackMarkers[i]).html("<img src=\"img/exclamation.gif\" />");
		}

	}

}


String.prototype.isIgnorable = function ()
{

	var result = false;

	for (var i in ignoreTags)
	{
		// If it doesn't not find it, meaning, if it finds it
		if ( this.indexOf( ignoreTags[i].toLowerCase() ) != -1 )
		{
			result = true;
		}

	}

	return result;

}


String.prototype.isTheme = function ()
{
	for (var i in allThemes)
	{
		if (this.toLowerCase() == allThemes[i].myKey.toLowerCase())
		{
			return true;
		}
	}
	return false
}





String.prototype.removeParameterStartingWith = function ( aString )
{

	snippet = this;

	while (snippet.indexOf(aString) != -1)
	{

		commandIndex	= this.indexOf(aString) - 1;
		commandEnd		= this.indexOf("&", commandIndex + 1);
	
		if ( commandEnd == -1 )
		{
			commandEnd = this.length;
		} 
		
		snippet = this.substr(0, commandIndex) + this.substr(commandEnd, analyticsLink.length - commandEnd);

	}

	return snippet;

}
