/*
	Trampoline Sim.
	Copyright (c) 2009, Darragh Coy.
	All rights reserved.
	Original work(s), source code & author(s) details available at: http://www.darraghcoy.com

	Redistribution and use in source and binary forms, with or without modification, are permitted 
	provided that the following conditions are met:

		* 	Redistributions of source code must retain the above copyright notice, this list of 
			conditions and the following disclaimer.
		* 	Redistributions in binary form must reproduce the above copyright notice, this list of 
			conditions and the following disclaimer in the documentation.
		* 	Neither the name of the author nor the names of contributors may be used to endorse or 
			promote products derived from this software without specific prior written permission.
		* 	The use of any third party libraries, modules or data files provided with the source 
			form of the program must follow and respect the individual licensing terms of these 
			components. You do not have permission to modify or circumvent the licensing terms for 
			provided third party components unless the third party licenses specifically allow this. 
			If you do not agree to the terms of provided third party components then you do not have 
			permission to use them in your derived work(s).
		* 	The terms of this license do not apply to separate (but related) distributions if supplied 
			by the author(s), only to the contents of this source distribution, derived works, and the 
			binaries produced by either modified or unmodified versions of the source code. The terms 
			of this license do not also apply to any third party libraries or components provided with 
			the source distribution. Such third party elements are licensed under their own separate 
			agreements.

	THIS SOFTWARE IS PROVIDED BY DARRAGH COY ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
	BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
	ARE DISCLAIMED. IN NO EVENT SHALL DARRAGH COY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
	OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
	OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
	IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef WINDOW_H
#define WINDOW_H

//=====================================================================================================================
//=====================================================================================================================

#include "Graphics\Display.h"

//=====================================================================================================================
//=====================================================================================================================

namespace Game
{
	//=================================================================================================================
	//=================================================================================================================

	class Display;
	class WindowEventListener;
	
	//=================================================================================================================
	/// @param		Class representing a Win32 window with a DirectX9 display
	//=================================================================================================================

	class Window
	{
		public:

			//-------------------------------------------------------------------------------------------------------------
			// Functions
			//-------------------------------------------------------------------------------------------------------------

				/// Creates the Window with the specified parameters

				Window( std::string title , bool fullscreen , const Vec2u & size , Display::AntialiasingLevel aa_level = Display::ANTIALIAS_NONE );

				/// Destroys the window

				~Window();	
									
				/// Runs the window for a bit, performing some message processing

				void Run();

				/// Get the window handle for the window

				inline HWND GetWindowHandle() const { return m_window_handle; }

				/// Get the direct3d display

				inline Display * GetDisplay(){ return m_display; }
				
				/// Tells if this window is valid and if the display for the window is setup right
				
				virtual bool IsValid() const;
				
				/// Tells if the window currently exists. Does not say if it is valid however.		
				
				bool Exists() const;
				
				/// Get the window position in screen coordinates
				
				Vec2i GetPosition() const;			
				
				/// Get the center of the client area in screen coordinates:
				
				Vec2i GetClientCenterScreen() const;
				
				/// Get client size of the window
				
				Vec2u GetClientSize() const;
				
				/// Get the size of the window
				
				Vec2u GetSize() const;
				
				/// Get the size of the screen
				
				static Vec2u GetScreenSize();

				/// Is the window resizeable ?        
				
				bool IsResizeable() const;
				
				/// Is the window minimized ?
				
				bool IsMinimized() const;
							
				/// Is the window maximized ?
				
				bool IsMaximized() const;
				
				/// Is the window in focus ? 
				
				bool HasFocus() const; 
				
				/// Get the window title
				
				std::string GetTitle() const;

				/// Closes the window

				void Close();
				
				/// Minimizes the window
				
				void Minimize();
				
				/// Maximises the window
				
				void Maximize();
				
				/// Restores the window
				
				void Restore();
				
				/// Centers the window on the screen
				
				void Center();
				
				/// Requests a window repaint
				
				void RequestRepaint();
				
				/// Gives the window focus
				
				void GiveFocus();
				
				/// set if window is resizeable
				
				void SetResizeable( bool sizeable );
				
				/// set if the window is visible
				
				void SetVisible( bool visible );
				
				/// set window size
				
				void SetSize( const Vec2u & size );
				
				/// set window drawing area size (window automatically resizes too)
				
				void SetClientSize( const Vec2u & size );
				
				/// set window position
				
				void SetPosition( const Vec2i & position );

				/// sets window title			
				
				void SetTitle( std::string title );
				
				/// Converts the given screen position into window client coords
				
				Vec2i ToClientCoords( const Vec2i & screen_pos ) const;
								
				/// Converts the given client position into screen coordinates
				
				Vec2i ToScreenCoords( const Vec2i & client_pos ) const;
				
				/// Sets the current window event listener
				
				void SetEventListener( WindowEventListener * listener );

				///	Gets the current window event listener

				inline WindowEventListener * GetEventListener(){ return m_event_listener; }

		private:

			//-------------------------------------------------------------------------------------------------------------
			// Functions
			//-------------------------------------------------------------------------------------------------------------
						
				/// Registers the window class for the window if not already done so
				
				void RegisterWindowClass();
				
				/// Gets the module handle for the program if not done so		
				
				void RetrieveModuleHandle();
				
				/// Creates the actual window for this class with the operating system. Also gets the DC for the window.
				
				void SetupWindow( std::string title , const Vec2u & client_size );

				/// Window procedure for the window
				
				static LRESULT CALLBACK WindowProcedure( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam );

				/// Copying is not allowed

				Window( Window & );

				/// Copying is not allowed

				Window & operator = ( Window & );

				/// Called when the window is destroyed or deleted:

				void OnWindowDestroyed();

			//-------------------------------------------------------------------------------------------------------------
			// Variables
			//-------------------------------------------------------------------------------------------------------------

				/// ATOM uniquely identifying the window class
				
				static ATOM	s_window_class_atom;
				
				/// Module handle for the program
				
				static HMODULE s_module_handle;
				
				/// Handle for the window			
				
				HWND m_window_handle;	
				
				/// Device context for the window
				
				HDC	m_dc;				
				
				/// The DirectX9 display
				
				Display * m_display;
				
				/// Event listener that receives window events
				
				WindowEventListener * m_event_listener;

			//-------------------------------------------------------------------------------------------------------------
			// Constants
			//-------------------------------------------------------------------------------------------------------------

				/// Name of the window class

				static const char *	WIN_CLASS_NAME;			
	};
};

#endif 