/**
 * Control actions of the video player.
 *
 * @package agdistis
 */

/**
 * Is the browser a version of Internet Explorer?
 *
 * @var int
 */
var isIE=navigator.appName.indexOf("Microsoft") != -1; // Tells whether we're in IE or not.



// oo0o00oo0o0o00o0o00o0o00o0o00o0oo0o00oo00o0o \\
// oo0[  Player Div Variable Declarations  ]0oo \\
// o0o00o0o0o0o0o0o00o0o00o0o00oo0o0o0o0o00o00o \\

/***** AVS Overridable Settings *****/
var pldv_player_width = 500;
var pldv_player_height = 400;
var pldv_init_x = "center";
var pldv_init_y = "center"; 
var pldv_side_margin = 3;
// Minimum size the player will be allowed to resize to. 0 if no minimum
var pldv_min_w = 450;
var pldv_min_h = 330;
var pldv_vid_id;



var pldv_alt_div_content = "No video has been loaded.  Please click a video to view.";

var pldv_div, pldv_player_div;
var pldv_id = "pldv_container";
var pldv_player_div_id = "pldv_player"; 

var pldv_status = 0;
var pldv_minimized = false;
var pldv_hide_immediate_override = false;
var pldv_animating = false;

// The following are all required for the floating player.  Meta can be used with the player in static mode if desired.
var pldv_meta_div, pldv_dragbar_div, pldv_home_div, pldv_home_shrink_div, pldv_resizer;

var pldv_meta_div_id = "pldv_meta";
var pldv_dragbar_div_id = "pldv_dragbar";
var pldv_home_div_id = "pldv_home";
var pldv_home_shrink_div_id = "pldv_shrink";
var pldv_resizer_id = "pldv_resizer";

// Used to record the location and offset of the player div before minimization so it can be restored later.
var pldv_slidehome_pos_x, pldv_sh_offset_x, pldv_sh_offset_y;

var pldv_use_doc_el;
if (document.compatMode && document.compatMode != "BackCompat")
{
	pldv_use_doc_el = true;
}
else
{
	pldv_use_doc_el = false;	
}





// oo0o00oo0o0o00o0o00o0o0o00o0o00o0oo0o00oo00o0o \\
// oo0[  Flash Player Variable Declarations  ]0oo \\
// oo00o00o0o0o0o0o0o00o0o00o0o00oo0o0o0o0o00o00o \\

/***** AVS Overridable Settings *****/
var flpl_skins_dir = './flpl_skins/';
var flpl_buffer_time = 2;
var flpl_ad_buffer_time = 1;
var flpl_scalemode = "letterbox";
var flpl_default_volume = 75; 
var flpl_alt_use_css = true;
var flpl_alt_ad_w = 300;
var flpl_alt_ad_h = 250;

var flpl_alt_ad_div_id = "flpl_ad"; // Not AVS overridable - no where else to put var though

var flpl_object;
var flpl_vid, flpl_skin_id, flpl_login_status, flpl_username, flpl_stored_volume;
var flpl_play_time, flpl_play_status, flpl_volume, flpl_viewmode; // These are sent from flpl_object to JS.
var flpl_bg_color = "121a1c";
var flpl_skin_array;

var flpl_width = 0;
var flpl_height = 0;
var flpl_stored_volume_cookiename = "syna_flpl_volume_store";
var flpl_stored_volume_days_to_expire = 365;
var flpl_playing_ad = false;

var flpl_video_api_url = "../files/video/video_api.php";
var flpl_playlist_api_url = "playlist_api.php";
var flpl_billing_api_url = "/"; // Functionality currently does not exist
var flpl_billing_success_url = "/"; // Functionality currently does not exist
var flpl_login_function = "vpjs_show_login";

// Override this path var as necessary in JS if player is used on a page
// outside of the video directory.
var flpl_player_swf_path = "flpl_player.swf";

// External Ad variables.  If LightningCast Ads are being used, and LC banners need to be displayed outside of the flash player...
var flpl_alt_ad_div, flpl_alt_ad_url, flpl_alt_ad_clickurl;

// Standalone variables.  Determine if the player is being used in standalone (non status-API) mode.
// These vars only get set locally.  No DB/API/AVS retrieval.
var flpl_standalone_mode_on = false;	// This only gets set to true locally if using standalone mode.
var flpl_standalone_skin_xml, flpl_standalone_vid_url, flpl_standalone_ad, flpl_standalone_autostart, flpl_standalone_duration;

// Playlisting flag.  Gets set to true if playlisting functionality is active.
var flpl_playlisting_on = true;
// If playlisting is being used, this should be set to the next video ID. 
var flpl_playlist_nextvid;

flpl_stored_volume = flpl_read_vol_cookie();
if (flpl_stored_volume == null)
{
	// No volume cookie stored.  So, set it to the default volume.
	flpl_stored_volume = flpl_default_volume;
}



/***** Windows Media Player Variable Declarations *****/
// These maintain the Windows Media Player Object
var wmpl_object, wmpl_object_url;
var wmpl_object_id = 'wmp_vid_player';
var wmpl_needs_install = false;

// Various messages needed for FireFox - due to plugin restrictions and requirements.
// Loaded from AVS
var wmpl_resizeff_message, wmpl_installff_message, wmpl_installffmeta_message;


/***** PLDV FUNCTIONS *****/

/**
 * pldv_initialize should be used upon page load to initialize the pldv_div and prepare for possible use
 * of the FVP/WMP on the current page.
 *
 * @param {String} div_id This should be the ID of the div that will become the pldv_div (player div).
 *						The FVP/WMP will be loaded within this div.
 */
function pldv_initialize(div_id)
{
	// Called during document onload.
	if (!pldv_status)
	{
		if (div_id != null)
		{
			pldv_id = div_id;
		}

		pldv_status = 1;
		pldv_div = document.getElementById(pldv_id);
		
		if (pldv_div == null)
		{
			pldv_status = 0;
		}
		else
		{
			// Initialize object references
			flpl_alt_ad_div = (flpl_alt_ad_div_id) ? document.getElementById(flpl_alt_ad_div_id) : false;
			
			pldv_player_div = document.getElementById(pldv_player_div_id);
			pldv_meta_div = (pldv_meta_div_id) ? document.getElementById(pldv_meta_div_id) : false;
			pldv_dragbar_div = (pldv_dragbar_div_id) ?  document.getElementById(pldv_dragbar_div_id) : false;
			pldv_player_div.innerHTML = "";
			pldv_resizer = (pldv_resizer_id) ?  document.getElementById(pldv_resizer_id) : false;
			pldv_home_div = (pldv_home_div_id) ? document.getElementById(pldv_home_div_id) : false;
			pldv_home_shrink_div = (pldv_home_div_id) ? document.getElementById(pldv_home_shrink_div_id) : false;
			
			
			// Initialize drag bar and resize handle.
			if (pldv_resizer)
			{
				new pldv_resizehandle(pldv_resizer);
			}

			if (pldv_dragbar_div)
			{
				new pldv_dragbar(pldv_dragbar_div);
			}
			
			if (pldv_player_width > 0)
			{
				flpl_width = pldv_player_width;
				pldv_player_div.style.width= pldv_div.style.width  =  pldv_player_width + "px";
			} 
			else
			{
				pldv_player_div.style.width= pldv_div.style.width  = "1px";
			}
			
			if (pldv_player_height > 0)
			{
				flpl_height = pldv_player_height;
				pldv_player_div.style.height = pldv_player_height + "px";
			}
			
			// Set X and Y of player div, determining center of visible browser window.
			if (pldv_init_x == "center")
			{
				// find the center of the window.
				// then, find the center of the flpl_container.
				var docwidth = pldv_getDocumentDims().width;
				
				// half of the docwidth, minus half of the player width, plus any scroll offset, will give us our x.
				pldv_init_x = (docwidth/2) - (pldv_player_width/2) + pldv_getWindowOffsetX();
			}

			if (pldv_init_y == "center")
			{
				// find the center of the window.
				// then, find the center of the flpl_container.
				var docheight = pldv_getDocumentDims().height;
				// half of the docheight, minus half of the player height, plus any scroll offset, will give us our y.
				pldv_init_y = (docheight/2) - (pldv_player_height/2) + pldv_getWindowOffsetY();
				// If in playlisting mode, this will be screwed up by the very large meta area that will be displayed below
				// the player.  So, subtract a bit to make sure the player doesn't go offstage.
				if (flpl_playlisting_on)
				{
					pldv_init_y = pldv_init_y - 80;
					if (pldv_init_y < 0) 
					{
						pldv_init_y = 0;
					}
				}
			}
			
			// Set X and Y location of player div, not centered.
			if (pldv_init_x >= 0)
			{
				pldv_div.style.left = pldv_check_offsetX(pldv_init_x, pldv_player_width) + "px";
			}

			if (pldv_init_y >= 0)
			{
				var new_style_top_string = pldv_check_offsetY(pldv_init_y, pldv_player_height);
				if (new_style_top_string < 0)
				{
					new_style_top_string = "0";
				}
				pldv_div.style.top = new_style_top_string + "px";
			}

			if (!pldv_min_w)
			{
				pldv_min_w = 0;
			}

			if (!pldv_min_h)
			{
				pldv_min_h = 0;
			}
		}
	}
}

/**
 * pldv_playvideo is a function that is used directly to play a video in the FVP or WMP, based on Video ID.
 * This can be used in onclick events.  If the player doesn't yet exist, it will be created and displayed.
 * @param {String} vid_id This can either be the video ID that will be passed to the API to retrieve
 *                 video url, or if in FVP standalone mode, can be a direct media URL (required).
 * @param {String} type This should be "flash", "flashstandalone", or "wmp", depending on which
 *                 type of media and which mode the player should be opened in.
 * @param {int} standalone_duration Duration of videos in a standalone mode.
 * @param {String} source An optional parameter specify what is calling pldv_playvideo.  This is to 
 *                 differentiate between how a video was played (user click, playlist, autoplay, etc.).
 * @return {bool}
 */
function pldv_playvideo(vid_id, type, standalone_duration, source)
{
	source = (source) ? source : '';
	vpjs_logging_api(vid_id, flpl_username, type + 'video', source);
	pldv_vid_id = vid_id;
	switch (type)
 	{
		case "flash":
			flpl_vid = vid_id;
			pldv_show("flpl");
			break;
		case "flashstandalone":
			// Change the standalone URL only.
			if (vid_id != "")
			{
				flpl_standalone_vid_url = vid_id;
			}
			
			if (standalone_duration > 0)
			{
				flpl_standalone_duration = standalone_duration;
			}
			else
			{
				flpl_standalone_duration = null;
			}

			pldv_show("flpl");
			break;
		case "wmp":
			wmpl_vid_play_id(vid_id);
			pldv_show("wmpl");
			break;
		case "wmpstandalone":
			// The following is used if vid_id is actually a full media url to be played by WMP directly.
			pldv_show("wmpl");
			wmpl_vid_play(vid_id);
		default:
	}
	
	if (pldv_meta_div)
	{
		if (!window.flpl_disable_playlist)
		{
			pldv_populate_playlist(pldv_vid_id);
		}
		else
		{
			pldv_populate_meta(pldv_vid_id);
		}
	}	
	
	return false;
}

/**
 * pldv_show is a function that is called by pldv_playvideo, and can be called on its own.  If the player is in
 * a minimized state, this will cause a slide animation and then cause the player to be visible.  If the appropriate
 * player does not yet exist, it calls the corresponding create function to initialize it.
 *
 * @param {String} which_player This optional var should be "wmpl" or "flpl", indicating which player to load.
 *								If not set, the player div will load alternate content instead.
 * @return {bool}
 */
function pldv_show(which_player)
{
	// which_player should be "wmpl" or "flpl".  If not present, player div's innerHTML will be set to pldv_alt_div_content.
	
	// Initialize the player div if it isn't already.
	pldv_initialize();
	
	// Check to see if the player is minimized.
	if (which_player)
	{	
		
		if (pldv_minimized)
		{
			pldv_slide_animate(pldv_home_shrink_div_id, pldv_home_div_id, "restore");
		}
		
		// Now, create the appropriate object and/or embed code for the specified player, and initialize
		// said player.
		switch(which_player)
		{
			case "wmpl":
				if (pldv_status != 3)
				{
					flpl_hide_ext_ad();
					wmpl_create();
				}
				break;

			case "flpl":
				// Eventually, rename flpl_object to flpl_object for consistency.
				if (pldv_status != 2)
				{
					flpl_create();
				}
				break;

			// End switch
		}
	}
	else
	{
		flpl_hide_ext_ad();
		// The desired player wasn't specified.  So, if an active player exists in minimized state, show it.
		// Otherwise, do nothing.
		
		if (pldv_status > 0)
		{
			// If player is minimized, returns it from minimized position.
			// Wrapper for pldv_slideback, located in video_div_movement.js .
			if (pldv_minimized == true)
			{
				pldv_slide_animate(pldv_home_shrink_div_id, pldv_home_div_id, "restore");
			}
			if (pldv_status == 1) 
			{
				// pldv_status == 1.  In this case, show alternate innerHTML content, which can be promotional.
				pldv_player_div.innerHTML = pldv_alt_div_content;
			}
		} 
	}
	

		
	return false;
}

/**
 * pldv_hide is a function that can be called directly to minimize the pldv_div and make it invisible.
 * This will start a slide animation, pldv_slide_animate, located in video_div_movement.js
 *
 * @return {bool}
 */
function pldv_hide()
{
	// If player is currently visible, minimizes it.
	if (flpl_object && (pldv_status == 2))
	{
		flpl_hide_ext_ad();
		flpl_object.minimize();
	}
	if (!pldv_minimized && pldv_div)
	{	
		 pldv_slide_animate(pldv_home_shrink_div_id, pldv_home_div_id, "minimize", false);
	}
	return false;
}

/**
 * pldv_hide_player a function that can be called directly to unload FVP or WMP from the pldv_div.
 * Any currently loaded media will also be unloaded, and the player div will load pldv_alt_div_contents instead.
 *
 * @return {bool}
 */
function pldv_hide_player()
{
	flpl_hide_ext_ad();
	
	if ((pldv_status == 2) && flpl_object)
	{
		if (flpl_object.purgeVideo)
		{
			flpl_object.purgeVideo();
		}
	}

	if ((pldv_status == 3) && wmpl_object)
	{
		wmpl_destroy();
	}

	if (pldv_status > 1)
	{
		pldv_player_div.innerHTML = pldv_alt_div_content;
		pldv_status = 1;
	}
	
	return false;
}

/** 
 * pldv_change_meta is a function used to change the contents Metadata display area of the pldv_div.  
 * If the pldv_meta_div exists, new content is assigned to its innerHTML property, and the player div size 
 * is reset, in case the height of the meta div increased or decreased.  
 *
 * @param {String} content Metadata details for a video
 * @return {bool}
 */ 
function pldv_change_meta(content)
{
	if (pldv_meta_div)
	{
		pldv_meta_div.innerHTML = content;
		pldv_set_div_size();
		flpl_hide_ext_ad();
	}
}



/***** FLPL Functions *****/

/**
 * flpl_create is called by pldv_show if flpl_object does not yet exist.  The function creates the object/embed
 * code appropriate to the current browser, with information from JS variables.  Assigns this code to the player div.
 *
 * @param {String} bgcolor This is the (optional) background color (hex code without #) that will be used for the FVP.
 *                         If not set, black will be used.
 */
function flpl_create(bgcolor)
{
	// This function creates/initializes the flpl_object.  
	wmpl_destroy();

	if (bgcolor == null)
	{	
		if (flpl_bg_color == null)
		{	
			// if no master bg color is set, use black.
			bgcolor = flpl_bg_color = "000000";
		}
		else
		{
			// there was a master color set, use it.
			bgcolor = flpl_bg_color;
		}
	}
	else
	{
		// bgcolor param was passed in, override the existing bg color.
		flpl_bg_color = bgcolor;
	}

	var so = new SWFObject(
		flpl_player_swf_path,
		"flpl_player",
		"96%",
		"100%",
		"8",
		"#"+bgcolor,
		"high",
		window.location,
		"http://get.adobe.com/flashplayer/");

	so.addParam("allowfullscreen","true");
	so.addParam("allowscriptaccess","always");
	so.addParam("swliveconnect","true");
	so.addParam("scale","noscale");
	so.addParam("wmode","opaque");
	so.addParam("salign","lt");

	flpl_sort_skins();

	// Assign flash code to player div and set player status.
	so.write(pldv_player_div);
	pldv_status = 2;
}

/***** flpl_object REQUEST AND REPLY functions.  Allows coordination of variable data between JS and flpl_object. *****/

/**
 * flpl_request_initialize is a function that is called by FVP as soon as videoplayer.swf loads, in order to retrieve initial
 * variables and settings from JS.  At this time, since it is certain that the FVP has loaded completely, the reference to
 * the FVP is made (and stored in flpl_object) for future use.  See documentation for more information.
 *
 * @return {Object} send_to_flash This is an object containing various values needed to set up initial state of FVP.
 */
function flpl_request_initialize()
{
	flpl_object = isIE ? document.getElementById("flpl_player") : document["flpl_player"];
	
	if (flpl_width == 0)
	{
		flpl_width = pldv_player_width;
	}
	if (flpl_height == 0)
	{
		flpl_height = pldv_player_height;
	}
	if (!flpl_standalone_mode_on)
	{
		flpl_standalone_mode_on = false;
	}

	// A debug parameter can be passed as "&debug=xxx", then calls
	// to video_api.php will be "op=xxx" instead of "op=play".
	var debug_array = /debug_video_api=([^&#]*)/.exec(window.location.search);
	var flpl_video_api_debug = debug_array ? debug_array[1] : "";
	
	// Make sure the right SIZE skin is being used, if more than one is available.
	flpl_check_skin(flpl_width, flpl_height);
	
	var send_to_flash = {
		flpl_skins_dir: flpl_skins_dir,
		flpl_video_api_url: flpl_video_api_url,
		flpl_video_api_debug: flpl_video_api_debug,
		flpl_billing_api_url: flpl_billing_api_url,
		flpl_billing_success_url: flpl_billing_success_url,
		flpl_username: flpl_username,
		flpl_ad_buffer_time: flpl_ad_buffer_time,
		flpl_login_function: flpl_login_function,
		flpl_stored_volume: flpl_stored_volume,
		flpl_init_width: flpl_width, 
		flpl_init_height: flpl_height,
		flpl_standalone: flpl_standalone_mode_on
	};

	return send_to_flash;
}

/**
 * flpl_request_standalone is a function that is called by FVP after flpl_request_initialize, if flpl_standalone_mode_on
 * has been set to true.  This indicates that the FVP should operate in "standalone" mode, which can be used when API
 * calls are limited or not needed, for special cases where video URLs will be provided directly in Javascript or HTML,
 * such as the case of certain mini-sites or promotional pages.
 * Information on variables:
 * 		flpl_standalone_skin_xml: this can be empty/null if API will be used to retrieve skin XML, or can
 *								contain the path or URL to an XML file containing special stand alone skin XML.
 *		flpl_standalone_vid_url: (required) This is the url to the media that will be played in FVP upon load.
 *		flpl_standalone_ad: this can be empty/null if no LightningCast ad is needed, or should be an LC Affiliate:site pair
 *							if LC ads are desired.
 *		flpl_standalone_autostart: this is a boolean indicating if the specified media should automatically start
 *							after loading.  Can be empty/null but if so will default to true in FVP.
 *       flpl_standalone_duration: this is an integer or float, representing the duration of the flash video in seconds.
 *                           This is optional - should be used if a long-duration HTTP video is used and metadata isn't
 *                           arriving at the player fast enough.  If the progress bar misbehaves with an HTTP video in
 *                           standalone mode, use this!
 * @return {Object} send_to_flash This is an object containing various values needed to set up standalone mode in FVP.
 */
function flpl_request_standalone()
{
	var send_to_flash = {
		flpl_standalone_skin_xml: flpl_standalone_skin_xml,
		flpl_standalone_vid_url: flpl_standalone_vid_url,
		flpl_standalone_ad: flpl_standalone_ad,
		flpl_standalone_autostart: flpl_standalone_autostart,
		flpl_standalone_duration: flpl_standalone_duration
	};
						
	return send_to_flash;
}

/**
 * flpl_request_buffer_time is a function that is called by FVP before playing back a normal (non-ad) video.
 * The value represents how many seconds of video should be buffered before playback will begin.
 *
 * @return {int} flpl_buffer_time This is the positive integer representing buffer time in seconds.
 */
function flpl_request_buffer_time()
{
	return flpl_buffer_time;
}

/**
 * flpl_request_login_status is a function that is called by FVP if user requests a video that requires login, 
 * and they are not already logged in, FVP will call flpl_login_function (whatever JS function that value represents).
 * Afterwards, this function is polled by flpl_object to see if the login attempt was successful.
 *
 * @return {String} flpl_login_status This should be "success", "failed", or a null or empty value.
 */
function flpl_request_login_status()
{
	return flpl_login_status;
}

/**
 * flpl_request_username is a function that is called by FVP to request the current username.
 * This will happen when the FVP receives Status XML about a video that indicates that login is required.
 * If the user logs in successfully after such, the FVP will execute this function to retrieve the current username.
 *
 * @return {String} flpl_username This should be the current username string that will be used by FVP to retrieve
 *                                 new Status XML after login.
 */
function flpl_request_username()
{
	// Gets called after successful login, to update the flash player.
	return flpl_username;
}

/**
 * flpl_reply_jiffy is a function that is called by FVP on interval (multiple times per second)
 * to make sure that JS has current information about FVP's properties.  FVP also checks JS
 * vars for any changes that have occurred since last update, so this function is the MAJOR
 * method of communication both to and from the FVP and Javascript.
 *
 * @param {Object} responseObject This object contains current playback time and playback status (optional).
 * @return {Object} send_to_flash This object contains JS information pertinent to FVP that may have
 *                                 changed since last flpl_reply_jiffy was called.
 */
function flpl_reply_jiffy(responseObject)
{
	// This is called by the flpl_object about 6 times per second (depends on what FPS is set in videoplayer.swf).
	// The player sends relevant information to JS, such as playback time and player status.
	// When called, JS sends current information back to the player.
	if (responseObject)
	{	// Make sure to set the JS vars only if Flash sent data.  flpl_object may call this function without params at startup.
		flpl_play_time = responseObject.flpl_play_time;
		flpl_play_status = responseObject.flpl_play_status;
		if ((flpl_play_status == "error") && (flpl_playing_ad))
		{
			flpl_hide_ext_ad();
		}
	}

	var send_to_flash = {
		flpl_vid_id: flpl_vid,
		flpl_skin_id: flpl_skin_id,
		flpl_scalemode: flpl_scalemode,
		flpl_viewmode: flpl_viewmode,
		flpl_skin_width: flpl_width,
		flpl_skin_height: flpl_height
	};

	// Reset width and height indicators for now, or flpl_object will attempt resize every 1/12 second.
	flpl_width = 0;
	flpl_height = 0;
	return send_to_flash;
}

/**
 * flpl_reply_user_event is a function that is called by FVP when a user
 * changes a setting via a button or control within the FVP.  These settings include
 * volume, viewmode, and scalemode.
 *
 * @param {Object} responseObject - contains the current values of volume, viewmode and scalemode from FVP (required).
 */
function flpl_reply_user_event(responseObject)
{
	if (responseObject.flpl_volume != null)
	{
		flpl_volume = responseObject.flpl_volume;
		if (flpl_volume > -1)
		{
			// Write the current volume to a cookie for later.
			flpl_create_vol_cookie();
			flpl_stored_volume = flpl_volume;
		}
	}
	if (responseObject.flpl_viewmode != null)
	{
		flpl_viewmode = responseObject.flpl_viewmode;
	}
	if (responseObject.flpl_scalemode != null)
	{
		flpl_scalemode = responseObject.flpl_scalemode;
	}
}

//////////////////////////// flpl_object controls
/**
 * flpl_play is a function that can be used to play (or unpause) current media in the FVP.
 * Can be used directly, in case HTML/Javascript controls are desired.
 *
 */
function flpl_play()
{
	// Begins playing an SWF or FLV if there is one loaded.
	// May not work correctly with all SWFs.
	if (flpl_object)
	{
		flpl_object.pbk_play();
	}
}

/**
 * flpl_pause is a function that can be used to pause current playback in the FVP.
 * Can be used directly, in case HTML/Javascript controls are desired.
 *
 */
function flpl_pause()
{
	// Pauses playback of an FLV or SWF if there is one loaded and it is already playing.
	// May not work correctly with all SWFs.
	if (flpl_object)
	{
		flpl_object.pbk_pause();
	}
}

/**
 * flpl_stop is a function that can be used to stop current playback in the FVP.
 * Can be used directly, in case HTML/Javascript controls are desired.
 *
 */
function flpl_stop()
{
	// Stops playback of an SWF or FLV if loaded.  Also rewinds to beginning.
	// May not work correctly with all SWFs.
	if (flpl_object)
	{
		flpl_object.pbk_stop();
	}
}

/**
 * flpl_setvol is a function that can be used to set the FVP volume.
 * Can be used directly, in case HTML/Javascript controls are desired.
 *
 * @param {int} volume This is an integer from 0 to 100 (required).
 */
function flpl_setvol(volume)
{
	if (flpl_object)
	{
		flpl_object.set_vol(Number(volume));
	}
}

/**
 * flpl_mute is a function that can be used to cause the FVP to mute its volume and to
 * store the previous volume.  Can be used directly, in case HTML/Javascript controls are desired.
 *
 */
function flpl_mute()
{
	// Mutes player (sets volume to 0 and retains old volume setting for later) if not already muted.
	if (flpl_object)
	{
		flpl_object.mute();
	}
}

/**
 * flpl_unmute is a function that can be used to cause the FVP to return from a muted state to
 * the previous volume.  Can be used directly, in case HTML/Javascript controls are desired.
 *
 */
function flpl_unmute()
{
	// Unmutes player (restores volume from mute to previous nonzero volume) if muted.
	if (flpl_object)
	{
		flpl_object.unmute();
	}
}

/**
 * flpl_setviewmode is a function used to set the viewmode of the FVP.
 * Viewmode options include "minimize", "double", "default".  Other viewmode
 * values used within FVP inclulde "normal" and "fullscreen", but these cannot be
 * used via JS.  The FVP will update with this value when it executes its next
 * flpl_reply_jiffy cycle.
 * Detail of mode types:  
 *    "minimize" will call pldv_hide and cause a minimization animation.
 *    "double" will cause the player (and div) to resize to twice the width
 *        and height of the "default" size of the current skin, but no larger
 *        than the currently visible document area.
 *    "default" will cause the player (and div) to resize to the initial width
 *        and height that it originally loaded as (if the user has resized it since load).
 * Usage: This function can be called directly, in case html/javascript controls
 * are needed for the player to adjust this setting.  Otherwise, this is not
 * used internally.
 *
 * @param {String} mode A string representing one of the three modes.
 */
function flpl_setviewmode(mode)
{
	// Sets the viewmode of the player.  Options are "minimize", "double", "default".  
	// Cannot force player to "fullscreen" from JS.
	if (flpl_object && (flpl_viewmode !="minimize")) 
	{
		flpl_object.set_viewmode(mode);
	}
}

/**
 * flpl_set_ext_ad is a function that is called when an external LightningCast banner ad is
 * to be displayed.  This function is called via the FVP only if the flpl_alt_ad_div has been set.
 * If flpl_alt_ad_div has not been set, the external banner will not be used.  This function sets
 * the url and click url variables with values passed from FVP, which obtains them via the LightningCast
 * Ad API.
 *
 * @param {String} ban_url The source URL of the banner ad, which should be a SWF, JPG, GIF or PNG (required).
 * @param {String} img_click_url A url that the banner should navigate to if the user clicks it (required).
 */
function flpl_set_ext_ad(ban_url, img_click_url)
{
	if (flpl_alt_ad_div)
	{
		flpl_alt_ad_url = ban_url;
		flpl_alt_ad_clickurl = img_click_url;
	}
}

/**
 * flpl_show_ext_ad is a function that is called when an external LightningCast banner ad is
 * to be displayed.  This function is called via the FVP, after flpl_set_ext_ad has been called.
 *
 */
function flpl_show_ext_ad()
{
	flpl_playing_ad = true;
	if (flpl_alt_ad_div && (flpl_alt_ad_url != ""))
	{
		var swf_found = flpl_alt_ad_url.indexOf(".swf");
		var doubleclick_found = flpl_alt_ad_url.indexOf("http://ad.doubleclick.net");
		var html_found = flpl_alt_ad_url.indexOf("&ext=.html");

		var banner_code = ""
		
		if (flpl_alt_use_css)
		{
			flpl_alt_ad_div.className = "pldv_ad_visible";
		}
		
		// Clean up any old ad swf that might be hanging around.
		var old_flash_ad = document.getElementById("flpl_banner");
		if (old_flash_ad)
		{
			old_flash_ad = null;		
		}

		if(doubleclick_found == 0 || html_found >= 0)
		{
			banner_code = '<iframe src="' + flpl_alt_ad_url + '" width="' + flpl_alt_ad_w + '" height="' + flpl_alt_ad_h + '" frameborder="0" scrolling="no"></iframe>';
		}		
		else if (swf_found >= 0)
		{
			// Handle SWF Banner.  How to handle onclick?
			// need to split url to extract any loadvars.
			
			if (isIE)
			{
				banner_code += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,28,0"';
				banner_code += 'width="'+ flpl_alt_ad_w +'" height="'+ flpl_alt_ad_h +'" id="flpl_banner">';
				banner_code += '<param name="movie" value="'+ flpl_alt_ad_url +'" />';
				banner_code += '<param name="quality" value="high" />';
				banner_code += '<param name="scale" value="noscale" />';
				banner_code += '<param name="salign" value="lt" />';
				banner_code += '<param name="swliveconnect" value="true" />';
				banner_code += '<param name="allowscriptaccess" value="always" />';
				banner_code += 	'</object>';
			}
			else
			{
				banner_code += '<embed src="'+ flpl_alt_ad_url +'" quality="high" scale="noscale" ';
				banner_code += 'allowscriptaccess="always" salign="lt" width="'+ flpl_alt_ad_w +'" height="'+ flpl_alt_ad_h +'" ';
				banner_code += 'name="flpl_banner" swliveconnect="true" type="application/x-shockwave-flash" '
				banner_code += 'pluginspage="http://www.macromedia.com/go/getflashplayer" />';
			}
		}
		else
		{
			// Handle Image Banner
			banner_code = '<img src="' + flpl_alt_ad_url + '" onclick="flpl_go_ext_ad_url(); return false;" style="cursor: pointer;" alt="" />';
		}
		flpl_alt_ad_div.innerHTML = banner_code;
	}
}

/**
 * flpl_vid_complete is triggered when the current video loaded into the Flash player has ended.
 * This is needed to trigger the next video to play if the playlisting functionality is active.
 * The function is called from within the flpl_object. No parameters or return values.
 *
 */
function flpl_vid_complete()
{
	if (flpl_playlisting_on)
	{
		// Playlisting is active, so set the video id to the next up in the playlist.
		if (flpl_playlist_nextvid && (flpl_playlist_nextvid != flpl_vid))
		{
			pldv_playvideo(flpl_playlist_nextvid, "flash", 0, "playlist_autoplay");
			// We can't just change the video id alone and let the flpl_object 
			// pick up the new video id alone, because we will need to repopulate 
			// the video's metadata area with new playlisted material, and metatdata
			// population only occurs if pldv_playvideo is called.
		}
	}
}

/**
 * flpl_go_ext_ad_url is executed on an onclick event, when an external LightningCast banner ad
 * has been clicked, if the LC banner is a jpg, gif or png.  Assigned in flpl_show_ext_ad.  It
 * opens the banner ad's clickurl in a new window.
 *
 */
function flpl_go_ext_ad_url()
{
	if (flpl_alt_ad_clickurl != "")
	{
		var ad_win = window.open(flpl_alt_ad_clickurl, "ad_win");
	}
}

/**
 * flpl_hide_ext_ad is a function that hides the external LightningCast clickable banner div,
 * if present.  Called by the FVP after ad playback is done, as well as pldv_hide, pldv_hide_player
 * and pldv_show, to make sure the ad div isn't visible at an inappropriate time.
 *
 */
function flpl_hide_ext_ad()
{
	flpl_playing_ad = false;
	if (flpl_alt_ad_div)
	{
		flpl_alt_ad_div.innerHTML = "";
		if (flpl_alt_use_css) 
		{
			flpl_alt_ad_div.className = "pldv_ad_invisible";
		}
	}
}

/// FLPL Cookie Functions ///
/**
 * flpl_create_vol_cookie writes the current flpl_volume to a cookie.
 * Called by flpl_reply_user_event.
 *
 */
function flpl_create_vol_cookie()
{
    var name = flpl_stored_volume_cookiename;
    var value = flpl_volume;

    // Set up the expiration date.
    var days = flpl_stored_volume_days_to_expire;
    var date = new Date();
    date.setTime(date.getTime() + (days*24*60*60*1000));
    var expires = "; expires=" + date.toGMTString();

    // Write the cookie.
    document.cookie = name + "=" + value + expires + "; path=/";
}



/**
 * flpl_read_vol_cookie looks for a stored previous flpl_volume from a cookie.
 * Called when this JS file loads.
 *
 * @return {int} (percentage stored volume) or null
 */
function flpl_read_vol_cookie()
{
    var name = flpl_stored_volume_cookiename;
    var name_equal = name + "=";
    var cookie_array = document.cookie.split(';');

    // Go through the document's cookies and look for the volume cookie.
    for (var i=0; i < cookie_array.length; i++)
    {
        var cookie = cookie_array[i];
        while (cookie.charAt(0)==' ')
        {
            cookie = cookie.substring(1,cookie.length);
        }
        if (cookie.indexOf(name_equal) == 0)
        {
           // Found the volume cookie, return the value.
            var volume = parseInt(cookie.substring(name_equal.length,cookie.length));
            return volume;
        }
    }
    // Didn't find the cookie, return null instead.
    return null;
}



/**
 * Make a call to generate the meta div.
 *
 * @param {int} vid_id
 */
function pldv_populate_meta(vid_id)
{
    new SynAjax().request(
        flpl_video_api_url,
        {
            method: 'get',
            onComplete: pldv_populate_meta_complete,
            parameters: 'op=meta&vid=' + vid_id
        }
    );
}

/**
 * Make a call to generate the meta div.
 *
 * @param {int} vid_id
 */
function pldv_populate_playlist(vid_id)
{
	$("#pldv_meta").load(flpl_playlist_api_url + '?vid=' + vid_id);
}



/**
 * Obtain the meta information to be displayed in the meta div.
 *
 * @param {Resource} request
 */
function pldv_populate_meta_complete(request)
{
    var xml = request.responseXML;
    var title = unescape(xml.getElementsByTagName('title')[0].firstChild.nodeValue);
    var description = unescape(xml.getElementsByTagName('description')[0].firstChild.nodeValue);
	pldv_change_meta('<p class="title">' + title + '</p><p class="desc">' + description + '</p>');
}



/** 
 * flpl_sort_skins sorts flpl_skin_array if it contains any objects.  
 * Called when flpl_object is created so that skins are ordered from smallest to 
 * largest in flpl_skin_array - so that skin switching works properly.  
 * Prepares flpl_skin_array for evaluation by flpl_check_skin in video_div_movement.js.  
 *
 */ 
function flpl_sort_skins() 
{ 
	if (flpl_skin_array && (flpl_skin_array.length > 0))
	{ 
		for (var i = 0; i < flpl_skin_array.length; i++) 
		{ 
			// Parse for nulls, and change to int values.  
			if (flpl_skin_array[i].minw == null) 
			{ 
				flpl_skin_array[i].minw = 0; 
			} 

			if (flpl_skin_array[i].minh == null) 
			{ 
				flpl_skin_array[i].minh = 0; 
			} 

			if (flpl_skin_array[i].maxw == null) 
			{ 
				flpl_skin_array[i].maxw = 50000; 
			} 

			if (flpl_skin_array[i].maxh == null) 
			{ 
				flpl_skin_array[i].maxh = 50000; 
			} 
		} 

		// Now, sort widthwise.  
		flpl_skin_array.sort(flpl_by_minwidth); 
	
		// Now, sort heightwise.  
		flpl_skin_array.sort(flpl_by_minheight); 
	} 
} 


 
/** 
 * flpl_by_minwidth is used by flpl_sort_skins, as a sorting function.  
 * Allows sorting of array items using minw and maxw property.  
 *
 * @param {Object} a - first item to be sorted
 * @param {Object} b - second item to be sorted
 * @return {int} (-1, 0 or 1) which denotes order 
 */ 
function flpl_by_minwidth(a, b) 
{ 
	// Helper for flpl_sort_skins 
	var a_min_width = a.minw; 
	var b_min_width = b.minw; 

	if (a_min_width < b_min_width) 
	{ 
		return -1; 
	} 

	if (a_min_width > b_min_width) 
	{ 
		return 1; 
	} 

	// Minimum values are the same!  So now check maxw property.  
	var a_max_width = a.maxw; 
	var b_max_width = b.maxw; 

	if (a_max_width < b_max_width) 
	{ 
		return -1; 
	} 

	if (a_max_width > b_max_width) 
	{ 
		return 1; 
	} 

	// All width properties match.  
	return 0; 
} 
 
/** 
 * flpl_by_minheight is used by flpl_sort_skins, as a sorting function.  
 * Allows sorting of array items using minh and maxh property.  
 *
 * @param {Object} a - first item to be sorted
 * @param {Object} b - second item to be sorted
 * @return {int} (-1, 0 or 1) which denotes order 
 */ 
function flpl_by_minheight(a, b) 
{ 
	// Helper for flpl_sort_skins 
	var a_min_height = a.minh; 
	var b_min_height = b.minh; 

	if (a_min_height < b_min_height) 
	{ 
		return -1; 
	} 

	if (a_min_height > b_min_height) 
	{ 
		return 1; 
	} 
            
	// Minimum values are the same!  So now check maxw property.  
	var a_max_height = a.maxh; 
	var b_max_height = b.maxh; 

	if (a_max_height < b_max_height) 
	{ 
		return -1; 
	} 

   	if (a_max_height > b_max_height) 
	{ 
		return 1; 
	} 
            
	// All height properties match.  
	return 0; 
}



/***** WMPL Functions *****/

/**
 * wmpl_vid_play is a function that assigns the media URL of the WMP and
 * then displays the WMP object.  It can be called directly with a URL or
 * is called by wmpl_vid_play_id_complete if a video ID is passed to the API and
 * the API returns a URL.
 *
 * @param {String} video_filename The url of the WMP media to load into the WMP object (required).
 */
function wmpl_vid_play(video_filename)
{
	// Plays a video file in the WMP object.
	wmpl_object_url = video_filename;
	wmpl_show_player();
}

/**
 * wmpl_vid_play_id is a function that, given a video ID, makes a request to the video API.
 * After this request, wmpl_vid_play_id_complete is called to process the results.
 *
 * @param {String} wmpvid The video ID of the desired WMP video to load from the API (required).
 */
function wmpl_vid_play_id(wmpvid)
{
        new SynAjax().request(
			flpl_video_api_url,
			{
				method: 'get',
				onComplete: wmpl_vid_play_id_complete,
				parameters: 'op=wmp&vid=' + escape(wmpvid)
			}
        );
}

/**
 * wmpl_vid_play_id_complete is a function that is called after wmpl_vid_play_id,
 * when WMP video information has been returned from the video API.
 *
 * @param {Object} req The response from the request to the video API (required).
 */
function wmpl_vid_play_id_complete(req)
{
	// Retrieves WMP video URL from API
	var contents = req.responseText;
	contents = contents.replace(/[\n\r\t ]/g, '');
	if (contents.match(/error/i))
	{
		return;
	}

	contents = contents.replace(/^.*?<filename>(.*?)<\/filename>.*$/i, '$1');
	wmpl_vid_play(unescape(contents));
}

/**
 * wmpl_show_player is a function that rewrites WMP object/embed code if necessary and
 * displays the WMP object.
 * Used by wmpl_vid_play.
 *
 */
function wmpl_show_player()
{
	if (pldv_status && !wmpl_needs_install)
	{
		var width = parseInt(pldv_player_div.style.width);
		var height = parseInt(pldv_player_div.style.height);
		pldv_player_div.innerHTML = new WMPTag(wmpl_object_id, wmpl_object_url, width, height, 5);
		wmpl_object = isIE ? document.getElementById(wmpl_object_id) : document[wmpl_object_id];
		pldv_status = 3;
	}
}


/**
 * wmpl_create is a function that initializes and prepares to write code to display the Windows Media
 * Player plugin, and handles the case that the plugin is not installed.
 * Used by pldv_show.
 *
 */
function wmpl_create()
{
	// This can merge with pldv_show
	if (pldv_status)
	{
		flpl_object = null;

		var width = parseInt(pldv_player_div.style.width);
		var height = parseInt(pldv_player_div.style.height);
		if (!(height > 0))
		{
			height = pldv_player_height;
			pldv_player_div.style.height = pldv_player_height + "px";
		} 

		if (!isIE)
		{
			// Determine if the FireFox WMP plugin is present.
			var is_WMP = false;
			for ( var i in  navigator.plugins )
			{
				// Check both the plugin name and plugin description, sometimes they are interchanged.
				var d = navigator.plugins[i].description;
				var n = navigator.plugins[i].name;
				if ((d != null) && (d.indexOf("Windows Media Player Firefox Plugin") >= 0))
				{
					is_WMP = true;
					break;
				}
				if ((n != null) && (n.indexOf("Windows Media Player Firefox Plugin") >= 0))
				{
					is_WMP = true;
					break;
				}
			}
			if (!is_WMP)
			{
				// The plugin isn't present in FireFox, set the installation flag.
				wmpl_needs_install = true;
			}
		}

		if (!wmpl_needs_install)
		{
			// Ok, write the WMP code.  Occurs in IE always, but in FireFox only if the WMP plugin is present.
			pldv_player_div.innerHTML = new WMPTag(wmpl_object_id, wmpl_object_url, width, height);
			wmpl_object = isIE ? document.getElementById(wmpl_object_id) : document[wmpl_object_id];
		}

		pldv_status = 3;
	
		if (!isIE && !wmpl_needs_install)
		{
			// This is a secondary catch for incorrect or absent WMP plugin.
			// If the object is written but control functionality isn't there, the wrong version
			// of WMP is being used, so disable the player and show a notice.
			if (!wmpl_object.controls)
			{
				wmpl_destroy();
				wmpl_needs_install = true;
			}
		}

		if (wmpl_needs_install)
		{
			// Display download instructions for FireFox WMP plugin.
			pldv_player_div.innerHTML = wmpl_installff_message;
			pldv_change_meta(wmpl_installffmeta_message);
		}
	}
}



/**
 * WMPTag is a class used to create the correct object/embed code to display a Windows Media Player object.
 *
 * @param {String} object_id This is the desired id of the new Windows Media Player object (required).
 * @param {String} object_url This the URL of the media that should be opened by WMP upon load (required).
 * @param {int} object_width The width in pixels of the player (required).
 * @param {int} object_height The height in pixels of the player (required).
 */
function WMPTag(object_id, object_url, object_width, object_height)
{
	this.id = object_id;
	this.src = object_url;
	this.width = object_width;

	if ((pldv_side_margin) && (pldv_side_margin > 0))
	{
		// If a player div side margin has been specified, allow for it now.
		this.width = object_width - ((object_width/100) * (2*pldv_side_margin));
	} 
	this.height = object_height;
}

/**
 * WMPTag.prototype.write is a function of the WMPTag class (see class description for more details).
 * It writes the tag code to the document object.
 *
 * @param {Object} doc This is a reference to the document (or other) object that the code should be written to (required).
 */
WMPTag.prototype.write=function(doc)
{
	doc.write(this.toString());
}

/**
 * WMPTag.prototype.toString is a function of the WMPTag class (see class description for more details).
 * It creates the object and/or embed code string for the Windows Media Player object.
 *
 * @return {String} WMPTag The string containing the code for WMP display.
 */
WMPTag.prototype.toString=function()
{
	// Creates the html code for a Windows Media Player plugin object.
	var WMPTag=new String();
        
	if (isIE)
	{
		WMPTag += '<object classid="CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6" '; 
	}
	else
	{
		WMPTag += '<object data="' + this.src + '" type="application/x-ms-wmp" ';
   	}
				
	WMPTag += 'standby="Loading..." id="'+this.id+'" ';
	WMPTag += 'width="'+this.width+'" ';
	WMPTag += 'height="'+this.height+'" >';
	WMPTag += '<param name="URL" value="'+this.src+'" />';
	WMPTag += '<param name="autoStart" value="true" />';
	WMPTag += '<param name="uiMode" value="full" />';
	WMPTag += '<param name="cache" value="true" />';
	WMPTag += '<param name="stretchToFit" value="true" />';
	WMPTag += '<param name="SendPlayStateChangeEvents" value="true" />';
	WMPTag += '</object>';
	
	return WMPTag;
}

/**
 * wmpl_resize is a function which resizes the Windows Media Player object, if
 * it exists.  Used by various functions/classes in video_div_movement.js, such
 * as when a user stretches the player div to resize it.  Also updates flpl_width
 * and flpl_height, so that if the FVP is opened after the WMP, FVP will have the
 * current correct size at which to load.
 * * Note: Because of the limitations of the FireFox Windows Media Plugin, the WMP object
 * must be reloaded (or rewritten to the page) each time the player is resized.  Otherwise,
 * the player will not change in size, even though the div will. As a result, whatever media
 * that was loaded before the resize occurred will need to be reloaded after the resize is complete,
 * resulting in a restart of playback.
 *
 * @param {int} new_width The new width in pixels that the WMP object should be changed to. (required)
 * @param {int} new_height The new height in pixels that the WMP object should be changed to. (required)
 */
function wmpl_resize(new_width, new_height)
{
	if (isIE)
	{
		// IE's ActiveX WMP plugin has full functionality, so we can resize the WMP via width/height attributes realtime.
		wmpl_object.height = new_height;
		if (pldv_side_margin > 0)
		{
			wmpl_object.width = new_width - ((new_width/100) * (2*pldv_side_margin));
			
		}
		else
		{
			wmpl_object.width = new_width;
		}
	}
	else
	{
		// FF's WMP plugin is not so nice, and width/height cannot be altered once created, so we need to
		// completely rewrite the object tag at the end of each resize cycle (when user releases mouse).
		// Less than desirable, but the alternative is to make FF WMP unresizable.
		if (!wmpl_needs_install)
		{
			pldv_player_div.innerHTML = new WMPTag(wmpl_object_id, wmpl_object_url, new_width, new_height);
			wmpl_object = isIE ? document.getElementById(wmpl_object_id) : document[wmpl_object_id];
		}
	}
	
	// Now, make sure the Flash player knows that the pldv_div has been resized already.
	// This is in the case that the WMP player is opened first, and then a flash video loaded later, to prevent
	// the flash player from starting at the wrong size.
	flpl_width = new_width;
	flpl_height = new_height;
}

/**
 * wmpl_stop is function that conveys a stop command to the Windows Media Player
 * object, if it exists.
 *
 */
function wmpl_stop()
{
	if (wmpl_object && wmpl_object.controls)
	{
		wmpl_object.controls.stop();
	}
}

/**
 * wmpl_pause is function that conveys a pause command to the Windows Media Player
 * object, if it exists.
 *
 */
function wmpl_pause()
{
	if (wmpl_object && wmpl_object.controls)
	{
		wmpl_object.controls.pause();
	}
}

/**
 * wmpl_destroy is function that clears/nullfies/obliterates the wmpl_object to avoid
 * video artifacts and bad memory issues.  Called when switching between WMP and FVP.
 *
 */
function wmpl_destroy()
{
	if (wmpl_object)
	{
		// Workaround for problem in IE6 - WMP must be destroyed so it doesn't show artifacts even after innerHTML is replaced with
		// flash player object code.
		if (wmpl_object.controls)
		{
			wmpl_object.close();
		}

		wmpl_object = null;
		delete wmpl_object;
	}
}
