/*!
@author d金魚
@since 2004/2/4
@note
このヘッダだけでも使えるようにしたい！！
*/
#ifndef DKUTIL_MATH_UTILITY_HPP
#define DKUTIL_MATH_UTILITY_HPP

#include <dkutil/math/interface.hpp>

namespace dkutil{



inline int arg_rand(ULONG *seed){
	ansi_rand_functor<ULONG> func;
	return func(seed);
}

inline int arg_random(ULONG *seed,ULONG Max){
	return arg_rand(seed) * Max / SHRT_MAX;
}


namespace policy{

///超簡易C言語標準乱数クラス。(爆)
class ansi_rand{
	uint32 mSeed;
public:
	typedef uint32 result_type;
	typedef uint32 state_type;
	typedef uint32 seed_type;
	typedef random_functor<result_type,seed_type,ansi_rand> random_functor_type;
	typedef random_domain_functor<result_type,seed_type,ansi_rand> random_domain_functor_type;

	BOOST_STATIC_CONSTANT(result_type,rand_max = 0x7fff);
	BOOST_STATIC_CONSTANT(uint32,bit_max = 14);
	result_type getRandMax()const
	{
		return rand_max;
	}
	ansi_rand(ULONG seed = time(NULL)) : mSeed(seed){}
	const state_type &getState()const{return mSeed;}
	state_type &getState(){return mSeed;}
	void seed(uint32 l){	mSeed = l;}
	result_type rand(){
		return arg_rand((ULONG *)&mSeed);
	}
	result_type random(result_type Max_){
		random_functor_type f;
		return f(Max_,*this);
	}
	result_type random(result_type Min_,result_type Max_){
		random_domain_functor_type f;
		return f(Min_,Max_,*this);
	}
};


class xor_shift_rand
{
	DKC_XORSHIFT_RNG mEntity;
public:
	typedef uint32 result_type;
	typedef DKC_XORSHIFT_RNG state_type;
	typedef uint32 seed_type;
	typedef random_functor<result_type,seed_type,xor_shift_rand> random_functor_type;
	typedef random_domain_functor<result_type,seed_type,xor_shift_rand> random_domain_functor_type;

	///多分･･･泣
	BOOST_STATIC_CONSTANT(result_type,rand_max = UINT_MAX);
	///maybe
	BOOST_STATIC_CONSTANT(uint32,bit_max = UINT_MAX);
	uint32 getRandMax()const
	{
		return rand_max;
	}
	xor_shift_rand(){
		::dkcXorShiftRNG128DefaultInit(&mEntity);
	}
	~xor_shift_rand(){
	}
	const state_type &getState()const{return mEntity;}
	state_type &getState(){return mEntity;}
	void seed(seed_type seed){
		::dkcXorShiftRNG128Init(&mEntity,seed);
	}
	result_type rand(){
		return ::dkcXorShiftRNG128(&mEntity);
	}
	result_type random(uint32 Max_){
		random_functor_type f;
		return f(Max_,*this);
	}

	result_type random(uint32 Min_,uint32 Max_)
	{
		random_domain_functor_type f;
		return f(Min_,Max_,*this);
	}
	
};

}//end of policy namespace

typedef rng_interface<policy::xor_shift_rand> rngXorShift;
typedef rng_interface<policy::ansi_rand> rngANSI;

}//end of dkutil namespace







#endif



