#ifndef __WON_CDKEY_H__
#define __WON_CDKEY_H__
#include "WonCDKey/WONShared.h"

#include "WONCommon/ByteBuffer.h"
#include "WONCommon/RegKey.h"
#include "WONCrypt/Blowfish.h"
#include <string>

namespace WONAPI
{

///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
class CDKey
{
protected:
	std::string				mProduct;     // Product string
	ByteBufferPtr			mKey;         // Key value
	bool					mIsValid;

	static const char*		mCDKeyPath;

public:
	CDKey();
	explicit CDKey(const std::string& theProduct);	

	// Initialization
	bool Init(const std::string& theKey); 	// CVCN-CVCN-CVCN-CVCN-NNNN (dashes are optional)
	bool InitEncrypted(const void *theEncryptedKey, unsigned long theEncryptLen); // (init from encrypted data generated by GetEncrypted())
	bool InitRaw(const void* theRawKey); // (init from raw form)

	// Key access
	std::string GetString() const; // string version of the key
	const ByteBuffer* GetRaw() const { return mKey; } // raw 8 byte format
	ByteBufferPtr GetEncrypted() const; // encrypted version

	// Product string 
	void SetProductString(const std::string &theProductString); // invalidates the current key
	const std::string& GetProductString() const { return mProduct; }
	
	static DWORD GetMachineId(bool *success = NULL); // get unique machine id for encrypting

	// Validity
	bool IsValid() const { return mIsValid; }
	void Invalidate();
	bool IsBeta() const;
	bool IsForceCheck() const;

	// Storage
	bool SaveToRegistry(RegKeyRoot theRoot = REGKEY_LOCAL_MACHINE, const char* thePath = mCDKeyPath); 
	bool LoadFromRegistry(RegKeyRoot theRoot = REGKEY_LOCAL_MACHINE, const char* thePath = mCDKeyPath);
	void ClearFromRegistry(RegKeyRoot theRoot = REGKEY_LOCAL_MACHINE, const char* thePath = mCDKeyPath);
	bool SaveToFile(const std::string &theFileName);
	bool LoadFromFile(const std::string &theFileName);

protected:
	unsigned char LightValidityCheck() const;
	bool CalcKeyFromBuffer(const char *theBuf);
	void GetSymmetricKey(Blowfish &theSymKey, bool useNewMethod = true) const;
	virtual void NotifyUsedOldMethodToDecrypt() { }
	virtual bool GetUseNewEncryptMethod() const { return true; }
};


}; // namespace WONAPI

#endif
