///////////////////////////////////////////////////////////////////////////////
/// @file dePlugins_priv.hpp
///
/// @brief private plugin header
///
/// @author Lightning
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Jun 2003
/// @author Lightning
/// @remarks Creation
///
///////////////////////////////////////////////////////////////////////////////

#ifndef DE_PLUGIN_PRIV_HPP
#define DE_PLUGIN_PRIV_HPP

#include "deGlobalTypes.hpp"
#include "deByteOrder.hpp"
#include "dePlugins.hpp"

//-------------------------------------------
// Classes Declared
//-------------------------------------------
class IdePlugin;
class IdePluginTwofish;
class IdePluginRijndael;
class IdePluginZLib;

//the base class for plugins
class dePlugin
{
	protected:
		dePlugin();
		virtual ~dePlugin();
		
	public:
		//get the interface for a class
		void* GetInterface(IdePlugin::interface_t i);

		//release a plugin
		int Release();

		//the basic interface functions for the data manipulation
		//buffer/length = input
		//newbuffer/newlength = new output, newlength is set to the length of the new buffer
		//it is updated to the actual written length
		virtual deBoolean EncodeData(void *Buffer, DWORD Length, void *NewBuffer, DWORD *NewLength) = 0;
		virtual deBoolean DecodeData(void *Buffer, DWORD Length, void *NewBuffer, DWORD *NewLength) = 0;

		//get the maximum size needed for a buffer
		virtual DWORD MaxEncodeLength(DWORD Length) = 0;
		virtual DWORD MaxDecodeLength(void *Buffer) = 0;

		//other functions are likely to exist to set individual settings for a plugin
};

class dePluginTwofish : public dePlugin, public IdePluginTwofish
{
	public:
		//constructor/destructor
		dePluginTwofish();
		~dePluginTwofish();

		//get the interface for a class
		void* GetInterface(IdePlugin::interface_t i);

		//release a plugin
		int Release();

		//the actual functions that do the work
		deBoolean EncodeData(void *Buffer, DWORD Length, void *NewBuffer, DWORD *NewLength);
		deBoolean DecodeData(void *Buffer, DWORD Length, void *NewBuffer, DWORD *NewLength);

		//get the maximum size needed for a buffer
		DWORD MaxEncodeLength(DWORD Length);
		DWORD MaxDecodeLength(void *Buffer);

		//different settings that can be set
		deBoolean SetKey(void *KeyBuffer, long Bitsize);	//what key to use
		deBoolean SetIV(void *IVBuffer, long Length);		//what IV to use (used on CBC and CFB1)
		deBoolean SetMode(Mode CipherMode);					//the type of encryption
		deBoolean SetRounds(int NumberRounds);				//number of rounds to do

	private:
		//struct is the size of a block for twofish, this is to allow for encryption
		//of the header without adding size
		typedef struct TwofishHeader
		{
			DWORD	ID;				//ID of the twofish data
			DWORD	OriginalSize;	//size of the original data
		} TwofishHeader;

		DWORD		priv_Key[8];	//stored key to use
		DWORD		priv_IV[4];		//stored IV to use
		int			priv_Rounds;	//number of rounds to do
		int			priv_KeySize;	//number of bits for the key
		Mode		priv_Cipher;	//type of encryption/decryption to do
};

class dePluginRijndael : public dePlugin, public IdePluginRijndael
{
	public:

		//constructor/destructor
		dePluginRijndael();
		~dePluginRijndael();

		//get the interface for a class
		void* GetInterface(IdePlugin::interface_t i);

		//release a plugin
		int Release();

		//the actual functions that do the work
		deBoolean EncodeData(void *Buffer, DWORD Length, void *NewBuffer, DWORD *NewLength);
		deBoolean DecodeData(void *Buffer, DWORD Length, void *NewBuffer, DWORD *NewLength);

		//get the maximum size needed for a buffer
		DWORD MaxEncodeLength(DWORD Length);
		DWORD MaxDecodeLength(void *Buffer);

		//different settings that can be set
		deBoolean SetKey(void *KeyBuffer, long Bitsize);	//what key to use
		deBoolean SetIV(void *IVBuffer, long Blocksize);	//IV to use

	private:
		typedef struct RijndaelHeader
		{
			DWORD	ID;				//ID of the rijndael data
			DWORD	OriginalSize;	//size of the original data
		} RijndaelHeader;

		//internal length verify function
		deBoolean ValidSize(int Size);

		DWORD		priv_Key[8];	//stored key to use
		DWORD		priv_IV[4];		//IV data
		int			priv_KeySize;	//number of bytes for the key
};

class dePluginZLib : public dePlugin, public IdePluginZLib
{
	public:
		//constructor/destructor
		dePluginZLib();
		~dePluginZLib();

		//get the interface for a class
		void* GetInterface(IdePlugin::interface_t i);

		//release a plugin
		int Release();

		//the actual functions that do the work
		deBoolean EncodeData(void *Buffer, DWORD Length, void *NewBuffer, DWORD *NewLength);
		deBoolean DecodeData(void *Buffer, DWORD Length, void *NewBuffer, DWORD *NewLength);

		//get the maximum size needed for a buffer
		DWORD MaxEncodeLength(DWORD Length);
		DWORD MaxDecodeLength(void *Buffer);

		//different settings that can be set
		deBoolean SetType(DataType Type);					//the type of data to compress
		deBoolean SetCompressAmount(long Amount);			//how much to compress it (0-9)

	private:
		typedef struct ZLibHeader
		{
			DWORD	ID;				//ID of the zlib data
			DWORD	OriginalSize;	//size of the original data
		} ZLibHeader;

		DataType	priv_DataType;				//type of data we are compressing
		long		priv_CompressAmount;		//how much to compress by (0 to 9)	
};

class dePluginSHA1 : public dePlugin, public IdePluginSHA1
{
	public:

		//constructor/destructor
		dePluginSHA1();
		~dePluginSHA1();

		//get the interface for a class
		void* GetInterface(IdePlugin::interface_t i);

		//release a plugin
		int Release();

		//the actual functions that do the work
		deBoolean EncodeData(void *Buffer, DWORD Length, void *NewBuffer, DWORD *NewLength);
		deBoolean DecodeData(void *Buffer, DWORD Length, void *NewBuffer, DWORD *NewLength);

		//get the maximum size needed for a buffer
		DWORD MaxEncodeLength(DWORD Length);
		DWORD MaxDecodeLength(void *Buffer);

	private:
		typedef struct SHA1Header
		{
			DWORD	ID;				//ID of the sha1 data
			DWORD	OriginalSize;	//size of the original data
			BYTE	SHA1Hash[20];	//sha1 hash
		} SHA1Header;

		//internal length verify function
		deBoolean ValidSize(int Size);
};

#endif