/* ====================================================================== */
/* ---------------------------------------------------------------------- */
/**images
 * The javascript source engine for internal windows manager. Window decoration
 * and style is defined in separate file iwindow_style.css.
 */



/* ====================================================================== */
/* Global declarations */
var wins = new Array(100);
var id_counter = 1;
var IE, opera;
var initialized = false;
var selected;

/* ====================================================================== */
/* ---------------------- Public functions ------------------------------ */
/**
 * Creates internal window with window parent container.
 * @param title the title of the window
 * @param body the content of the window to display
 * @param xpos the X position from left border of the document body
 * @param ypos the Y position from left border of the document body
 * @param width width of the window
 * @param height height of the window
 * @return a window object
 */
function openGlobalWindow(title, body, xpos, ypos, width, height)
{
	initialize();
  win = makeWindow('', 'about:blank', xpos, ypos, width, height, title, body);
  return win;
}

/**
 * Creates internal window with dock parent.
 * @param parent the ID of the parent dock
 * @param title the title of the window
 * @param body the content of the window to display
 * @param xpos the X position from left border of the document body
 * @param ypos the Y position from left border of the document body
 * @param width width of the window
 * @param height height of the window
 * @return a window object
 */
function openInternalWindow(parent, title, body, xpos, ypos, width, height)
{
	initialize();
  win = makeWindow(parent, 'about:blank', xpos, ypos, width, height, title, body);
  return win;
}

/**
 * Sets the window resizable property.
 * @param res boolean value
 */
function setResizable(res)
{
	if (this.resizable == res)
		return;
	this.resizable = res;
	if (res == false)
	{		
		var elem = document.getElementById("w_border_resize_" + this.id);
		this.w_resize_element = elem;
		elem.parentNode.removeChild(elem);
	} else
	{
		var elem = document.getElementById("w_body_" + this.id);
		elem.appendChild(this.w_resize_element);
	}
}

/**
 * Sets the window movable property.
 * @param res boolean value to be set
 */
function setMovable(mov)
{
	this.movable = mov;
}


/* ====================================================================== */
/* ---------------------- Private functions ----------------------------- */

/**
 * Default constructor for Window object.
 */
function Window(id, parent, element, width, height)
{
	// Properties
	this.id = id;
	this.parent = parent;
	this.element = element;
	this.minimized = false;
	this.maximized = false;
	this.width = width;
	this.height = height;
	this.x = findPosX(element);
	this.y = findPosY(element);
	this.movable = true;
	this.resizable = true;
	
	// Methods
	this.setResizable = setResizable;
	this.setMovable = setMovable;
}

/**
 * Window manager initialization.
 */
function initialize()
{
	if (initialized)
		return;

	var detect = navigator.userAgent.toLowerCase();
  IE = (detect.indexOf('msie') + 1) ? true : false;
  opera = (detect.indexOf('opera') + 1) ? true : false;
	if (opera)
		IE = false;
	
	if (!IE) {
		// Register the mouse events
		document.captureEvents(Event.MOUSEUP|Event.MOUSEDOWN);
	}

	// Register event handlers
	document.onmousedown = mouse_down;
	document.onmouseup = mouse_up;
	initialized = true;
}

/**
 * Creates window.
 */
function makeWindow(parent, url, xpos, ypos, width, height, title, body)
{
	// customize style for IE
	var w_border_tl_ie = "";
	var w_border_tr_ie = "";
	var w_border_bl_ie = "";
	var w_border_br_ie = "";
	var w_border_l_ie = "";
	var w_border_t_ie = "";
	var w_border_r_ie = "";
	var w_border_b_ie = "";
	var w_border_resize_ie = "";
	var w_body_ie = "";
	var w_content_ie = "";
	if (IE) {
		w_border_tl_ie = "filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"/images/iwindow_resources/border_tl.png\", sizingMethod=\"scale\"); background-image: none;";
		w_border_tr_ie = "filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"/images/iwindow_resources/border_tr.png\", sizingMethod=\"scale\"); background-image: none;";
		w_border_bl_ie = "filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"/images/iwindow_resources/border_bl.png\", sizingMethod=\"scale\"); background-image: none;";
		w_border_br_ie = "filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"/images/iwindow_resources/border_br.png\", sizingMethod=\"scale\"); background-image: none;";
		w_border_resize_ie = "filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"/images/iwindow_resources/resize.png\", sizingMethod=\"crop\");"
			+ "background-image: none; cursor: default;";
		w_border_l_ie = "height: "+ (height - 40) +"px;" +
			"filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"/images/iwindow_resources/border_l.png\", sizingMethod=\"scale\"); background-image: none;";
		w_border_t_ie = "width: "+ (width - 40) +"px;" +
			"filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"/images/iwindow_resources/border_t.png\", sizingMethod=\"scale\"); background-image: none;";
		w_border_b_ie = "width: "+ (width - 40) +"px;" +
			"filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"/images/iwindow_resources/border_b.png\", sizingMethod=\"scale\"); background-image: none;";
		w_border_r_ie = "height: "+ (height - 40) +"px;" +
			"filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src=\"/images/iwindow_resources/border_r.png\", sizingMethod=\"scale\"); background-image: none;";
		w_body_ie = "width: "+ (width - 22) +"px; height: "+ (height - 22) +"px;";
		w_content_ie = "width: "+ (width - 22) + "px; height: "+ (height - 68) + "px;";
	}
	
	var win_content = 
			"<div id='w_border_tl_"+ id_counter +"' class='w_border_tl' style='"+ w_border_tl_ie +"'></div>"
		+ "<div id='w_border_t_"+ id_counter +"' class='w_border_t' style='" + w_border_t_ie + "'></div>"
		+ "<div id='w_border_tr_"+ id_counter +"' class='w_border_tr' style='"+ w_border_tr_ie +"'></div>"
		+ "<div id='w_border_l_"+ id_counter +"' class='w_border_l' style='" + w_border_l_ie + "'></div>"
		+ "<div id='w_border_r_"+ id_counter +"' class='w_border_r' style='" + w_border_r_ie + "'></div>"
		+ "<div id='w_border_bl_"+ id_counter +"' class='w_border_bl' style='"+ w_border_bl_ie +"'></div>"
		+ "<div id='w_border_b_"+ id_counter +"' class='w_border_b' style='" + w_border_b_ie + "'></div>"
		+ "<div id='w_border_br_"+ id_counter +"' class='w_border_br' style='"+ w_border_br_ie +"'></div>"
		+ "<div id='w_body_"+ id_counter +"' class='w_body' style='"+ w_body_ie +"' onmousedown='javascript:select_win("+ id_counter +");'>"
			+ "<div id='w_title_"+ id_counter +"' class='w_title'><div>"+ title +"</div>"
				+ "<a id='w_min_btn_"+ id_counter +"' class='w_min_btn' onclick='javascript:minimize_win("+ id_counter +")'></a>"
				+ "<a id='w_max_btn_"+ id_counter +"' class='w_max_btn' onclick='javascript:maximize_win("+ id_counter +")'></a>"
				+ "<a id='w_close_btn_"+ id_counter +"' class='w_close_btn' onclick='javascript:close_win("+ id_counter +")'></a>"
			+ "</div>"
			+ "<div id='w_content_"+ id_counter +"' class='w_content' style='"+ w_content_ie +"'>" + body + "</div>"
			+ "<div id='w_border_resize_"+ id_counter +"' class='w_border_resize' style='"+ w_border_resize_ie +"'>Resize</div>"
		+ "</div>";
	
	// Check the parent and set X,Y correction
	if (parent.length != 0 && document.getElementById(parent))
	{
		// Try to find parent dock
		var p = document.getElementById(parent);
		p_width = p.offsetWidth;
		p_height = p.offsetHeight;
		p_left = findPosX(p);
		p_top = findPosY(p);
		if (p_top > ypos || ypos > (p_top + p_height)) ypos = p_top;
		if (p_left > xpos || xpos > (p_left + p_width))	xpos = p_left;
			
	}
	
	// create the window element
  win = document.createElement('div');
	win.id = "w_" + id_counter;
	if (!IE)
		win.setAttribute('style', "padding: 0px; position: absolute; width: "+ width + "px; height: "+ height +"px; z-index: "+ id_counter +"; left: "+ xpos +"px; top: "+ ypos +"px;");	
	else
		win.style.cssText = "padding: 0px; position: absolute; width: "+ width + "px; height: "+ height +"px; z-index: "+ id_counter +"; left: "+ xpos +"px; top: "+ ypos +"px;";	
  win.innerHTML = win_content;
  document.body.appendChild(win);
	
  win_obj = new Window(id_counter, parent, win, width, height);
  wins[id_counter] = win_obj;
	id_counter = id_counter + 1;
	return win_obj;
}

/**
 * Closes the window specified by ID.
 */
function close_win(id) 
{ 
	if (openedDialog == 1)
	  media_sync(null);
	document.body.removeChild(wins[id].element); 
	openedDialog = 0;
}

/**
 * Minimizes the window.
 */
function minimize_win(id)
{
	var win = wins[id];
	
	if (win.maximized)
		maximize_win(id);

	if (win.minimized)
	{
		win.element.style.height = win.height + 'px';
		if (win.resizable)
		{
			elem = document.getElementById("w_border_resize_" + id);
			elem.style.visibility = 'visible';
		}
		
		if (IE || opera)
		{
			elem = document.getElementById("w_border_l_" + id);
			elem.style.height = (win.height - 40) + 'px';
			elem = document.getElementById("w_border_r_" + id);
			elem.style.height = (win.height - 40) + 'px';
			elem = document.getElementById("w_body_" + id);
			elem.style.height = (win.height - 22) + 'px';
			elem = document.getElementById("w_content_" + id);
			elem.style.visibility = 'visible';
		}
		win.minimized = false;
	} else
	{
		// Store old position and size
		win.height = parseInt(win.element.style.height);
		win.element.style.height = '50px';
		if (win.resizable)
		{
			elem = document.getElementById("w_border_resize_" + id);
			elem.style.visibility = 'hidden';
		}

		if (IE || opera)
		{
			elem = document.getElementById("w_border_l_" + id);
			elem.style.height = '10px';
			elem = document.getElementById("w_border_r_" + id);
			elem.style.height = '10px';
			elem = document.getElementById("w_body_" + id);
			elem.style.height = '10px';
			elem = document.getElementById("w_content_" + id);
			elem.style.visibility = 'hidden';
		}
		win.minimized = true;
	}
	return false;
}

/**
 * Maximize the window.
 */
function maximize_win(id)
{	
	var win = wins[id];
	
	if (win.minimized)
		minimize_win(id);
	
	if (win.maximized)
	{
		// Restore old size
		win.element.style.height = win.height + 'px';
		win.element.style.width = win.width + 'px';
		win.element.style.left = win.x + 'px';
		win.element.style.top = win.y + 'px';
		
		if (IE || opera)
		{
			elem = document.getElementById("w_border_l_" + id);
			elem.style.height = (win.height - 40) + "px";
			elem = document.getElementById("w_border_r_" + id);
			elem.style.height = (win.height - 40) + "px";
			elem = document.getElementById("w_border_t_" + id);
			elem.style.width = (win.width - 40) + "px";
			elem = document.getElementById("w_border_b_" + id);
			elem.style.width = (win.width - 40) + "px";
			elem = document.getElementById("w_body_" + id);			
			elem.style.width = (win.width - 22) + "px";
			elem.style.height = (win.height - 22) + "px";			
		}
		win.maximized = false;
	} else
	{
		var width, height;
		
		// Store old position and size
		win.width = parseInt(win.element.style.width);
		win.height = parseInt(win.element.style.height);
		win.x = parseInt(win.element.style.left);
		win.y = parseInt(win.element.style.top);		
		
		if (win.parent.length != 0 && document.getElementById(win.parent))
		{
			// Try to find parent dock
			var parent = document.getElementById(win.parent);
			width = parent.offsetWidth;
			height = parent.offsetHeight;
			win.element.style.left = findPosX(parent) + "px";
			win.element.style.top = findPosY(parent) + "px";
		} else
		{
			// No parent dock			
			win.element.style.left = "0px";
			win.element.style.top = "0px";
			
			width = document.documentElement.clientWidth;
			height = document.documentElement.clientHeight;
			if (opera)
				height = document.body.clientHeight;
		}			
				
		win.element.style.width =  width + "px";
		win.element.style.height = height  + "px";			
		
		if (IE || opera)
		{
			elem = document.getElementById("w_border_l_" + id);
			elem.style.height = (height - 40) + "px";
			elem = document.getElementById("w_border_r_" + id);
			elem.style.height = (height - 40) + "px";
			elem = document.getElementById("w_border_t_" + id);
			elem.style.width = (width - 41) + "px";
			elem = document.getElementById("w_border_b_" + id);
			elem.style.width = (width - 41) + "px";
			elem = document.getElementById("w_body_" + id);			
			elem.style.width = (width - 22) + "px";
			elem.style.height = (height - 22) + "px";			
		}
		win.maximized = true;
	}
	
	return false;
}

/**
 * Handle window selection. 
 */
function select_win(id)
{
	selected = wins[id];
	
	var maxZIndex = getMaxZIndex(wins);	
	var oldZIndex = selected.element.style.zIndex;
	selected.element.style.zIndex = maxZIndex + 1;
	arrangeZIndexes(wins, oldZIndex);
}

/**
 * Returns max Z index from window elements.
 */
function getMaxZIndex(wins)
{
	var maxZ = 0;
	for (var i in wins)
	{
		if (wins[i].element) {
			z = parseInt(wins[i].element.style.zIndex);
			if (z > maxZ)
				maxZ = z;
		}
	}
	return maxZ;
}

/**
 * Arranges the Z-indexes in window elements.(preserve infinite increments)
 */
function arrangeZIndexes(wins, oldZIndex)
{
	for (var i in wins)
	{
		if (wins[i].element) {
			if (wins[i].element.style.zIndex > oldZIndex)
				wins[i].element.style.zIndex = (parseInt(wins[i].element.style.zIndex) - 1);
		}
	}
}

/**
 * Called when mouse button is released.
 */
function mouse_up(ev)
{
	// Disable the mousemove listener
	document.onmousemove = null;
}

/**
 * Mouse down handler. Registers move handler functions.
 */
function mouse_down(ev)
{
	if (selected == null)
		return false;
	
	if (IE) {
		click_x = event.clientX;
		click_y = event.clientY;
	} else {
		click_x = ev.pageX;
		click_y = ev.pageY;
	}  
	
	px  = parseInt(selected.element.style.left);
	py  = parseInt(selected.element.style.top);
	pw = parseInt(selected.element.style.width);
	ph = parseInt(selected.element.style.height);

	if (px <= click_x && click_x <= (px + pw) && 
	    py <= click_y && click_y <= (py + ph)) 
	{
		if (click_y <= (py + 35) && selected.movable) 
		{
			if (!IE) document.captureEvents(Event.MOUSEMOVE);
			document.onmousemove = mouse_move;
		} else {

			if (selected.resizable && 
			   (click_x >= (px + pw - 30) && click_x <= (px + pw - 15) && 
			    click_y >= (py + ph - 30) && click_y <= (py + ph - 15))) 
			{			
				if (!IE) document.captureEvents(Event.MOUSEMOVE);
				document.onmousemove = mouse_resize;
			}
		}
	} else 
		document.onmousemove = null;
}

/**
 * Called when window is moved.
 */
function mouse_move(ev)
{
	if (selected.parent.length != 0 && document.getElementById(selected.parent))
	{
		// Try to find parent dock
		var parent = document.getElementById(selected.parent);
		winMinMoveX  = findPosX(parent);
		winMinMoveY  = findPosY(parent);
		winMaxMoveX = parent.offsetWidth;
		winMaxMoveY = parent.offsetHeight;
	} else
	{
		winMinMoveX  = 0;
		winMinMoveY  = 0;
		// winMaxMoveX = document.documentElement.clientWidth;
		// winMaxMoveY = document.documentElement.clientHeight;
		winMaxMoveX = document.body.clientWidth;
		winMaxMoveY = document.body.clientHeight;
		if (opera)
			winMaxMoveY = document.body.clientHeight;
	}

	if (IE) {
		var tempX = px + (event.clientX - click_x);
		var tempY = py + (event.clientY - click_y);

		var tempw = (winMaxMoveX + winMinMoveX) - pw;
		var temph = (winMaxMoveY + winMinMoveY) - ph;
	} else {
		var tempX = px + (ev.clientX - click_x);
		var tempY = py + (ev.clientY - click_y);

		var tempw = (winMaxMoveX + winMinMoveX) - pw;
		var temph = (winMaxMoveY + winMinMoveY) - ph;
	}

	// Let's not go negative
	tempw = tempw < 0 ? 0 : tempw;
	temph = temph < 0 ? 0 : temph;

	if (tempX < winMinMoveX) 
	  selected.element.style.left = winMinMoveX + "px";
	else if (tempX > tempw) 
	  selected.element.style.left = tempw + "px";
	else
	  selected.element.style.left = tempX + "px";
		
	if (tempY < winMinMoveY)
	  selected.element.style.top = winMinMoveY + "px";
	else if (tempY > temph) 
	  selected.element.style.top = temph + "px";
	else
	  selected.element.style.top = tempY + "px";

	return false;
}

/**
 * Called when window is resized.
 */
function mouse_resize(ev)
{
	if (selected.parent.length != 0 && document.getElementById(selected.parent))
	{
		// Try to find parent dock
		var parent = document.getElementById(selected.parent);
		winMinMoveX  = findPosX(parent);
		winMinMoveY  = findPosY(parent);
		winMaxMoveX = parent.offsetWidth;
		winMaxMoveY = parent.offsetHeight;
	} else
	{
		winMinMoveX  = 0;
		winMinMoveY  = 0;
		winMaxMoveX = document.documentElement.clientWidth;
		winMaxMoveY = document.documentElement.clientHeight;
		if (opera)
			winMaxMoveY = document.body.clientHeight;
	}
	
	if (IE) {
		var tempX = pw + (event.clientX - click_x);
		var tempY = ph + (event.clientY - click_y);

		var tempw = px - winMinMoveX;
		var temph = py - winMinMoveY;
	} else {
		var tempX = pw + (ev.clientX - click_x);
		var tempY = ph + (ev.clientY - click_y);

		var tempw = px - winMinMoveX - 2;
		var temph = py - winMinMoveY - 2;
	}

	// Check the parent dock
	if (tempX > (winMaxMoveX - tempw) || tempY > (winMaxMoveY - temph)) 
		return;
	
	// Minimal size
	if (tempX < 120 || tempY < 65)
		return;
	
	height = tempY;
	width = tempX;
	id = selected.id;
	selected.element.style.width  = tempX + "px";
	selected.element.style.height = tempY + "px";
	
	if (IE || opera)
		{
			elem = document.getElementById("w_border_l_" + id);
			elem.style.height = (height - 40) + "px";
			elem = document.getElementById("w_border_r_" + id);
			elem.style.height = (height - 40) + "px";
			elem = document.getElementById("w_border_t_" + id);
			elem.style.width = (width - 40) + "px";
			elem = document.getElementById("w_border_b_" + id);
			elem.style.width = (width - 40) + "px";
			elem = document.getElementById("w_body_" + id);			
			elem.style.width = (width - 22) + "px";
			elem.style.height = (height - 22) + "px";
			if (IE)
			{
				elem = document.getElementById("w_content_" + id);			
				elem.style.width = (width - 22) + "px";
				elem.style.height = (height - 68) + "px";			
			}
		}
	
	return false;
}

/**
 * Finds the real X position of the element.
 */
function findPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}

/**
 * Finds the real Y position of the element.
 */
function findPosY(obj)
{
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}
