#include <DirectWindow.h>
#include "CMameDisplay.h"


//
//reversed order color struct
//used for writing to screen
//
struct bgr_color
	{
	uint8 blue;
	uint8 green;
	uint8 red;
	uint8 alpha;
	};

struct infobits
	{
	
	uint8 needsx;
	uint8 needsy;
	uint32 offsetx;
	uint32 offsety;
	uint32 rowsize;
	uint32 height; 
	uint8 *p;
	};

class Benaphore
{
public:
						Benaphore(
							const char *name = "Benaphore");
	virtual				~Benaphore();

	bool				isValid()
							{ return ( ben_sem < B_NO_ERROR ? false : true ); }

	inline void				Lock();
	inline void				Unlock();

private:
	sem_id	ben_sem;
	long	atom;
};

class CMameDirectWin : public BDirectWindow, public CMameDisplay {
public:
					CMameDirectWin(
						status_t			*outRet,
						BRect				inFrame,
						int					inColorDepth);
	virtual			~CMameDirectWin();
						
	virtual void	DirectConnected(
						direct_buffer_info	*inInfo);
	virtual	void	ShutDown();

	virtual void	SetPenAtIdx(
						int32				inIdx,
						uint8				inRed,
						uint8				inGreen,
						uint8				inBlue);
	virtual void	SetPalette();
	virtual void	Update8BitDirect(
						uint8				*inSource,
						int32				inLineNumber,
						int32				inScreenWidth,
						int32				inVisibleWidth,
						bool				inDouble);
						
						
	virtual void	Update8BitSingleDirect(
						uint8				*inSource,
						int32				inLineNumber,
						int32				inScreenWidth,
						int32				inVisibleWidth);
	virtual void	Update8BitDoubleDirect(
						uint8				*inSource,
						int32				inLineNumber,
						int32				inScreenWidth,
						int32				inVisibleWidth);
	virtual void	Update8BitDirectWScan(
						uint8				*inSource,
						int32				inLineNumber,
						int32				inScreenWidth,
						int32				inVisibleWidth);
    
private:
	void			SetInfo(
						direct_buffer_info	*inInfo);
	bool			QuitRequested();

	Benaphore		mLocker;
	bool			mValid;
	
	//
	//store all the different versions of mame's palette
	//for BDirect window use
	//
	uchar palette8[256];
	uint16 palette15[256];
	uint16 palette16[256];
	bgr_color palette32[256];
	int depth;

    BRect		mRequestedSize;
    uint8         *fBits; 
    int32         fRowBytes; 
    color_space      fFormat; 
    clipping_rect   fBounds; 
	uint32         fNumClipRects; 
    clipping_rect   *fClipList; 
    infobits * fInfoList;
};

inline void
Benaphore::Lock()
{
	if (atomic_add(&atom, 1) > 0)
		acquire_sem(ben_sem);
}

inline void
Benaphore::Unlock()
{
	if (atomic_add(&atom, -1) > 1)
		release_sem( ben_sem );
}

