
#ifndef DKUTIL_CRYPTOGRAPH_INTERFACE_HPP
#define DKUTIL_CRYPTOGRAPH_INTERFACE_HPP

#include <dkutil/memory/interface.hpp>
#include <dkutil/shared_buffer.hpp>
#include <dkutil/buffer.hpp>
namespace dkutil{

struct PasswordOption
{
	///パスワードがバイナリだったらTRUE
	bool isPasswordBinary;
	///パスワード(バイナリ)
	shared_buffer mPasswordBin;
	///パスワード(文字列)
	std::string mPassword;
	///initialize vector
	shared_buffer mIV;
};

struct CPasswordOption : public PasswordOption{
	CPasswordOption(){
		isPasswordBinary = true;

	}
	void setPassword(parm_string str){
		mPassword = str.c_str();
		isPasswordBinary = false;
	}
	void setPassword(const shared_buffer &x){
		mPasswordBin = x;
		isPasswordBinary = true;
	}
	void setInitializeVector(const shared_buffer &x){
		mIV = x;
	}

	PasswordOption &operator=(const CPasswordOption &x)
	{
		return(PasswordOption &)x;
	}
	

protected:
	bool isScranble;
	BYTE mScrambleKey;
};

class CReservePassword{
	//shared_buffer mBuff;
	byte_buffer mBuff;
	BYTE mScrambleKey;
	bool isScramble;


public:
	static void encrypt_buff(byte_buffer &x,BYTE ScrambleKey){
		BYTE *p = x.get();
		for(size_t i=0;i<x.size();i++)
		{
			p[i] = dkcEncryptByte(p[i],ScrambleKey);
		}
	}
	static void decrypt_buff(shared_buffer &x,BYTE ScrambleKey){
		BYTE *p = x.get();
		for(size_t i=0;i<x.size();i++)
		{
			p[i] = dkcDecryptByte(p[i],ScrambleKey);
		}
	}
	CReservePassword(const CPasswordOption &x,BYTE key = 0xEA){
		if(x.isPasswordBinary){
			mBuff = x.mPasswordBin;
		}else{
			mBuff.copy_string(x.mPassword);
		}
		mScrambleKey = key;
		isScramble = false;
		scramble();
	}
	//bool isValid()const	{return mBuff.isValid();}

	void scramble(){
		//size_t i;
		if(false==is_scramble())
		{
			encrypt_buff(mBuff,mScrambleKey);
			isScramble = true;
		}/*else{
			decrypt_buff(mBuff,mScrambleKey);
			isScramble = false;
		}*/
	}
	shared_buffer getPasswordBinary()const{
		shared_buffer x;
		x.copy(mBuff.get(),mBuff.size());
		dkcmNOT_ASSERT(is_scramble()==false);
		decrypt_buff(x,mScrambleKey);
		return x;
	}
	bool isString()const{
		shared_buffer x = getPasswordBinary();
		return (x.get()[x.size()] == '\0');
	}
	bool getPasswordString(std::string &dest)const{
		shared_buffer x = getPasswordBinary();
		return x.to_string(dest);

	}
	CPasswordOption getPassword()const{
		CPasswordOption x;
		std::string dest;
		if(getPasswordString(dest)){
			x.setPassword(dest);
		}else{
			x.setPassword(getPasswordBinary());
		}
		return x;
	}
	
	bool is_scramble()const{
		return isScramble;
	}

};
/*
class CCryptographEncodeStreamAction : public IStreamAction{
	IArrayProcess *mps;
public:
	BOOST_STATIC_CONSTANT(bool,is_read = false);
	CCryptographEncodeStreamAction(IArrayProcess *ps){
		mps = ps;
	}
	virtual bool action(uint8 *pd,size_t size){
		return mps->encode(pd,size);
		//return true;
	}
};
class CCryptographDecodeStreamAction : public IStreamAction{
	IArrayProcess *mps;
public:
	BOOST_STATIC_CONSTANT(bool,is_read = false);
	CCryptographDecodeStreamAction(IArrayProcess *ps){
		mps = ps;
	}
	virtual bool action(uint8 *pd,size_t size){
		return mps->decode(pd,size);
		//return true;
	}
};*/
/*
///@param T policy type
template<class T,class FS_T>
class to_stream_interface{
public:
	typedef typename T policy_type;
	typedef typename FS_T fs_type;
	to_stream_interface(){}
	~to_stream_interface(){}


	bool reset(path_string str,const PasswordOption &x,fs_type *pfs)
	{
		mP.reset(str,x);
		mpFS = pfs;
	}
	///処理
	bool action(size_t size)
	{
		mP.action(size);
	}
private:
	policy_type mP;
	fs_type *mpFS;
};

class ICryptographToStreamConverter{
public:
	///
	virtual bool reset(path_string str,const PasswordOption &x) = 0;
	///処理
	virtual bool action(size_t size) = 0;

};
*/

}//end of dkutil namespace



#endif