#ifndef __MY_SMALL_OBJ_H__
#define __MY_SMALL_OBJ_H__

#ifdef _USE_RGE_
	#include "../../rge/Rune/Core/Stream/RuStreamIO.h"
#else
	#include "MineLib/RuStreamIO.h"
#endif

#include "MyBaseInc.h"
#include "RecycleBin/recyclebin.h"
#include <deque>
#include <queue>

#pragma warning (disable:4949)

#pragma unmanaged

using		namespace std;
//---------------------------------------------------------------------------
///修改priority_queue 增加一個Clear的功能
template< class T, class Container = vector<T> , class Compare = less<typename Container::value_type > >
class MyP_Queue : public priority_queue<T,Container,Compare>
{
public:
    void clear(){c.clear();};

};

//---------------------------------------------------------------------------
//字串與ID 一對一的 Map
class Map_StrAndID
{
#define _Max_Number_    10000

    vector< string >    _IDToStrList;
    map< string , int > _StrToIDList;
public:

    bool    Add     ( char*  Str , int ID );
    bool    Del     ( char*  Str );
    bool    Del     ( int    ID  );
    int     GetID   ( char*  Str );
    char*   GetStr  ( int    ID  );

};
//---------------------------------------------------------------------------
/*
//要使用的Temp 基本組合
struct MyVector_BaseType
{
int  ID;
virtual void Init();     
};
*/
template < class Temp >
class MyVector
{
    RecycleBin< Temp >      _Bin;
    vector<Temp*>           _List;
    set<Temp*>              _Set;

public:

    int     size( );
    int     MaxNum( );
    Temp*   operator [] ( const int ID ) const;
    Temp*   New( unsigned ID );
    bool    Del( unsigned ID );

    int     Push_back( Temp* );
    Temp*   Pop_back( );
    Temp*   Back( );
    Temp*   Begin( );

    //Flag = true 重設循序取資料資訊(使用前一定要重設)
    //Flag = false 循序取資料
    Temp*	GetData( bool ResetFlag = false );    
};
//-------------------------------------------------------------------------------------
template<class Temp>
int     MyVector<Temp>::size( )
{
    return (int)_Set.size();
};
//-------------------------------------------------------------------------------------
template<class Temp>
Temp*    MyVector<Temp>::operator [] ( const int ID ) const
{
    if( _List.size() <= (unsigned) ID )
        return NULL;

    return _List[ ID ];
};
//-------------------------------------------------------------------------------------
template<class Temp>
Temp*    MyVector<Temp>::New( unsigned ID )
{
    if( ID > _Max_Number_ )
        return NULL;

    while( _List.size() <= ID )
    {
        _List.push_back( NULL  );
    }


	if( _List[ ID ] != NULL )
		return NULL;

    Temp* Ret =  _Bin.NewObj( );

    if( Ret == NULL )
        return NULL;

	_List[ ID ] = Ret;

    Ret->Init();
    Ret->ID = ID;

    _Set.insert( Ret );
    return Ret;
};
//-------------------------------------------------------------------------------------
template<class Temp>
bool    MyVector<Temp>::Del( unsigned ID ) 
{
    if( _List.size() <= ID )
        return false;

    Temp* CliInfo = _List[ ID ];
    if( CliInfo == NULL )
        return false;

    _Bin.DeleteObj( CliInfo );
    _Set.erase( CliInfo );
    _List[ ID ] = NULL;
    return true;    
};
//-------------------------------------------------------------------------------------
//循序取資料
template<class Temp>
Temp*	MyVector<Temp>::GetData( bool ResetFlag )
{
    static set<Temp*>::iterator Iter ;
	if( ResetFlag == true )
    {
        Iter = _Set.begin();
        return NULL;
    }

    if( Iter == _Set.end() )
        return  NULL;

    Temp* Ret = *Iter;
    Iter++;
	
    return Ret;

};
//-------------------------------------------------------------------------------------
template<class Temp>
int	MyVector<Temp>::MaxNum( )
{
    return (int)_List.size();
}
//---------------------------------------------------------------------------
class MutilThread_CritSect
{
    CRITICAL_SECTION _CritSect;
public:
    MutilThread_CritSect()
    {
        Init();
    }
    ~MutilThread_CritSect()
    {
        DeleteCriticalSection( &_CritSect );
    };
    void Init()
    {
        InitializeCriticalSection( & _CritSect );
    }
    void Enter()
    {
		if( _CritSect.DebugInfo == NULL )
			return;
        EnterCriticalSection( &_CritSect );
    }
    void Leave()
    {
		if( _CritSect.DebugInfo == NULL )
			return;
        LeaveCriticalSection( &_CritSect );
    }
};
//--------------------------------------------------------------------------
inline MutilThread_CritSect*  g_CritSect( )
{ 
    static MutilThread_CritSect    g_Thread_CritSect; 

    return &g_Thread_CritSect;
}
//--------------------------------------------------------------------------
//計數物件
//--------------------------------------------------------------------------
template<class Temp>
class ObjectConutClass
{
    static int _ObjCount;
public:
    ObjectConutClass() { _ObjCount++; };
    virtual ~ObjectConutClass(){ _ObjCount--; };
    int ObjCount()     { return _ObjCount; }
};
//--------------------------------------------------------------------------
template<class Temp>
int ObjectConutClass<Temp>::_ObjCount = 0;
//--------------------------------------------------------------------------
//時間字串物件
//--------------------------------------------------------------------------
namespace TimeStr
{
    char* ProcessBegin();
    char* Now_Date();
    char* Now_Time();
    char* Now();  

	int	  Now_Value( );	
	char* DateTimeStr( int );
};
//--------------------------------------------------------------------------
//=====================================================================================
//劇情參數型態定義
enum	ArgValueTypeENUM
{
    EM_ValueType_Double	    = 1 ,
    EM_ValueType_Int		= 2 ,
    EM_ValueType_String	    = 3 ,
    EM_ArgValueTypeENUM_FORCE_DWORD   = 0x7fffffff, 
};
//=====================================================================================
//參數傳遞物件
//=====================================================================================
class	ArgTransferStruct
{
protected:
    map<string,string>		_Arg;						            //參數，與值	
public:
    void    Clear() { _Arg.clear(); }
    int		GetNumber	( const string Name );				        //讀取參數(數字)
    char*	GetString	( const string Name );				        //讀取參數(字串)
    void	PushValue	( const string Name , const string Value );	//資料設定
	void	PushValue	( const string Name , int	Value );		//資料設定
};
//--------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//建立刪除開檔物件
// T 為 IRuStream的演生物件
template <class T = CRuFileStream > 
class FileStreamPtr
{
    T*  _Iter;
public:
    FileStreamPtr( )
    {
        _Iter = new T;
    };
    ~FileStreamPtr( )
    {
        delete _Iter;
    };

    T* operator->()
    { return _Iter;};
};
//-------------------------------------------------------------------------------------

/*
//範例  
class CYetAnotherClass
{
private:
    InitSimple<int, 42> m_atltuae;
    ...
private:
    enum States
    {
        START, RUNNING, STOP
    };

    InitSimple<States, START> m_state;
};
*/
template <typename T, T t>
struct InitSimple
{
    InitSimple() : m_t(t) {}

    operator T&() {return m_t;}
    operator T&() const {return m_t;}

    T& AsType() {return m_t;}
    const T& AsType() const {return m_t;}

    T* operator&() {return &m_t;}
    const T* operator&() const {return &m_t;}

    T& operator=(const T& t) {return (m_t = t);}
    InitSimple(const InitSimple& rhs) {m_t = rhs.m_t;}

private:
    T m_t;
};
//--------------------------------------------------------------------------------------------------------------------
//	簡易的排序用物件資料
//--------------------------------------------------------------------------------------------------------------------
struct	BaseSortStruct
{
    int		Value;
    void*	Data;

    bool operator >  ( const BaseSortStruct& P )    
    {	return P.Value > Value;	}
    bool operator <  ( const BaseSortStruct& P )
    {	return P.Value > Value;	}
    bool operator == ( const BaseSortStruct& P )
    {	return P.Value == Value;	}

};
//----------------------------------------------------------------------------------------------------------
//template < typename T >
class BaseLinkList
{
public:
    BaseLinkList()
    {
        Next = Front = NULL;
    }

    BaseLinkList* Next;
    BaseLinkList* Front;

    void AddTo( BaseLinkList* FrontObj );
    void Del( );
};
//----------------------------------------------------------------------------------------------------------
class MyFloat
{
#define _MyFloat_SMATH_EPSILON			1.0e-4f						//1E-6f

    bool _FloatEQU ( float X , float Y )
    {
        return (((X - _MyFloat_SMATH_EPSILON) < Y) && (Y < ( X + _MyFloat_SMATH_EPSILON)));
    }

    float  _Value;
public:
    MyFloat( float V ) { _Value = V; }

    float   operator = ( const float V ) { _Value = V ; return _Value; }
    float   operator = ( const MyFloat& V ) { _Value = V._Value ; return _Value; }
    bool    operator == ( const float V ){ return _FloatEQU ( V , _Value );}
    bool    operator == ( const MyFloat& V ){ return _FloatEQU ( V._Value , _Value ); }
};
//----------------------------------------------------------------------------------------------------------
#pragma managed
#endif //__MY_SMALL_OBJ_H__