/**
* SetupWindowEnvironment
*
* Sets up a windowing environment within the document body
**/
function SetupWindowEnvironment() { 

	document.body.addEventListener("mousemove", WindowAction, true);
	document.body._all_current_windows = new Object;

}

/**
* WindowingEnvironment
*
* A controller for the windowing environment
**/
function WindowingEnvironment( environment ) {

	this.environment = environment;
	this.all_current_windows = new Object;

	this.started = false;

}

new WindowingEnvironment();

/**
* WindowingEnvironment.start
*
* Add the mousemove event listener to the windowing environment
**/
WindowingEnvironment.prototype.start = function() { 


	//this.environment.addEventListener("mousemove", WindowAction, true );
	CBAddEventListener( this.environment, "mousemove", WindowAction );
	this.environment.windowing_environment = this;

	this.started = true;

}

/**
* WindowingEnvironment.addPopupWindow
*
* Add a popup window to the windowing environment
*
* @param p The PopupWindow to add
*
**/
WindowingEnvironment.prototype.addPopupWindow = function( p ) { 

	if ( !this.started ) throw( "WindowingEnvironment.addPopupWindow :: Cannot addPopupWindow to an unstarted WindowingEnvironment" );

	if( this.all_current_windows[ p.name ] ) throw( "WindowingEnvironment.addPopupWindow :: popup window with name " + p.name + " already in WindowingEnvironment" );

	this.all_current_windows[ p.name ] = p;

	p.header.setMouseDownCommand( new StartMovingPopupWindowCommand( p, this ) );
	p.header.setMouseUpCommand( new StopMovingPopupWindowCommand( p, this ) );

	//create a close button if necessary
	//create a close button if necessary
	if ( p.closable ) { 
		var cbut = new SimpleButtonWidget( p.style_set, new ClosePopupWindowCommand( this, p ) );
		cbut.addContentNode( textToDOM( "span", "close" ) );

		p.addControlButton( cbut );
	}

	//center the popup window
	var win_width = getWindowWidth();
	var win_height = getWindowHeight();

	var center_left = ( parseInt( win_width ) / 2 ) - ( parseInt( p.start_width ) / 2 );
	var center_top = ( parseInt( win_height ) / 2 ) - ( parseInt( p.start_height ) / 2 ) + document.body.scrollTop;

	p.setPosition( center_top, center_left );

	this.environment.appendChild( p.getDOM() );

}

/**
* WindowingEnvironment.removePopupWindow
*
* Remove a popup window from the windowing environment
*
* @param p the PopupWindow to remove
**/
WindowingEnvironment.prototype.removePopupWindow = function( p ) {

	if ( ! this.all_current_windows[ p.name ] ) throw( "WindowingEnvironment.removePopupWindow :: no popup window with name " + p.name + " exists in WindowingEnvironment" );
	delete this.all_current_windows[ p.name ];
	this.environment.removeChild( p.getDOM() );

}

/**
* WindowingEnvironment.setMoving
*
* Set a particular window to moving inside the windowing environment
*
* @param p The PopupWindow to set moving
* @param start_x
* @param start_y
**/
WindowingEnvironment.prototype.setMoving = function( p, start_x, start_y ) { 
	

	//alert( "set moving x: " + start_x + " y: " + start_y + " p: " + p.constructor );
	this.current_moving = p;
	this.start_mouse_x = start_x;
	this.start_mouse_y = start_y;
	this.current_moving.start_mouse_x = start_x;
	this.current_moving.start_mouse_y = start_y;

}

/**
* WindowingEnvironment.unsetMoving
*
* Unset a particular window to moving inside the windowing environment
*
* @param p The PopupWindow to unset moving
**/
WindowingEnvironment.prototype.unsetMoving = function( p ) { 
	
	if ( this.current_moving == p ) 
		this.current_moving = null;

}



/**
* StartMovingPopupWindowCommand
*
* @param p The PopupWindow which will be moving
* @param e The PopupWindow engine
**/
function StartMovingPopupWindowCommand( p, e ) {

	this.popup_window = p;
	this.popup_window_engine = e;

}

new StartMovingPopupWindowCommand( null, null );

StartMovingPopupWindowCommand.prototype.execute = function(e) { 

	this.popup_window_engine.setMoving( this.popup_window, e.clientX + document.body.scrollLeft, e.clientY + document.body.scrollTop );

}

/**
* StopMovingPopupWindowCommand
*
* @param p The PopupWindow which is moving
* @param e The PopupWindow engine
**/
function StopMovingPopupWindowCommand( p, e ) {

	this.popup_window = p;
	this.popup_window_engine = e;

}

new StopMovingPopupWindowCommand( null, null );

StopMovingPopupWindowCommand.prototype.execute = function() { 

	this.popup_window_engine.unsetMoving( this.popup_window );

}


function WindowAction(e) {

	if ( document.body.windowing_environment.current_moving != null ) {
		
		var win_cur_mov = document.body.windowing_environment.current_moving.getDOM();
		
		var new_event_x_pos = e.clientX + document.body.scrollLeft;
		var new_event_y_pos = e.clientY + document.body.scrollTop;
		 
		//alert( "windowing environment starts x: " + document.body.windowing_environment.current_moving.start_mouse_x + " y: " + document.body.windowing_environment.current_moving.start_mouse_y );

		var new_x_shift = parseInt( document.body.windowing_environment.current_moving.start_mouse_x ) - parseInt( new_event_x_pos );
		var new_y_shift = parseInt( document.body.windowing_environment.current_moving.start_mouse_y ) - parseInt( new_event_y_pos );

		//alert( "new shifts x: " + new_x_shift + " y: " + new_y_shift );

		var new_x_pos = parseInt( win_cur_mov.style.left ) - new_x_shift;
		var new_y_pos = parseInt( win_cur_mov.style.top ) - new_y_shift;
	
		document.body.windowing_environment.current_moving.start_mouse_x = new_event_x_pos;
		document.body.windowing_environment.current_moving.start_mouse_y = new_event_y_pos;

		win_cur_mov.style.left = new_x_pos;
		win_cur_mov.style.top = new_y_pos;
		
	}

}


/**
* ClosePopupWindowCommand
*
* @param we The windowning engine to remove the window from
* @param p the window to remove
**/
function ClosePopupWindowCommand( we, p ) { 

	this.window_engine = we;
	this.popup_window = p;

}

new ClosePopupWindowCommand( null, null );

ClosePopupWindowCommand.prototype.execute = function() { 

	this.window_engine.removePopupWindow( this.popup_window );

}

