 /**
  * This file includes the functions necessary for html navigation of the Smithsonian
  * player.  A quick overview of the flow is that after the brightcove video player has 
  * loaded we use the player as a gateway to communicate to brightcove's backend and get
  * the lineup.  From this we create html elements that represent this videos and allows
  * the user to play a new video.
  * 
  * Also within this script file is the support for paging of the videos and continous play.
  *
  * @author Jesse Streb
  **/

var bc_gCurrentTitleId = null;
var bc_gFirstVideo = true;
var bc_gHitBottom = false;
var bc_gHitTop = true;
var bc_gVideoContainerHeight = 0;
var bc_gVideoContainer = null;
var bc_gSlideCount = 0;
var bc_gLineIdArray = new Array();
var bc_gVideoCount = 0;

var config = new Array();
config["videoId"] = null; //the default video loaded into the player
config["videoRef"] = null; //the default video loaded into the player by ref id specified in console
config["lineupId"] = null; //the default lineup loaded into the player
config["playerTag"] = null; //player tag used for identifying this page in brightcove reporting
config["autoStart"] = false; //tells the player to start playing video on load
config["preloadBackColor"] = "#000000"; //background color while loading the player
config["width"] = 300;
config["height"] = 278;
config["playerId"] = 1391584851;
config["adServerURL"]="http://ad.doubleclick.net/pfadx/gosmithsonian.tmus/homepage";

/**
 * onTemplateLoaded is the entry point for building our nav.  Once this is loaded we register our
 * eventListeners that we need in our javascript.
 * 
 * @param message If there was an error this is passed in here.
 */
function onTemplateLoaded(message) {
	if(message == null) {
		callFlash("addEventListener", "contentLoad", "bc_onContentLoad");
		callFlash("addEventListener", "mediaStart", "bc_onMediaStart");
		callFlash("addEventListener", "mediaComplete", "bc_mediaComplete");
	}
}

/**
 * Once the content has been loaded this is fired.  We registered this event handler in onTemplateLoaded.
 * After we have the content we then need to get the lineup for this title so that we can build out our 
 * list of videos.
 * 
 * @param {Object} evt
 */
function bc_onContentLoad(evt) {
	callFlash("getPlayerLineupIds");
}

/**
 * This is a callback from our request above to get the lineUpIds for this player.  Since
 * we only want the first lineupwe make a request for that lineup to build our navigation.
 * 
 * @param {Object} lineup_array - an array of lineup ids.  This should only be one lineup.
 */
function getPlayerLineupIds_Result(lineup_array) {
	callFlash("getLineupById", lineup_array[0]);	
}

/**
 * This is the callback from our above request of 'getLineupById'.  With the lineupDTO we 
 * can get a the list of videos so that we can request each one.
 * 
 * @param {Object} lineupDTO - an object which among other things has a list of videos.
 */
function getLineupById_Result(lineupDTO) {
	bc_gLineUpDTO = lineupDTO;
	var numOfVideos = lineupDTO.videoIds.length;
	//loop through each video and make request to get the DTO.
	for(var i = 0; i < numOfVideos; i++) {
		callFlash("getTitleById", lineupDTO.videoIds[i]);
	}
	
	//Since we know how many videos there are in the lineup we now know the height of the container which we will use for scrolling.
	bc_gVideoContainerHeight = numOfVideos * 30;

	if(numOfVideos > 3) {
		document.getElementById('bc_upArrowDiv').style.display = "block";
		document.getElementById('bc_downArrowDiv').style.display = "block";
	}
}

/**
 * A callback for getTitleById which provides with the titleDTO so that we can finally build
 * out our navigation for the player.
 * 
 * @param {Object} titleDTO - An object that contains all the necessary information for this title.
 */
function getTitleById_Result(titleDTO) {
	bc_gVideoContainer = document.getElementById('bc_videosContainer');
	//I need to set this in javascript so that I can read it correctly crossbrowser when I slide.
	bc_gVideoContainer.style.top = "0px";
	
	var div = document.createElement('div');
	if(bc_gFirstVideo) {
		div.className = "bc_firstVideoContainer";
		bc_gFirstVideo = false;
	} else {
		div.className = "videoContainer";
	}
	
	//Actually set the new html inside of our div here.
	div.innerHTML = "<div id='vidDesc_" + titleDTO.id + "' class='vidTitle' onclick='bc_playTitle(" + titleDTO.id + ", " 
	+ titleDTO.lineupId + ")' onmouseover='bc_titleMouseOver(this)' onmouseout='bc_titleMouseOut(" + titleDTO.id + ")'>" + titleDTO.displayName + "</div>";
	bc_gVideoContainer.appendChild(div);
	
	//Need to add this to my array of videos so that we can make continous playback work
	bc_gLineIdArray[bc_gVideoCount] = titleDTO.id;
	bc_gVideoCount++;
}

/**
 * A function that tells the player to play the specified video.
 * @param {Object} titleId - Id of the title.
 * @param {Object} lineup - id of the lineup (optional with one lineup)
 */
function bc_playTitle(titleId, lineup) {
	callFlash("loadTitleById", titleId, "full");
}

/**
 * Called when a new video starts playing which allows us to update the UI with
 * the now playing title.  However, we still need to find out what the current title
 * is so we make a call to the player to find this out.
 * 
 */
function bc_onMediaStart(pObj) {
	callFlash("getCurrentTitle");	
}

/**
 * The callback for the above request to get the current Title, this gives us our
 * id which allows us to see if it is a new title.  If it is then we want to make
 * the old one the white, then set color of the title orange for this one.  We are 
 * able to get the element because when we created these elements we used the titleID
 * as part of our naming convention.
 * 
 * @param {Object} titleDTO - the titleDTO which provides the id of this title.
 */
function getCurrentTitle_Result(titleDTO) {
	if(titleDTO.id != bc_gCurrentTitleId && bc_gCurrentTitleId != null) {
		document.getElementById("vidDesc_" + bc_gCurrentTitleId).style.color = "#ffffff";
	}
	document.getElementById("vidDesc_" + titleDTO.id).style.color = "#f16f1a";
	bc_gCurrentTitleId = titleDTO.id;
}

/**
 * The callback for the event listener we registered at the top for when video has completed
 * We use this event to enable continous play.  Once this has fired we check the current title id
 * and compare it to our array we created when we created the navigation and then play the next
 * title.
 * 
 * @param {Object} pObj
 */
function bc_mediaComplete(pObj) {
	for(var i = 0; i < bc_gLineIdArray.length; i++) {
		//Need to add "" to turn it into a string so that we can compare correctly.
		var testId = bc_gLineIdArray[i] + "";
		if(testId == bc_gCurrentTitleId) {
			//Need to add "" to turn it into a string so that we can compare correctly.
			var newTitleToPlay = bc_gLineIdArray[++i] + "";
			if(newTitleToPlay) {
				bc_playTitle(newTitleToPlay);
			}
			return;
		}
	}
}

/**************************************************************************************************
 * THE BELOW FUNCTIONS ARE HELPER FUNCTIONS OR FUNCTIONS FOR SLIDING NAVIGATION EFFECTS
 **************************************************************************************************/

/**
 * When a user clicks on the down arrow we need to slide the navigation down to the next 3 elements or
 * if there are not 3 then the bottom.
 */
function bc_startSlideDown() {
	document.getElementById('bc_upArrowImage').src = "http://media.gosmithsonian.com/designimages/bc_upArrow-gosmith.gif";
	bc_gHitTop = false;

	var endPosition = null;
	//Check to see if we do not have room to scroll the whole way.
	if((Math.abs(bc_getNum(bc_gVideoContainer.style.top)) + 180) >= bc_gVideoContainerHeight) {
		endPosition = -(bc_gVideoContainerHeight - 90);
		document.getElementById('bc_downArrowImage').src = "http://media.gosmithsonian.com/designimages/bc_downArrowDisabled-gosmith.gif";
		bc_gHitBottom = true;	
	} else {
		endPosition = bc_getNum(bc_gVideoContainer.style.top) - 90;
	}
	
	//Do the actual slide down.
	bc_prepSlideElement(bc_gVideoContainer, 700, endPosition, 'top');
}

/**
 * This is called when the user mouses off of the arrow.  What we do here is check to see if we are at
 * the bottom.  If we are then we want to show the disabled mouseover.
 */
function bc_stopSlideDown() {
	if(bc_getNum(bc_gVideoContainer.style.top) > (95 - bc_gVideoContainerHeight)) {
		document.getElementById('bc_downArrowImage').src = "http://media.gosmithsonian.com/designimages/bc_downArrow-gosmith.gif";
	} else {
		document.getElementById('bc_downArrowImage').src = "http://media.gosmithsonian.com/designimages/bc_downArrowDisabled-gosmith.gif";
		bc_gHitBottom = true;	
	}
}

/**
 * When the user mouses over the arrow we change the image to let them know they can press it.  If
 * they have already hit the bottom then we don't want to show this to them.
 */
function bc_downArrowMouseOver() {
	if(!bc_gHitBottom) {
		document.getElementById('bc_downArrowImage').src = "http://media.gosmithsonian.com/designimages/bc_downArrowOver-gosmith.gif";
	}
}

/**
 * When a user clicks on the up arrow we need to slide the navigation up to the next 3 elements or
 * if there are not 3 then the top.
 */
function bc_startSlideUp() {
	document.getElementById('bc_downArrowImage').src = "http://media.gosmithsonian.com/designimages/bc_downArrow-gosmith.gif";
	bc_gHitBottom = false;
	
	var endPosition = null;
	if((bc_getNum(bc_gVideoContainer.style.top) + 90) >= 0) {
		endPosition = 0;
		document.getElementById('bc_upArrowImage').src = "http://media.gosmithsonian.com/designimages/bc_upArrowDisabled-gosmith.gif";
		bc_gHitTop = true;
	} else {
		endPosition = bc_getNum(bc_gVideoContainer.style.top) + 90;
	}
	
	bc_prepSlideElement(bc_gVideoContainer, 700, endPosition, 'top');
}

/**
 * This is called when the user mouses off of the arrow.  What we do here is check to see if we are at
 * the top.  If we are then we want to show the disabled mouseover.
 */
function bc_stopSlideUp() {
	if(bc_getNum(bc_gVideoContainer.style.top) < 0) {
		document.getElementById('bc_upArrowImage').src = "http://media.gosmithsonian.com/designimages/bc_upArrow-gosmith.gif";
	} else {
		document.getElementById('bc_upArrowImage').src = "http://media.gosmithsonian.com/designimages/bc_upArrowDisabled-gosmith.gif";
		bc_gHitTop = true;
	}
	
}

/**
 * When the user mouses over the arrow we change the image to let them know they can press it.  If
 * they have already hit the top then we don't want to show this to them.
 */
function bc_upArrowMouseOver() {
	if(!bc_gHitTop) {
		document.getElementById('bc_upArrowImage').src = "http://media.gosmithsonian.com/designimages/bc_upArrowOver-gosmith.gif";
	}
}

/**
 * Change the text to orange when the user mouses over a title.
 * @param {Object} pElem - pass in the element so that we don't have to find it.
 */
function bc_titleMouseOver(pElem) {
	pElem.style.color = "#f16f1a";
}

/**
 * Change the text back to black if this is not the title that is playing.
 * @param {Object} pId - we can not take in the elem since we need to look it up by id to see if it is the current title.
 */
function bc_titleMouseOut(pId) {
	if(pId != bc_gCurrentTitleId && pId != null) {
		document.getElementById("vidDesc_" + pId).style.color = "#000000";
	}
}

/**
 * A helper function to get a number if from a style.  This is to handle the case where we set the height
 * of a div to 100px and need to get rid of the px.
 * @param {Object} num - the string or number to check.
 */
function bc_getNum(num) {
	if(num.indexOf('px') > -1) {
		return parseInt(num.substring(0, num.indexOf('px')));
	} else {
		return parseInt(num);
	}
}

/**
 * A helper function to prep for the actual transistion of sliding the elements.
 * @param {Object} pElementToMove - The element that we are going to move on the screen.
 * @param {Object} pTimeToTake - How long we have to make this transistion.
 * @param {Object} pMoveEnd - Where we want this element to end up.
 * @param {Object} pType - What type of move this is.  So top in this case.
 */
function bc_prepSlideElement(pElementToMove, pTimeToTake, pMoveEnd, pType) {
    var moveStart = bc_getNum(pElementToMove.style[pType]);
    var amountToMove = pMoveEnd - moveStart;
    var timeStart = new Date().getTime ();
    var timeEnd = timeStart + pTimeToTake;
    bc_doSlideElement(pElementToMove, pType, amountToMove, moveStart, pTimeToTake, timeEnd);
  }

/**
 * A helper function do the actual slide down.  This based off of time to make the transistion as
 * clean as possible.
 * 
 * @param {Object} pElementToMove - The element that is goign to be slid
 * @param {Object} pType - What we changing on this element to move.  In this case top.
 * @param {Object} pAmountToMove - How much we have left to move..
 * @param {Object} pMoveStart - A starting position.
 * @param {Object} pTimeToTake - How much time we have to complete this move.
 * @param {Object} pTimeEnd - When we have to complete this move by.
 */
function bc_doSlideElement(pElementToMove, pType, pAmountToMove, pMoveStart, pTimeToTake, pTimeEnd) {
    var currentTime = new Date().getTime();
    var timeRemaining = Math.max(0, pTimeEnd - currentTime);
    var currentMove = parseInt(pAmountToMove - (Math.pow(timeRemaining, 3) / Math.pow(pTimeToTake, 3)) * pAmountToMove);
    pElementToMove.style[pType] = (pMoveStart + currentMove) + "px";
    if (timeRemaining > 0) {
      setTimeout(function () { bc_doSlideElement(pElementToMove, pType, pAmountToMove, pMoveStart, pTimeToTake, pTimeEnd); }, 10);
    }
}

