/*!
@file registration.hpp
@since 2004/09/08
*/
#ifndef DKUTIL_REGISTRATION_HPP
#define DKUTIL_REGISTRATION_HPP

#include <dkutil/dktl/map_ex.hpp>
#include <dkutil/dktl/adapters.hpp>
#include <dkutil/math/utility.hpp>

namespace dkutil{


template<class T,typename _PRIO_T = int>
class registration{
public:
	///priority
	typedef _PRIO_T priority_type;
	typedef T element_type;
	///登録する時はこの型を使ってください。
	typedef sptr<element_type> element_sptr_type;
	typedef dkutil::map_ex<priority_type,element_sptr_type > container_type;
	typedef typename container_type::iterator iterator;
	typedef typename container_type::const_iterator const_iterator;
	typedef typename container_type::mapped_type find_result_type;


public:

	bool empty()const{
		return mMap.empty();
	}

	registration(){}
	~registration(){
		clear();
	}
	
	
	bool regist_random(element_sptr_type ptr){
		bool flag = false;
		for(int i=0;i<100;i++){
			if(true==mMap.SetData(mARand.rand(),ptr)){
				break;
				flag = true;
			}
		}
		return flag;
	}
	bool regist(priority_type priority,element_sptr_type ptr){
		return mMap.SetData(priority,ptr);
	}
	bool erase(priority_type priority){
		return mMap.DeleteData(priority);
	}
	bool erase(element_sptr_type ptr){
		return mMap.DeleteData(ptr);
	}
	iterator begin(){
		return mMap.begin();
	}
	iterator end(){
		return mMap.end();
	}
	const_iterator begin()const{
		return mMap.begin();
	}
	const_iterator end()const{
		return mMap.end();
	}
	find_result_type &find_by_key(priority_type a){
		return mMap.GetData(a);
	}
	const find_result_type &find_by_key(const priority_type a)const{
		return mMap.GetData(a);
	}
	container_type &getContainer(){
		return mMap;
	}
	const container_type &getContaienr()const{
		return mMap;
	}
	void clear(){
		mMap.clear();
	}
private:

	container_type mMap;
	policy::ansi_rand mARand;
};


}//end of dkutil namespace



#endif
