/**
 * The functions in this file handle the resizing, animation, and dragging functionality
 * of the stretchable floating video player div.
 *
 * @package agdistis
 */


/**
 * pldv_slide_animate is a set of functions used to animate the minimization or return from minimization of
 * the floating player div.  When used to minimize, the floating player div is moved to an invisible position
 * and an animation div is assigned to the previous width, height and location as the player div.
 * The animation div is then moved and resized until it matches the size of the finish_el.
 * When used to "restore", the animation element starts off at the same size and location as the
 * "home" div, and is resized and moved until it matches the previous location of the floating player div.
 * The floating player div is then made visible.  At the end of both cycles, the animation div becomes invisible.
 *
 * @param string ani_el The id of the div that is to be used to animate.
 * @param string finish_el The id of the target div, that the ani_el will move to.
 * @param string end_state Should either be "minimize" or "restore".
 * @param {boolean} unload Optional param, when used with end_state == "minimize", will
 *							unload any video present in the flash player.
 */
function pldv_slide_animate(ani_el, finish_el, end_state, unload)
{
	if (unload == null)
	{
		unload = false;
	}
	
	var slide_obj =document.getElementById(ani_el);
	var finish_obj = document.getElementById(finish_el);
	var startX, startY, endX, endY;
	var startWidth, startHeight, endWidth, endHeight;
	var w_d, h_d, x_d, y_d;
	var self, interval;	
	var speed = 30;
	var interval_time = 20;
	
	if (end_state && (slide_obj) && (finish_obj))
	{
		switch (end_state)
		{
			case "minimize":
				if ((parseInt(pldv_div.style.left) > -50)&&(slide_obj.style.display != "block"))
				{
					startX = parseInt(pldv_div.style.left);
					startY = parseInt(pldv_div.style.top);
					endX = parseInt(pldv_getOffsetX(finish_el));
					endY = parseInt(pldv_getOffsetY(finish_el));
					startWidth = parseInt(pldv_getOffsetWidth(pldv_id));
					startHeight = parseInt(pldv_getOffsetHeight(pldv_id));
					endWidth = parseInt(pldv_getOffsetWidth(finish_el));
					endHeight = parseInt(pldv_getOffsetHeight(finish_el));	
					start_slide();
				}
				break;
			case "restore":
				if ((parseInt(pldv_div.style.left) < -50)&&(slide_obj.style.display != "block"))
				{
					startX = parseInt(pldv_getOffsetX(finish_el));
					startY = parseInt(pldv_getOffsetY(finish_el));
					endX = parseInt(pldv_slidehome_pos_x);
					endY = parseInt(pldv_getOffsetY(pldv_id));
					startWidth = parseInt(pldv_getOffsetWidth(finish_el));
					startHeight = parseInt(pldv_getOffsetHeight(finish_el));
					endWidth = parseInt(pldv_getOffsetWidth(pldv_id));
					endHeight = parseInt(pldv_getOffsetHeight(pldv_id));
					
					endX = pldv_check_offsetX(endX, endWidth, pldv_sh_offset_x);
					if ((endX != parseInt(pldv_slidehome_pos_x)) && (endX != -3000))
					{
						pldv_slidehome_pos_x = endX + "px";
					}
					
					endY = pldv_check_offsetY(endY, endHeight, pldv_sh_offset_y);
					pldv_div.style.top = endY + "px";

					start_slide();
				}
			default:
				break;
		}
	}
	
	/**
	 * Begins the animation by making the animation div visible setting its start location.
	 */
	function start_slide() 
	{
		pldv_animating = true;
		self = this;
		slide_obj.style.width = startWidth + "px";
		slide_obj.style.height = startHeight + "px";
		slide_obj.style.left = startX + "px";
		slide_obj.style.top = startY + "px"
		slide_obj.style.display = "block";
		
		if (end_state == "minimize")
		{
			// Store the current x location of the player div, and move it so it is not visible.
			// Cannot use style.display = none or opacity = 0, since that would unload the player object.
			// So, to get around this, move it to an absolute negative position.
			if (parseInt(pldv_div.style.left) != -3000)
			{
				pldv_slidehome_pos_x = pldv_div.style.left;
			}
						
			// set pldv_sh_offset.  These values will be used to reset the pldv_div position on restore, if user scrolls the browser window.
			pldv_sh_offset_x = parseInt(pldv_div.style.left) + offsetx;
			pldv_sh_offset_y = parseInt(pldv_div.style.top) + offsety;
			
			pldv_div.style.left = "-3000px";
			
			if (pldv_status == 2)
			{	
				// If flash player loaded...
				if (unload)
				{
					// unload the current video or swf from the player.
					flpl_object.unload();
					flpl_vid = "";
				}
				else
				{
					// If flash plugin is installed, cease playback, since the player will be hidden.
					if (flpl_object)
					{
						flpl_object.pbk_pause();
					}
				}
			}
			if (pldv_status == 3)
			{	
				// If WMP is loaded... pause playback.
				wmpl_pause();
			}
		
		}
		w_d = (startWidth < endWidth) ? 1 : -1;
		h_d = (startHeight < endHeight) ? 1 : -1;
		x_d = (startX < endX) ? 1 : -1;
		y_d = (startY < endY) ? 1 : -1;
		
		// Create the animation interval.
		interval = setInterval(slide_check, interval_time);
	};



	/** 
	 * Executed on an interval, this function periodically changes the size and location of the
	 * animation div to simulate shrinking or stretching for minimization or restore.
	 */
	function slide_check()
	{
		var width_ended = true;
		var height_ended = true;
		var x_ended = true;
		var y_ended = true;

		if (end_state == "restore")
		{
			// put a check in to see if the login window is working.
			if (pldv_hide_immediate_override)
			{
				slide_obj.style.width = endWidth + "px";
				slide_obj.style.height = endHeight + "px";
				slide_obj.style.left = endX + "px";
				slide_obj.style.top = endY + "px";
				width_ended = true;
				height_ended = true;
				x_ended = true;
				y_ended = true;
			}
			
		}

		if (parseInt(slide_obj.style.width) != endWidth)
		{
			width_ended = false;
			slide_obj.style.width = (parseInt(slide_obj.style.width) + (w_d*speed)) + "px";
			if (Math.abs(parseInt(slide_obj.style.width) - endWidth) < (1.5 * speed))
			{
				slide_obj.style.width = endWidth + "px";
				width_ended = true;
			}
		}
		if (parseInt(slide_obj.style.height) != endHeight)
		{
			height_ended = false;
			slide_obj.style.height = (parseInt(slide_obj.style.height) + (h_d*speed)) + "px";
			if (Math.abs(parseInt(slide_obj.style.height) - endHeight) < (1.5 * speed))
			{
				slide_obj.style.height = endHeight + "px";
				height_ended = true;
			}
		}
		if (parseInt(slide_obj.style.left) != endX)
		{
			x_ended = false;
			slide_obj.style.left = (parseInt(slide_obj.style.left) + (x_d*speed)) + "px";
			if (Math.abs(parseInt(slide_obj.style.left) - endX) < (1.5 * speed))
			{
				slide_obj.style.left = endX + "px";
				x_ended = true;
			}
		}
		if (parseInt(slide_obj.style.top) != endY)
		{
			y_ended = false;
			slide_obj.style.top = (parseInt(slide_obj.style.top) + (y_d*speed)) + "px";
			if (Math.abs(parseInt(slide_obj.style.top) - endY) < (1.5 * speed))
			{
				slide_obj.style.top = endY + "px";
				y_ended = true;
			}
		}
	
		if (width_ended && height_ended && x_ended && y_ended)
		{	
			pldv_animating = false;
			// Destination size/location reached.  Stop the interval, and perform any final actions.	
			if (end_state == "minimize")
			{
				slide_obj.style.display = "none";
				pldv_minimized = true;
			}
			else
			{
				slide_obj.style.display = "none";
				if (!pldv_hide_immediate_override)
				{
					pldv_div.style.left = pldv_slidehome_pos_x;
				
					// If the flpl_object exists, tell it to activate its return-from-minimization code.
					if (flpl_object)
					{
						flpl_object.unmini();
					}
			
					// Reset minimization and viewmode flags.
					pldv_minimized = false;
					if (flpl_viewmode == "minimize")
					{
						flpl_viewmode = "normal";
					}
				}
				else
				{
					pldv_hide_immediate_override = false;
				}	
			}
			clearInterval(interval);
		}
	};
}

//////////////////////// Dragging and resize handle functions.

/**
 * pldv_resizehandle is a class used to allow a div within pldv_div to act as
 * a resize handle to resize pldv_div and pldv_player_div if the user desires.
 * Object el must be assigned to an existing div before becoming a resize handle.
 * Usage:  if (pldv_resizer) new pldv_resizehandle(pldv_resizer);
 * Found in video_players.js, within pldv_initialize.
 *
 * @constructor
 * @param object el This is a reference to the div that should be used as the resize handle (required).
 */
function pldv_resizehandle(el)
{
	// These vars keep track of any old document mouseup or mousemove assignments.
	var old_mouseup, old_mousemove;
	
	// Assign mousedown for the div
	el.onmousedown = resize_mousedown;
	
	/**
	 * resize_enddrag is a method of pldv_resizehandle, and is executed when user
	 * releases the mouse button after clicking on the resize div.
	 */
	function resize_enddrag()
 	{
		// Occurs when user stops dragging.
		// Causes the flpl_object or wmpl_object to rescale itself to fit the newest size of the pldv_player_div.
		
		// Reset any old existing mouse behaviors that may have existed before the resize event.
		document.onmouseup = old_mouseup;
		document.onmousemove = old_mousemove;
		
		var new_width = parseInt(pldv_player_div.style.width);
		var new_height = parseInt(pldv_player_div.style.height);
		
		
		// Resize for Flash Video Player
		if (pldv_status == 2)
		{	  
			flpl_resize(new_width, new_height, "normal");
		}
		
		// Resize for WMP
		if (pldv_status == 3)
		{
			wmpl_resize(new_width, new_height);
		}	
	}


	
	/**
	 * resize_drag is a method of pldv_resizehandle, and is executed when user
	 * releases the mouse button after clicking on the resize div.
	 *
	 * @param {event} e The event activated upon mousemove after user clicks resize handle.
	 * @return false
	 */
	function resize_drag(e)
	{
		// Occurs repeatedly while user moves mouse after clicking on the resize handle.
		// Resizes the pldv_player_div.
		// The flpl and wmp objects only get resized after the user releases the mouse.
		e = e || window.event;
		
		// Get the height of the metadata display area and the height of the dragbar.
		var meta_height = parseInt(pldv_getOffsetHeight(pldv_meta_div_id));
		var drag_height = parseInt(pldv_getOffsetHeight(pldv_dragbar_div_id));
		
		// Get the real browser window inner dimensions.
		var dimensions = pldv_getDocumentDims();
		var docwidth = dimensions.width;
		var docheight = dimensions.height;
		
		// Determine the scrolled offset of the window - if user has scrolled down or to the right on the page.
		var offsetx = pldv_getWindowOffsetX();
		var offsety = pldv_getWindowOffsetY();
		
		// Find the width and height of the player div, in relation to the mouse position and the upper left corner of the div.
		var this_width = e.clientX - parseInt(pldv_div.style.left);
		var this_height = e.clientY  - parseInt(pldv_div.style.top) - meta_height;
		
		// Check to make sure the user isn't resizing out of bounds.
		var total_width = parseInt(pldv_getOffsetWidth(el.id));
		var total_height = this_height + meta_height + drag_height;
		var height_check = e.clientY + parseInt(pldv_getOffsetHeight(el.id))/2;
		if (((this_width + total_width) < docwidth)
				&& (e.clientX < docwidth)
				&& (total_height < docheight) 
				&& (height_check < docheight))
		{
			// check minimium sizes	
			if ((this_width + offsetx) < pldv_min_w)
			{
				this_width = pldv_min_w - offsetx;
			}
			if ((this_height + offsety) < pldv_min_h)
			{
				this_height = pldv_min_h - offsety;
			}

			pldv_set_div_size(this_width + offsetx + 5 , this_height + offsety - (parseInt(pldv_getOffsetWidth(el.id))));
		}
		return false;
	}


	
	/**
	 * resize_mousedown is a method of pldv_resizehandle, and is executed when user
	 * presses the mouse button over the resize div.
	 *
	 * @param {event} e The event activated upon mousedown when user clicks resize handle.
	 * @return false
	 */
	function resize_mousedown(e)
	{
		// Initiates a drag event, occurs when user clicks the resize handle.
		e = e || window.event;
		
		var target = (e && e.target) || (window.event && window.event.srcElement);
		// We may need to prevent WMP from resizing in FireFox.
		// Save any existing mouseup/mousemove functions that may have been set before the user resized.
		old_mouseup = document.onmouseup;
		old_mousemove = document.onmousemove;
		if (target == el)
		{
			// Only begin dragging if the mousedown event occurred from the resize handle.
			resize_enddrag();	// Make sure no other mousedrags are happening at the moment.
			document.onmouseup = resize_enddrag;
			document.onmousemove = resize_drag;
    			
			// Now, if WMP plugin isn't installed and browser is FireFox, display a message indicating installation is required.
			if ((pldv_status == 3)&&(!isIE)&&(!wmpl_needs_install))
			{
				pldv_player_div.innerHTML = wmpl_resizeff_message;
			}
		}
		return false;
	}
}


/**
 * pldv_dragbar is a class used to allow a div within pldv_div to act as
 * a draggable handle to reposition pldv_div and pldv_player_div if the user desires.
 * Object el must be assigned to an existing div before becoming a dragbar.
 * Usage: if (pldv_dragbar_div) new pldv_dragbar(pldv_dragbar_div);
 * Found in video_players.js, within pldv_initialize.
 *
 * @param object el This is a reference to the div that should be used as the dragbar handle (required).
 */
function pldv_dragbar(el)
{
	var click_offsetx = 0;
	var click_offsety = 0;
	var old_mouseup, old_mousemove;
	
	old_mouseup = document.onmouseup;
	old_mousemove = document.onmousemove;
	
	el.onmouseup = enddrag;
	el.onmousedown = drag_mousedown;
	
	/**
	 * enddrag is a method of pldv_dragbar, and is executed when user
	 * releases the mouse button and/or when dragging is complete.
	 * @param {event} e The event activated upon mouseup when user releases the mouse after clicking the drag handle.
	 */
	function enddrag(e)
	{
		// Occurs when user releases mouse after dragging.
		document.onmouseup = old_mouseup;
		document.onmousemove = old_mousemove;
	}
	
	/**
	 * drag is a method of pldv_dragbar, and is executed repeatedly as the user
	 * moves the mouse after clicking the dragbar handle div.  The function
	 * repositions the player div appropriately within the browser window, disallowing
	 * position adjustment outside of the visible browser window area.
	 * @param {event} e The event activated upon mousemove when drags mouse after clicking drag handle.
	 * @return false
	 */
	function drag(e)
	{
		// Occurs when user moves mouse (drags) after a mousedown occurs on the dragbar element.
		e = e || window.event;
		if ((parseInt(pldv_getOffsetX(pldv_id)) > -50)&&(!pldv_minimized))
		{
			// Determine the scrolled offset of the window - if user has scrolled down or to the right on the page.
			var offsetx = pldv_getWindowOffsetX();
			var offsety = pldv_getWindowOffsetY();
		
			var dimensions = pldv_getDocumentDims();
			var docwidth = dimensions.width;
			var docheight = dimensions.height;
			// Window restraints - prevents user from dragging pldv_div outside of the current window boundaries.
			if ((e.clientX - click_offsetx - offsetx + parseInt(pldv_getOffsetWidth(pldv_id))  < docwidth)
				&& (e.clientX - click_offsetx - offsetx > 0))	
			{
	  			pldv_div.style.left = (e.clientX - click_offsetx) + "px" ;
			} 
			if ((e.clientY - offsety - click_offsety + parseInt(pldv_getOffsetHeight(pldv_id)) < docheight )
				&& (e.clientY - click_offsety - offsety > 0)) 
			{
				pldv_div.style.top = (e.clientY - click_offsety) + "px";
			} 
		}
		else
		{
			// The user may have clicked the flpl_object's minimize button while near the edge of the browser window, while
			// a drag event was still active.  If so, stop the drag event so that the minimize animation isn't interrupted.
			enddrag();
		}
		return false;
	}
	
	/**
	 * drag_mousedown is a method of pldv_dragbar, and is executed when user clicks
	 * the drag handle div.  This starts the drag cycle.
	 * @param {event} e The event activated upon mousedown when user clicks the drag handle.
	 * @return false
	 */
	function drag_mousedown(e)
	{
		// Occurs when user clicks down on the dragging element.
		e = e || window.event;
		var target = (e && e.target) || (window.event && window.event.srcElement); 
		if (target.id == el.id)
		{
			enddrag(); // Make sure any other drag events are cleared.
   			click_offsetx = parseInt(e.clientX) - parseInt(pldv_getOffsetX(pldv_id));
			click_offsety = parseInt(e.clientY) - parseInt(pldv_getOffsetY(pldv_id));
			old_mouseup = document.onmouseup;
			old_mousemove = document.onmousemove;
			document.onmouseup = enddrag;
			document.onmousemove = drag;
		}

		return false;
	}
}

///////////// Resizing functions for setting size of pldv_div and pldv_player_div, and rescaling flpl_object.


/**
 * flpl_resize is a function used to resize the flash video player and the pldv_player_div.
 * It is used when the player div has been resized (ie via the resize handle).
 * @param int new_width This is the desired new width of the player div.
 * @param int new_height This is the desired new height of the player div.
 * @param string mode This is the viewmode, which is passed to the Flash player.
 */
function flpl_resize(new_width, new_height, mode)
{
	// Resizes the flash video player and the pldv_player_div.
	if (flpl_object)
	{
		pldv_set_div_size(new_width, new_height);

		// Now, reset the skin if necessary.
		flpl_check_skin(new_width, new_height);

		// Need to wait a moment before telling the flash object to resize so the player doesn't scale before the div is done sizing.
		setTimeout('flpl_object.resize_skin(' + new_width + ', ' + new_height + ', "' + mode + '");', 35);	
	}
}

/**
 * flpl_check_skin is a function used to make sure the appropriate skin is being used
 * when the flash player is resized, in case there is more than one skin available in 
 * the flpl_skin_array.
 * @param int new_width This is the new width of the player.
 * @param int new_height This is the new height of the player.
 */
function flpl_check_skin(new_width, new_height)
{
	// If there are multiple sizes of skins available, chooses the correct one for the particular width and height.
	// Performed on flpl_resize, as well as when switching from WMP to FLV playback.

	var new_id = flpl_skin_id;
	if ((flpl_skin_array != null) && (flpl_skin_array.length > 0))
	{	
		var found = false;
		for (i = 0; i < flpl_skin_array.length; i++)
		{
			if (found)
			{
				break;
			}
			if ((new_width >= flpl_skin_array[i].minw)
				&& (new_height >= flpl_skin_array[i].minh))
			{	
				new_id = flpl_skin_array[i].id;
				if ((new_width <= flpl_skin_array[i].maxw)&&(new_height <= flpl_skin_array[i].maxh))
				{
					found = true;
				}
			} 
		}		
	}
	if (new_id != flpl_skin_id)
	{
		flpl_skin_id = new_id;
	}
}

/**
 * flpl_resize_restricted is a wrapper for flpl_resize, only to be used in special cases.
 * When the flash player viewmode is set to "double" or "default", the player div gets
 * resized, and we need to make sure that the player isn't resized larger than the
 * visible area of the document in the browser.  See documentation.
 *
 * @param int new_width This is the desired new width of the player div.
 * @param int new_height This is the desired new height of the player div.
 * @param string mymode This is the viewmode, which is passed to the Flash player.
 */
function flpl_resize_restricted(new_width, new_height, mymode)
{
	if (flpl_object)
	{
		var dimensions = pldv_getDocumentDims();
		var docwidth = dimensions.width;
		var docheight = dimensions.height;
		var offsetx = pldv_getWindowOffsetX();
		var offsety = pldv_getWindowOffsetY();
		var meta_height = parseInt(pldv_getOffsetHeight(pldv_meta_div_id));
		var dragbar_height = parseInt(pldv_getOffsetHeight(pldv_dragbar_div_id));
		if (docwidth < (new_width + parseInt(pldv_getOffsetX(pldv_id)) - offsetx ))
		{	
			// first, move to flush left, then check again.
			pldv_div.style.left = (0 + offsetx) + "px";
			if (docwidth < (new_width + offsetx))
			{
				new_width = docwidth-2;
			}
		}
		if (docheight < (new_height + parseInt(pldv_getOffsetY(pldv_id)) - offsety ))
		{
			// set y coord to 0
			pldv_div.style.top = (0 + offsety) + "px";
			if (docheight < (new_height + offsety))
			{
				new_height = docheight - (meta_height + dragbar_height)-2;
			}
		}
		flpl_resize(new_width, new_height, mymode);
	}	
}

/**
 * pldv_set_div_size is function used to set the pldv_player_div and pldv_div width and height.
 * It can be called when the Flash player is loading a new skin, or when the player div is
 * being resized.
 *
 * @param int new_width This is the desired new width of the player div.
 * @param int new_height This is the desired new height of the player div.
 */
function pldv_set_div_size(new_width, new_height)
{
	// Resizes pldv_div (width only since height will stretch) and pldv_player_div.
	if (!new_width)
	{
		new_width = parseInt(pldv_player_div.style.width);
	}
	if (!new_height)
	{
		new_height = parseInt(pldv_player_div.style.height);
	}
	if ((pldv_player_div)&&(new_width > 20)&&(new_height > 20))
	{
		var old_width = pldv_player_div.style.width;
		pldv_player_div.style.width = new_width + "px";
		
		// check to make sure the window isn't shrinking further than the largest item in the div....
		var meta_width = parseInt(pldv_getOffsetWidth(pldv_meta_div_id));
		var dragbar_width = parseInt(pldv_getOffsetWidth(pldv_dragbar_div_id));
		var actual_width = parseInt(pldv_getOffsetWidth(pldv_player_div_id));
		
		if ((meta_width > actual_width))// && (dragbar_width > actual_width))
		{	
			if (parseInt(old_width) >= meta_width)
			{
				pldv_player_div.style.width = old_width;
			}
			else
			{
				pldv_player_div.style.width  = (meta_width + 10) + "px";
			}
			pldv_div.style.width = pldv_getOffsetWidth(pldv_player_div_id)+"px";
			
			// Now, if the new width is SIGNIFICANTLY smaller than the meta width, stop the mousedrag event, to prevent
			// weird video artifacts.
			if ((meta_width - actual_width) > 15)
			{
				document.onmouseup();
			}
		}
		else
		{
			pldv_div.style.width = pldv_getOffsetWidth(pldv_player_div_id)+"px";
		}
		// Because the metadata height may change, we have to check height as well.
		var meta_height = parseInt(pldv_getOffsetHeight(pldv_meta_div_id));
		var dragbar_height = parseInt(pldv_getOffsetHeight(pldv_dragbar_div_id));
			
		pldv_player_div.style.height = new_height + "px";
		flpl_width = new_width;
		flpl_height = new_height;
	}
}


////////////// Helpers - these determine various size/position information for <div>s that might not have a styled size/position.

/**
 * pldv_getOffsetHeight is function used to determine the actual height of a div
 * that may not have a style.height property.
 *
 * @param string id This is the id of the div whose height needs to be determined.
 * @return int The height in pixels of the div.
 */
function pldv_getOffsetHeight(id)
{
	// Returns actual height of elements that may not have a style.height property.
	var h = 0;
	var o;
	var d = document.getElementById(id);
	if('number' == typeof d.offsetHeight) 
	{
		h = d.offsetHeight;
	}
	else if ((o = document.defaultView) && o.getComputedStyle) 
	{
		h = o.getComputedStyle(d, null).height;
	}
	return h;
}

/**
 * pldv_getOffsetWidth is function used to determine the actual width of a div
 * that may not have a style.width property.
 *
 * @param string id This is the id of the div whose width needs to be determined.
 * @return int The width in pixels of the div.
 */
function pldv_getOffsetWidth(id)
{
	// Returns actual width of elements that may not have a style.width property.
	var w = 0;
	var o;
	var d = document.getElementById(id);
	if ('number' == typeof d.offsetWidth)
	{
		w = d.offsetWidth;
	}
	else if ((o = document.defaultView) && o.getComputedStyle)
	{
		w = o.getComputedStyle(d, null).width;
	}
	return w;
}

/**
 * pldv_getOffsetX is function used to determine the x position of a div
 * that may not have a style.left property.  Position is from left of browser.
 *
 * @param string id This is the id of the div whose x position needs to be determined.
 * @return int The position in pixels of the div, from the left side of the document window.
 */
function pldv_getOffsetX(id)
{
	// Returns X position of elements that may not have a style.left property.
	// Relative to browser window.
	var obj = document.getElementById(id);
	var curleft = 0;
	var parent_el=obj.offsetParent; 
	curleft = obj.offsetLeft;
	while (parent_el!=null)
	{ 
		curleft+=parent_el.offsetLeft; 
		parent_el=parent_el.offsetParent; 
	} 
	return curleft;
}

/**
 * pldv_getOffsetY is function used to determine the y position of a div
 * that may not have a style.top property.  Position is from top of browser.
 *
 * @param string id This is the id of the div whose y position needs to be determined.
 * @return int The position in pixels of the div, from the top of the document window.
 */
function pldv_getOffsetY(id)
{
	// Returns Y position of elements that may not have a style.top property.
	// Relative to browser window.
	var obj = document.getElementById(id);
	var curtop = 0;
	var parent_el=obj.offsetParent; 
	curtop = obj.offsetTop;
	while (parent_el!=null)
	{ 
		curtop+=parent_el.offsetTop; 
		parent_el=parent_el.offsetParent; 
	} 
	return curtop;
}

/**
 * pldv_getDocumentDims is function used to determine the width and height of the document
 * visible within the browser window, minus the width and height of any visible scrollbars.
 *
 * @return object The width and height of the client window.  Access via object.width and object.height.
 */
function pldv_getDocumentDims()
{
	// Determines the dimensions inside the browser window document area (user viewable), minus scrollbar width/height if present.
	var docwidth, docheight;
	var tempVersion = navigator.appVersion.toLowerCase();
	tempVersion = tempVersion.split("msie");
	tempVersion = tempVersion[1];
	var ieVersion = isIE ? parseInt(tempVersion) : null;
	var vert_scroll = 0;
	var horiz_scroll = 0;
	if (isIE)
	{
		docwidth = pldv_use_doc_el ? document.documentElement.clientWidth : document.body.offsetWidth;
		docheight = pldv_use_doc_el ? document.documentElement.clientHeight : document.body.offsetHeight;
	} 
	else 
	{
		docwidth = window.innerWidth;
		docheight = window.innerHeight;
	}
	 	
	// Check to see if scrollbars are present.  IE7's docwidth & height already take into account scroll widths,
	// but in FF, we need to subtract the width and height of the scrollbars appropriately.
	if (!isIE)
	{
		vert_scroll =  (document.body.scrollHeight - docheight > 0) ? 18 : 0;
		horiz_scroll =  (document.body.scrollWidth - docwidth > 0) ? 16 : 0;
	}
	docwidth = docwidth - vert_scroll - 2;
	docheight = docheight - horiz_scroll - 2;
	return({width: docwidth, height: docheight});
}

/**
 * pldv_getWindowOffsetX is function used to determine the scrolled offset width of the browser window.
 *
 * @return int offsetx The scroll offset width.
 */
function pldv_getWindowOffsetX()
{
	if (isIE)
	{
		offsetx = pldv_use_doc_el ? document.documentElement.scrollLeft : document.body.scrollLeft;
	}
	else 
	{
		offsetx = pageXOffset;
	}
	return offsetx;
}

/**
 * pldv_getWindowOffsetY is function used to determine the scrolled offset height of the browser window.
 *
 * @return int offsety The scroll offset height.
 */
function pldv_getWindowOffsetY()
{
	if (isIE)
	{
		offsety =  pldv_use_doc_el ? document.documentElement.scrollTop : document.body.scrollTop;
	}
	else 
	{
		offsety = pageYOffset;
	}
	return offsety;
}


/**
 * pldv_check_offsetX is function used to determine if the given x position of the floating player div
 * is within the viewable scrolled area of the browser window, and if not, returns a new value.
 *
 * @param int x_pos - required, the x position of the pldv_div, relative to the very left of the document
 * @param int width - required, the width of the pldv_div
 * @param int replace_pos - optional, the new value to use if the given x is bad
 * @return int x_pos - the usable x position.
 */
function pldv_check_offsetX(x_pos, width, replace_pos)
{
	if (!replace_pos)
	{
		replace_pos = 0;
	}
	var offsetx = pldv_getWindowOffsetX();
	var dimensions = pldv_getDocumentDims();
	var docwidth = dimensions.width;

	if ((x_pos < offsetx)||((x_pos + width) > (offsetx + docwidth)))
	{
		// the old x location of the player div is outside of the scrolled viewable area of the browser, adjust.
		x_pos = replace_pos + offsetx;
						
		if ((x_pos + width + 15) > (offsetx + docwidth))
		{
			// Check to make sure the right edge of player is within the scrollable area after repositioning.
			x_pos = offsetx + docwidth - width - 20;
		}			
	}
	return x_pos;
}

/**
 * pldv_check_offsetY is function used to determine if the given y position of the floating player div
 * is within the viewable scrolled area of the browser window, and if not, returns a new value.
 *
 * @param int y_pos - required, the y position of the pldv_div, relative to the very top of the document
 * @param int height - required, the height of the pldv_div
 * @param int replace_pos - optional, the new value to use if the given y is bad
 * @return int y_pos - the usable y position.
 */
function pldv_check_offsetY(y_pos, height, replace_pos)
{
	if (!replace_pos)
	{
		replace_pos = 0;
	}
	var offsety = pldv_getWindowOffsetY();
	var dimensions = pldv_getDocumentDims();
	var docheight = dimensions.height;

	if ((y_pos < offsety)||((y_pos + height) > (offsety + docheight)))
	{
		// the old y location of the player div is outside of the scrolled viewable area of the browser, adjust.
		y_pos = replace_pos + offsety;
						
		if ((y_pos + height + 15) > (offsety + docheight))
		{
			// Check to make sure the bottom edge of player is within the scrollable area after repositioning.
			y_pos = offsety + docheight - height - 20;
		}
	}
	return (y_pos < 0) ? 0 : y_pos;
}

/**
 * pldv_hide_immediate is a function that can be called directly to make pldv_div invisible WITHOUT animation.
 * Can be used by functions that need to temporarily make the player invisible, like login functions.
 */
function pldv_hide_immediate()
{
	if (pldv_div && (!pldv_minimized || pldv_animating)) // && (parseInt(pldv_div.style.left) > 0))
	{
		pldv_hide_immediate_override = true;
		if (parseInt(pldv_div.style.left) > 0)
		{
			pldv_slidehome_pos_x = pldv_div.style.left;
		}

		// set pldv_sh_offset.  These values will be used to reset the pldv_div position on restore, if user scrolls the browser window.
		pldv_sh_offset_x = parseInt(pldv_div.style.left) + pldv_getWindowOffsetX();
		pldv_sh_offset_y = parseInt(pldv_div.style.top) + pldv_getWindowOffsetY();

		if (pldv_status == 2)
		{
			// If flash player loaded...
			// cease playback, since the player will be hidden.
			flpl_object.pbk_pause();
		}
		if (pldv_status == 3)
		{
			// If WMP is loaded... pause playback.
			wmpl_pause();
		}
		pldv_div.style.left = "-3000px";
		pldv_minimized = true;
	}
}

/**
 * pldv_show_immediate is a function that can be called directly to make pldv_div visible WITHOUT animation.
 * Should ONLY be used to make the div visible again after calling pldv_hide_immediate. 
 */
function pldv_show_immediate()
{
	if (pldv_div && pldv_minimized)
	{
		pldv_hide_immediate_override = false;
		endX = parseInt(pldv_slidehome_pos_x);
		endY = parseInt(pldv_getOffsetY(pldv_id));
		endWidth = parseInt(pldv_getOffsetWidth(pldv_id));
		endHeight = parseInt(pldv_getOffsetHeight(pldv_id));

		endX = pldv_check_offsetX(endX, endWidth, pldv_sh_offset_x);

		if ((endX != parseInt(pldv_slidehome_pos_x)) && (parseInt(endX) != -3000))
		{
			pldv_slidehome_pos_x = endX + "px";
		}

		endY = pldv_check_offsetY(endY, endHeight, pldv_sh_offset_y);
		pldv_div.style.top = endY + "px";
		pldv_div.style.left = pldv_slidehome_pos_x;
		// If the flpl_object exists, tell it to activate its return-from-minimization code.
		if (flpl_object)                       
		{       
			flpl_object.unmini();                        
		}
		pldv_minimized = false;
		if (flpl_viewmode == "minimize")              
		{
			flpl_viewmode = "normal";   
		}
	}
} 
