///////////////////////////////////////////////////////////////////////////////
//
// File   : Asura_PSP_StencilBufferManager.h
// Author : Catalin Arsenescu
// Date   : 01-March-2007
//
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif   // ifdef ASURA_USE_PRAGMA_ONCE

#ifndef __CLASS_ASURA_PSP_STENCIL_BUFFER_MANAGER__
#define __CLASS_ASURA_PSP_STENCIL_BUFFER_MANAGER__

enum ASURA_PSP_STENCIL_OPERATION
{
	ASURA_PSP_STENCIL_OPERATION_KEEP = 0,		//!< Do not add to the stencil bufffer
	ASURA_PSP_STENCIL_OPERATION_ZERO,			//!< Clear the stencil buffer value to zero
	ASURA_PSP_STENCIL_OPERATION_REPLACE,		//!< Chancge the stencil buffer value with the reference value
	ASURA_PSP_STENCIL_OPERATION_INVERT,			//!< Invert the stencil buffer value
	ASURA_PSP_STENCIL_OPERATION_INCREMENT,		//!< Increment stencil buffer value by one
	ASURA_PSP_STENCIL_OPERATION_DECREMENT,		//!< Decremnet stencil buffer value by one
	ASURA_PSP_NUM_STENCIL_OPERATIONS			//!< Detect the last object in the enum for creating an assert
};

enum ASURA_PSP_STENCIL_FUNCTION
{
	ASURA_PSP_STENCIL_FUNCTION_NEVER = 0,		//!< Do not draw any pixels
	ASURA_PSP_STENCIL_FUNCTION_ALWAYS,			//!< Draw all the pixels
	ASURA_PSP_STENCIL_FUNCTION_EQUAL,			//!< If the reference value equals stencil value draw the pixel
	ASURA_PSP_STENCIL_FUNCTION_NOT_EQUAL,		//!< If the reference value is not equal with the stencil value draw the pixel
	ASURA_PSP_STENCIL_FUNCTION_LESS,			//!< If the reference value is less that the stencil value draw the pixel
	ASURA_PSP_STENCIL_FUNCTION_LESS_EQUAL,		//!< If the reference value is less or equal with the stencil value draw the pixel
	ASURA_PSP_STENCIL_FUNCTION_GREATER,			//!< If the reference value is greater that the stencil value draw the pixel
	ASURA_PSP_STENCIL_FUNCTION_GREATER_EQUAL,	//!< If the reference value greater or equal with the stencil value draw the pixel
	ASURA_PSP_NUM_STENCIL_FUNCTIONS				//!< Detect the last object in the enum for creating an assert
};

class Asura_PSP_StencilBufferManager
{
public:
//Public functions
	static	void	SetStencilOperation		(ASURA_PSP_STENCIL_OPERATION	eStencilFailOperation,
											 ASURA_PSP_STENCIL_OPERATION	eZTestFailOperation,
											 ASURA_PSP_STENCIL_OPERATION	eZTestPassOperation);

	static	void	SetStencilFunction		(ASURA_PSP_STENCIL_FUNCTION		eFunction,
											 u_char							ucReferenceValue,
											 u_char							ucMaskValue);

	static	void	SetStencilEnabled		(bool							bEnabled);

	static	void	ClearStencilBuffer		(void);
	/*!
	Description:
		This function set the default value to clear the stencil buffer.
		After that the first time you call Clear or ClearStencilBuffer the stencil buffer will use this value.
		The number of bits for the stencil buffer depends on the format of the drawing buffer according:
		SCEGU_PF8888 -> 8 bits (0...255)
		SCEGU_PF4444 -> 4 bits (0... 15)
		SCEGU_PF5551 -> 1 bit  (0, 1)
		SCEGU_PF5650 -> None

	TO DO:
		Check the display buffer format and make an assert if we set a wrong value for clearing the buffer
	*/
	static	void	SetStencilBufferClearBits (u_char						ucDefaultClearBits);

private:
// Private constructor and destructor
	Asura_PSP_StencilBufferManager(void);
	~Asura_PSP_StencilBufferManager(void);

// Private static member
	static	ASURA_PSP_STENCIL_OPERATION		s_eStencilOperationStencilTestFail;
	static	ASURA_PSP_STENCIL_OPERATION		s_eStencilOperationZTestFail;
	static	ASURA_PSP_STENCIL_OPERATION		s_eStencilOperationZTestPass;

	static	ASURA_PSP_STENCIL_FUNCTION		s_eStencilFunction;
	static	u_char							s_ucStencilReferenceValue;			//!< Reference value to be used for comparison
	static	u_char							s_ucStencilMaskValue;				//!< Mask the stencil ( or reference? ) value
	
	static	u_char							s_ucDefaultStencilClearBits;		//!< The defaul stencil buffer clear bits

	static	bool							s_bStencilEnabled;					//!< true if we must test the stencil buffer
	static	bool							s_bUpdateStencilOperation;			//!< true if we must update the stencil operation
	static	bool							s_bUpdateStencilFunction;			//!< true if we must update the stencil function

// Private static functions
	static	void	UpdateStencilOperation	(void);
	static	void	UpdateStencilFunction	(void);
};

#endif	// __CLASS_ASURA_PSP_STENCIL__
