/********************************************
(c) 2005-present, uTime Games
Despite the fact that you can see this, 
you may NOT use or copy this code for any reason.
If you'd like to use this code, please contact:
	Geoffrey Benson at
	sales@utimegames.com

Licensing terms are generally reasonable -
ranging from free to cheap - but you MUST
ask and obtain permission first.

Thank you for not being a jerk.
  --The Management
********************************************/

// The "window" JavaScript class

// Available modes:
// no_title : just the frame
// titled: with a titlebar, requires 'title' option
// closeable: same as titled, plus a close box, requires 'title' and 'close_message' options
// no_frame: just a content div

var PQWindow = Class.create({
	initialize: function( name, options )
	{
		// Private class variables initialization
		this._name = "";
		this._width = 0;
		this._height = 0;
		this._class = "";
		this._titlebar_text = "";
		this._mode = "titled";
		this._border_size = 10;
		this._titlebar_height = 26;
		this._overflow = "auto";
		this._moveable = false;
		this._on_page = false;
		this._left = 100;
		this._top = 200;
		this._always_in_back = false;
		this._side_panel = false;
		this._panel_contents = "default";
		
		// End Defaults
		
		this._name = name;
		
		// set various options
		if( !options )
			return;
			
		if( options['side_panel'] != undefined )
			this._side_panel = options['side_panel'];
		
		if( options['panel_contents'] != undefined )
			this._panel_contents = options['panel_contents'];
		
		if( options['overflow'] != undefined )
			this._overflow = options['overflow'];
		
		if( options['width'] != undefined )
			this._width = options['width'];
		
		if( options['height'] != undefined )
			this._height = options['height'];
		
		if( options['class'] != undefined )
			this._class = options['class'];
		
		if( options['title'] != undefined )
			this._titlebar_text = options['title'];

		if( options['mode'] != undefined )
			this._mode = options['mode'];
		
		if( this._mode == "closeable" )
			this._moveable = true;	// default to moveable for 'closeable'

		if( options['moveable'] != undefined )
			this._moveable = options['moveable'];
			
		if( this._moveable != true )
			this._on_page = true;
		
		if( options['on_page'] != undefined )
			this._on_page = options['on_page'];
		
		if( options['top'] != undefined )
			this._top = options['top'];
			
		if( options['left'] != undefined )
			this._left = options['left'];
		
		if( options['always_in_back'] != undefined )
			this._always_in_back = options['always_in_back'];
		
		// Create the window and put it on the page
		if( this._on_page == false )
		{
			// default sizes for these: width: 300, height: to fit
			if( !options['width'] )
			{
				options['width'] = 300;
				this._width = 300;
			}
			
			var main = $( this.GetWindowId() );
			if( !main )
			{
				// Get the body of the page
				frame = this.Generate();
				frame.hide();
				$$('body')[0].insert( frame );
			}
		}
		else
		{
			// These types are fixed, and just go into their parent element, already on the page, regardless of 'moveable' flag.
			var main = $( this.GetWindowId() );
			if( !main )
				return;
			
			frame = this.Generate();
			main.update( frame );
			main.scrollTop = 0;
		}
		
		if( this._moveable == true )
		{
			new Draggable( this.GetWindowId(), { 'handle': this.GetTitlebarId(), 'zindex': game_state.GetWindowDragZIndex(), 'onEnd': EndWindowDrag } );
		}
	},
	
	Generate: function()
	{
		// Construct and return a div that's visually the window, and can be retrieved by name.
		// Don't actually attach it to the DOM - that's up to the invoker
		var options = {};
		
		options['id'] = this.GetWindowId();
		
		if( this._class )
			options['class'] = this._class;

		options['onmouseup'] = "BringWindowToFront( '" + this.GetWindowId() + "' );";
		
		if( this._always_in_back == true )
			options['always_in_back'] = "true";
		
		var frame = new Element( 'div', options );
		
		if( this._width )
		{
			var temp_width = this._width + this._border_size * 2;
			frame.style.width = temp_width + "px";
		}
		
		if( this._height )
		{
			var temp_height = this._height + this._border_size * 2;
			if( this._mode == "titled" || this._mode == "closeable" )
				temp_height += this._titlebar_height;
			frame.style.height = temp_height + "px";
		}
		
		frame.style.zIndex = game_state.GetWindowZIndex();

		if( this._on_page == false )
		{
			// Cookies get precedence on window location.  Or, failing that, whatever defaults we have in the options.
			var outer_pos = $( 'main_window' ).viewportOffset();
			
			var window_name = this.GetWindowId();
			var pos = GetCookieWindowPosition( window_name );
			if( pos === false )
			{
				pos = { 'left': this._left, 'top': this._top };
			}

			var left = outer_pos['left'] + parseInt( pos['left'] );
			var top = outer_pos['top'] + parseInt( pos['top'] );

			frame.style.position = 'absolute';
			frame.style.left = left + 'px';
			frame.style.top = top + 'px';
		}
		
		// Side panel (if any)
		if( this._side_panel == true )
		{
			var tab_left = this._width + this._border_size * 2;
			var tab_top = 6;
			if( this._mode == "titled" || this._mode == "closeable" )
				tab_top += this._titlebar_height;
			else
				tab_top += this._border_size;
			
			var tab_style = 'left: ' + tab_left + 'px; top: ' + tab_top + 'px;';

			var panel_wrapper = new Element( 'div', { 'class': 'side_panel', 'id': this.GetWindowId() + "_side_wrapper", 'style': tab_style } );
			
			var panel_contents = new Element( 'div', { 'class': 'side_panel_contents', 'id': this.GetWindowId() + "_side_contents" } );
			
			var panel_contents_inner = new Element( 'div', { 'class': 'side_panel_contents_inner', 'id': this.GetWindowId() + "_side_contents_inner" } );
			panel_contents_inner.update( this._panel_contents );
			panel_contents.insert( panel_contents_inner );
			
			panel_wrapper.insert( panel_contents );
			
			var panel_tab = new Element( 'div', { 'class': 'side_panel_tab side_panel_tab_expanded', 'id': this.GetWindowId() + "_side_panel_tab", 'tooltip': 'Toggle' } );
			Event.observe( panel_tab, 'click', game_state.ToggleSideBar.bindAsEventListener( game_state, this.GetWindowId() ) );
			Event.observe( panel_tab, 'mouseover', game_state.EventShowTooltip );
			Event.observe( panel_tab, 'mouseout', game_state.EventClearTooltip );
			panel_wrapper.insert( panel_tab );
			
			frame.insert( panel_wrapper );
		}

		if( this._mode != "no_frame" )
		{
			// Window Top
			var top = new Element( 'div', { 'class' : 'window_top' } );
			
			var top_table = new Element( 'table' );
			var top_table_tbody = new Element( "tbody" );
			var top_table_row = new Element( "tr" );
			
			var top_table_left = new Element( "td", { 'class' : 'window_top_left_corner' } );
			var top_table_center = new Element( "td", { 'class' : 'window_top_border' } );
			var top_table_right = new Element( "td", { 'class' : 'window_top_right_corner' } );

			top_table_row.insert( top_table_left );
			top_table_row.insert( top_table_center );
			top_table_row.insert( top_table_right );
			
			top_table_tbody.insert( top_table_row );
			top_table.insert( top_table_tbody );
			top.insert( top_table );
			frame.insert( top );
		}

		// Window Titlebar (if any)
		if( this._mode == 'titled' || this._mode == 'closeable' )
		{
			var titlebar = new Element( "div", { 'class' : 'window_titlebar', 'id': this.GetTitlebarId() } );
			
			var titlebar_table = new Element( "table" );
			var titlebar_table_tbody = new Element( "tbody" );
			var titlebar_table_row = new Element( "tr" );
			
			var titlebar_table_left = new Element( "td", { 'class' : 'window_left_border' } );
			var titlebar_table_center = new Element( "td", { 'class' : 'window_titlebar_contents', 'id': this.GetTitlebarTextId() } );
			var titlebar_table_right = new Element( "td", { 'class' : 'window_right_border' } );
			
			titlebar_table_center.update( this._titlebar_text );
			if( this._moveable == true )
				titlebar_table_center.style.cursor = 'move';
			
			titlebar_table_row.insert( titlebar_table_left );
			titlebar_table_row.insert( titlebar_table_center );
			
			if( this._mode == 'closeable' )
			{
				var titlebar_table_closebox = new Element( "td", { 'class' : 'window_titlebar_control_link' } );
				var close_link = new Element( 'a', { 'href': "javascript:;", 'tooltip': "Close" } );
				Event.observe( close_link, 'click', game_state.EventCloseWindow.bindAsEventListener( game_state, this.GetWindowId() ) );
				close_link.update( "X" );
				Event.observe( close_link, 'mouseover', game_state.EventShowTooltip );
				Event.observe( close_link, 'mouseout', game_state.EventClearTooltip );
				titlebar_table_closebox.insert( close_link );
				close_link = null;
				
				titlebar_table_row.insert( titlebar_table_closebox );				
			}
			
			titlebar_table_row.insert( titlebar_table_right );
			
			titlebar_table_tbody.insert( titlebar_table_row );
			titlebar_table.insert( titlebar_table_tbody );
			titlebar.insert( titlebar_table );
			frame.insert( titlebar );

			var titlebar_bottom = new Element( "div" );
			titlebar_bottom.className = "window_titlebar_bottom";
			
			var titlebar_bottom_table = new Element( "table" );
			var titlebar_bottom_table_tbody = new Element( "tbody" );
			var titlebar_bottom_table_row = new Element( "tr" );
			
			var titlebar_bottom_table_left = new Element( "td", { 'class' : 'window_titlebar_bottom_left_corner' } );
			var titlebar_bottom_table_center = new Element( "td", { 'class' : 'window_bottom_border' } );
			var titlebar_bottom_table_right = new Element( "td", { 'class' : 'window_titlebar_bottom_right_corner' } );
			
			titlebar_bottom_table_row.insert( titlebar_bottom_table_left );
			titlebar_bottom_table_row.insert( titlebar_bottom_table_center );
			titlebar_bottom_table_row.insert( titlebar_bottom_table_right );
			
			titlebar_bottom_table_tbody.insert( titlebar_bottom_table_row );
			titlebar_bottom_table.insert( titlebar_bottom_table_tbody );
			titlebar_bottom.insert( titlebar_bottom_table );
			frame.insert( titlebar_bottom );
		}
		
		if( this._mode != "no_frame" )
		{
			// Window Middle
			var middle = new Element( "div", { 'class' : 'window_middle' } );
			
			var middle_table = new Element( "table" );
			var middle_table_tbody = new Element( "tbody" );
			var middle_table_row = new Element( "tr" );
			
			var middle_table_left = new Element( "td", { 'class' : 'window_left_border' } );
			var middle_table_center = new Element( "td" );
			var middle_table_right = new Element( "td", { 'class' : 'window_right_border' } );
			
			var content_wrapper = new Element( 'div', { 'id': this.GetContentId(), 'class': 'window_contents' } );
			
			// Set the size of the content
			if( this._width )
			{
				content_wrapper.style.width = this._width + "px";
			}
			
			if( this._height )
			{
				content_wrapper.style.height = this._height + "px";
			}
			
			content_wrapper.setStyle( { 'overflow': this._overflow } );
//			content_wrapper.style.overflow = this._overflow;
			
			middle_table_center.insert( content_wrapper );
			
			middle_table_row.insert( middle_table_left );
			middle_table_row.insert( middle_table_center );
			middle_table_row.insert( middle_table_right );
			
			middle_table_tbody.insert( middle_table_row );
			middle_table.insert( middle_table_tbody );
			middle.insert( middle_table );
			frame.insert( middle );
			
			// Window Bottom
			var bottom = new Element( "div", { 'class' : 'window_bottom' } );
			
			var bottom_table = new Element( "table" );
			var bottom_table_tbody = new Element( "tbody" );
			var bottom_table_row = new Element( "tr" );
			
			var bottom_table_left = new Element( "td", { 'class' : 'window_bottom_left_corner' } );
			var bottom_table_center = new Element( "td", { 'class' : 'window_bottom_border' } );
			var bottom_table_right = new Element( "td", { 'class' : 'window_bottom_right_corner' } );
			
			bottom_table_row.insert( bottom_table_left );
			bottom_table_row.insert( bottom_table_center );
			bottom_table_row.insert( bottom_table_right );
			
			bottom_table_tbody.insert( bottom_table_row );
			bottom_table.insert( bottom_table_tbody );
			bottom.insert( bottom_table );
			frame.insert( bottom );
		}
		
		if( this._mode == "no_frame" )
		{
			var content = new Element( "div", { 'id' : this.GetContentId() } );
			frame.insert( content );
		}
		
		return frame;
	},
	
	GetContentId: function()
	{
		if( this._on_page == true && this._mode == "no_frame" )
			return this._name;
		else
			return "pqwindow_contents_" + this._name;
	},
	
	GetWindowId: function()
	{
		if( this._on_page == true )
			return this._name;
		else
			return "pqwindow_" + this._name;
	},
	
	GetTitlebarId: function()
	{
		return "pqwindow_titlebar_" + this._name;
	},
	
	GetTitlebarTextId: function()
	{
		return "pqwindow_titlebar_text_" + this._name;
	}
});

function CloseWindow( window_id )
{
	var the_window = $( window_id );
	if( !the_window )
		return;

	if( the_window.readAttribute( 'displayed' ) != 'true' )
		return;
	
	the_window.setAttribute( 'displayed', 'false' );
	
	new Effect.DropOut( the_window, { 'duration': 0.3 } );
//	new Effect.Fade( the_window, { 'duration': 0.3 } );
//	new Effect.Fold( the_window, { 'duration': 0.3 } );
}

function ShowWindow( window_id )
{
	if( !g_window_cache[window_id] )
		return;
	g_window_cache[window_id].show();
/*	var the_window = $( window_id );
	if( !the_window )
		return;

	if( the_window.readAttribute( 'displayed' ) == 'true' )
		return;
	
	BringWindowToFront( window_id );
	
	the_window.setAttribute( 'displayed', 'true' );
	
	new Effect.Appear( the_window, { 'duration': 0.3 } );
//	new Effect.BlindDown( the_window, { 'duration': 0.4 } );
*/
}

function EndWindowDrag( object, event )
{
	// Store the new top/left position in a cookie for later use
	var window_name = object.element.readAttribute( 'id' );
	
	var temp_pos = object.element.viewportOffset();
	var outer_pos = $( 'main_window' ).viewportOffset();
	
	if( temp_pos['left'] < 0 )
	{
		object.element.style.left = 0;
		temp_pos['left'] = 0;
	}
	
	if( temp_pos['top'] < 0 )
	{
		object.element.style.top = 0;
		temp_pos['top'] = 0;
	}
	
	var pos = {};
	pos['left'] = temp_pos['left'] - outer_pos['left'];
	pos['top'] = temp_pos['top'] - outer_pos['top'];
	
	SetCookieWindowPosition( window_name, pos );
	
	var always_in_back = object.element.readAttribute( 'always_in_back' );
	if( always_in_back != "true" )
	{
		// as soon as we can, reset our z-index to the highest one on the stack
		setTimeout( "BringWindowToFront( '" + window_name + "' );", 15 );
	}
}

function BringWindowToFront( name )
{
	var the_window = $( name );
	if( !the_window )
		return;

	var always_in_back = the_window.readAttribute( 'always_in_back' );
	if( always_in_back == "true" )
		return;

	// Store the current scroll position in the content area of the window
	var temp = name.replace( /pqwindow_/, "pqwindow_contents_" );
	
	var contents = $( temp );
	
	var top = contents.scrollTop;

	the_window.style.zIndex = game_state.GetWindowZIndex();
	
	contents.scrollTop = top;
	
	// Special case for chat text, since the bit we need to scroll isn't the main content
	if( name == "pqwindow_chattext" )
	{
		var chattext = $('chattext_contents');
		if( chattext )
			chattext.scrollTop = chattext.scrollHeight;
	}
}

function GetCookieWindowPosition( name )
{
	// Loads the window position from the cookie by name, or else returns a default value
	var short_name = name.replace( /pqwindow_/, "" );
	
	var cookie_name = "pq_windows";
	if( game_state.IsFacebook() == true )
		cookie_name = "pqfb_windows";
	
	var raw_cookie = readCookie( cookie_name );
	if( raw_cookie == undefined )
		return false;
	
	var crumbles = raw_cookie.split( "|" );
	
	var len = crumbles.length;
	for( var i = 0; i < len; i++ )
	{
		var crumb = crumbles[i];
		var bits = crumb.split( ":" );
		if( bits[0] == short_name )
		{
			var temp = bits[1].split( "_" );
			var pos = {};
			pos['left'] = temp[0];
			pos['top'] = temp[1];
			return pos;
		}
	}
	
	// Name not found
	return false;
}

function SetCookieWindowPosition( name, pos )
{
	// Sets a window position in the cookie
	
	var short_name = name.replace( /pqwindow_/, "" );
	
	// First, break apart the existing cookie
	var cookie_name = "pq_windows";
	if( game_state.IsFacebook() == true )
		cookie_name = "pqfb_windows";

	var raw_cookie = readCookie( cookie_name );
	if( raw_cookie == undefined )
		raw_cookie = "";
	
	var window_hash = {};
	var crumbles = raw_cookie.split( "|" );
	
	var len = crumbles.length - 1;	// -1 to account for the trailing | character.
	for( var i = 0; i < len; i++ )
	{
		var crumb = crumbles[i];
		var bits = crumb.split( ":" );
		var temp = bits[1].split( "_" );
		var temp_pos = { 'left': temp[0], 'top': temp[1] };
		window_hash[bits[0]] = temp_pos;
	}
	
	// Set the window position
	window_hash[short_name] = pos;
	
	// Reassemble cookie
	var new_cookie = "";
	for( window_name in window_hash )
	{
		new_cookie += window_name + ":" + window_hash[window_name]['left'] + "_" + window_hash[window_name]['top'] + "|";
	}
	
	createCookie( cookie_name, new_cookie, 3652 );	// ~10 year expiration
}