#ifndef __CP_Tran_h
#define __CP_Tran_h

#include "common.h"
#ifndef uint16_t
 #include "typedfs.h"
#endif


/// Parent codepage translator that maintains list of translators.
class CpTranslator
	{
private:static CpTranslator *First;
	CpTranslator *Previous;
	CpTranslator *Next;

public: explicit CpTranslator(const char *name);
	~CpTranslator();

	const char *Name;

	virtual uint16_t operator[](const uint16_t n) const {return(n);}
	virtual uint16_t number(void) const {return(0);}
        static CpTranslator *getFirst(void) {return(First);};
        CpTranslator *getNext(void) {return(Next);};

	friend CpTranslator *GetTranslator(const char *Name);
	};
CpTranslator *GetTranslator(const char *Name);	


/// Codepage translator that converts to wchar.
class WCpTranslator: public CpTranslator
	{
public: WCpTranslator(const char *name, uint16_t number, const uint16_t *trn);

	uint16_t Number;
	const uint16_t *Trn;

	virtual uint16_t operator[](const uint16_t n) const {if(n>=Number) return(0); return(Trn[n]);}
	uint16_t number(void) const {return(Number);}
	};


/// Codepage translator that converts to 8bit char.
class BCpTranslator: public CpTranslator
	{
public: BCpTranslator(const char *name, uint16_t number, const uint8_t *trn);

	uint16_t Number;
	const uint8_t *Trn;

	virtual uint16_t operator[](const uint16_t n) const {if(n>=Number) return(0); return(Trn[n]);}
	uint16_t number(void) const {return(Number);}
	};        

/// Codepage translator that converts to wchar where the space is not contiguous.
class WSparseCpTranslator: public CpTranslator
	{
public: WSparseCpTranslator(const char *name, uint8_t banks, const uint16_t *const *trn_bank);

	uint8_t Banks;
	const uint16_t * const* Trn_bank;

	virtual uint16_t operator[](const uint16_t n) const;
	uint16_t number(void) const {return(256*Banks);}
	};


/// Codepage translator that converts to wchar where the space is not contiguous.
class BSparseCpTranslator: public CpTranslator
	{
public: BSparseCpTranslator(const char *name, uint8_t banks, const uint8_t *const *trn_bank);

	uint8_t Banks;
	const uint8_t * const* Trn_bank;

	virtual uint16_t operator[](const uint16_t n) const;
	uint16_t number(void) const {return(256*Banks);}
	};


#endif