#ifndef __DEMOPAJA_DX8VIEWPORTC_H__
#define __DEMOPAJA_DX8VIEWPORTC_H__

// forw declaration
namespace PajaSystem {
	class DX8ViewportC;
};

#include "PajaTypes.h"
#include "DeviceInterfaceI.h"
#include "GraphicsViewportI.h"
#include "Vector2C.h"
#include "BBox2C.h"
#include "DX8DeviceC.h"


namespace PajaSystem {

	//! The ID of the OpenGL interface, use this ID to request the interface.
	const PluginClass::ClassIdC	CLASS_DX8_VIEWPORT = PluginClass::ClassIdC( 0, 20001 );


	//! Device interface for OpenGL
	/*!	The purpose of the device interface for OpenGL is to setup
		the area where an effect can draw and to convert coordinates
		from screen (pixel) coordinates to the layout.
	*/
	class DX8ViewportC : public GraphicsViewportI
	{
	public:

		virtual Edit::DataBlockI*				create();
		static DX8ViewportC*					create_new( DX8DeviceC* pDevice );
		virtual PluginClass::ClassIdC			get_class_id() const;
		virtual const char*						get_class_name();

		//! Sets perspective viewport and projection matrix.
		/*!	\param rBBox the bounding box of the effect.
			\param f32FOV FOV on x-axis.
			\param f32Aspect Aspect ration of the viewport.
			\param f32ZNear Near clipping plane.
			\param f32ZFar Far clipping plane.

			The bounding box is used to define the DX viewport. It means that all the rendering is clipped to the bounding box.
			The viewport is clipped against the maximum viewport boundaries and projection matrix is changed accordingly.
		*/
		virtual void				set_perspective( const PajaTypes::BBox2C& rBBox, PajaTypes::float32 f32FOV, PajaTypes::float32 f32Aspect,
										PajaTypes::float32 f32ZNear, PajaTypes::float32 f32ZFar );

		//! Sets orthographic viewport and projection matrix.
		/*!	\param rBBox the bounding box of the effect.
			\param f32Width Width of the viewport.
			\param f32Height Height of the viewport.
			\param f32ZNear Near clipping plane.
			\param f32ZFar Far clipping plane.

			The bounding box is used to define the DX viewport. It means that all the rendering is clipped to the bounding box.
			The viewport is clipped against the maximum viewport boundaries and projection matrix is changed accordingly.
		*/
		virtual void				set_ortho( const PajaTypes::BBox2C& rBBox,
										PajaTypes::float32 f32Left, PajaTypes::float32 f32Right,
										PajaTypes::float32 f32Top, PajaTypes::float32 f32Bottom,
										PajaTypes::float32 f32ZNear = -1, PajaTypes::float32 f32ZFar = 1 );

		//! Sets identity viewport and projection matrix.
		/*!	This methods set the viewport to the maximum rendering area, and sets all the matrices
			(projection, world, view) to identity matrices. This method should be used to set the viewport if 
			already transformed vertices are used for rendering.

			Use client_to_layout(), layout_to_client(), delta_client_to_layout(), and delta_layout_to_client() to convert
			your vertices. Also notice that Demopaja System assumes that the origo of the rendering are is lower left
			and in DX the origo is in upper left corner.

			Example:
			\code
			Vector2C	rVertex;
			rVertex = ....;

			rVertex = pViewport->layout_to_client( rVertex );			// Convert from layout to pixel coordinates
			rVertex[1] = (pViewport->get_height() - 1) - rVertex[1];	// Swap origo.
			\endcode
		*/
		virtual void				set_identity();


		// Hmm... should these also do the origo change too????

		//! Converts positions in screen pixels to the layout coordinate system.
		virtual PajaTypes::Vector2C	client_to_layout( const PajaTypes::Vector2C& rVec );
		//! Converts positions in layout coordinate system uints to the screen pixels.
		virtual PajaTypes::Vector2C	layout_to_client( const PajaTypes::Vector2C& rVec );
		//! Converts delta values of screen pixels to the layout coordinate system.
		virtual PajaTypes::Vector2C	delta_client_to_layout( const PajaTypes::Vector2C& rVec );
		//! Converts delta values layout coordinate system uints to the screen pixels.
		virtual PajaTypes::Vector2C	delta_layout_to_client( const PajaTypes::Vector2C& rVec );

		//! Returns the viewport (visible are of the demo).
		virtual const PajaTypes::BBox2C&	get_viewport();
		//! Returns the layout (rendering are of the demo).
		virtual const PajaTypes::BBox2C&	get_layout();
		//! Returns the width of the screen in pixels.
		virtual PajaTypes::int32			get_width();
		//! Returns the height of the screen in pixels.
		virtual PajaTypes::int32			get_height();

		//! Sets the dimension of the OpenGL rendering are in pixels (used internally).
		virtual void				set_dimension( PajaTypes::int32 i32PosX, PajaTypes::int32 i32PosY, PajaTypes::int32 i32Width, PajaTypes::int32 i32Height );
		//! Sets the viewport (used internally).
		virtual void				set_viewport( const PajaTypes::BBox2C& rViewport );
		//! Sets the layout (used internally).
		virtual void				set_layout( const PajaTypes::BBox2C& rLayout );

	protected:
		//! Default constructor (used internally).
		DX8ViewportC();
		DX8ViewportC( DX8DeviceC* pDevice );
		//! Default destructor.
		virtual ~DX8ViewportC();

	private:
		//! Calculates new constants for layout and client mappings.
		void						recalc_mapping();

		PajaTypes::BBox2C	m_rViewport;			// The viewport size in paja (include pan and zoom).
		PajaTypes::BBox2C	m_rLayout;				// Layout bbox.
		PajaTypes::int32	m_i32Width;				// Actual screen size in pixels.
		PajaTypes::int32	m_i32Height;
		PajaTypes::int32	m_i32PosX;				// Position of lower left corner in pixels.
		PajaTypes::int32	m_i32PosY;
		PajaTypes::float64	m_f64LayoutAspectX;		// Conversion variables.
		PajaTypes::float64	m_f64LayoutAspectY;
		PajaTypes::float64	m_f64ClientAspectX;
		PajaTypes::float64	m_f64ClientAspectY;
		DX8DeviceC*			m_pDevice;
	};

};

#endif // __DX8ViewportC_H__

