/***************************************************************************/
/** @file       util.h
    @brief      
    @author     shom
****************************************************************************/

#pragma once

///--	delete, Release
template < class T >
void my_safe_del( T*& p )
{
    if( p )
    {
        delete p;
        p	= NULL;
    }
}

template < class T >
void my_safe_del_array( T*& p )
{
    if( p )
    {
        delete[] p;
        p	= NULL;
    }
}

template < class T >
void my_safe_rel( T*& p )
{
    if( p )
    {
        p->Release();
        p	= NULL;
    }
}
///--

///--	"zero-set"
extern void my_memzero( void* dst, u32 size );
///--

///--	"color"
extern u32	set_color_argb( u32 a, u32 r = 0xff, u32 g = 0xff, u32 b = 0xff );
extern u32	set_color_rgba( u32 r, u32 g, u32 b, u32 a = 0xff );

extern u32	switch_color_a( u32 color, u32 a );
extern u32	switch_color_r( u32 color, u32 r );
extern u32	switch_color_g( u32 color, u32 g );
extern u32	switch_color_b( u32 color, u32 b );

extern u32	add_color_a( u32 color, u32 a );
extern u32	add_color_r( u32 color, u32 r );
extern u32	add_color_g( u32 color, u32 g );
extern u32	add_color_b( u32 color, u32 b );

extern u32	sub_color_a( u32 color, u32 a );
extern u32	sub_color_r( u32 color, u32 r );
extern u32	sub_color_g( u32 color, u32 g );
extern u32	sub_color_b( u32 color, u32 b );

extern u32	get_color_a( u32 color );
extern u32	get_color_r( u32 color );
extern u32	get_color_g( u32 color );
extern u32	get_color_b( u32 color );


class color_t
{
public:
	color_t( u32 in_color );
	color_t( u32 in_r, u32 in_g, u32 in_b, u32 in_a = 0xff );
	color_t( f32 in_r, f32 in_g, f32 in_b, f32 in_a = 1.f );

	void set( u32 in_r, u32 in_g, u32 in_b, u32 in_a = 0xff );
	
	void switch_r( u32 in_r );
	void switch_g( u32 in_g );
	void switch_b( u32 in_b );
	void switch_a( u32 in_a );
	
	void add_r( u32 in_r );
	void add_g( u32 in_g );
	void add_b( u32 in_b );
	void add_a( u32 in_a );
	
	void sub_r( u32 in_r );
	void sub_g( u32 in_g );
	void sub_b( u32 in_b );
	void sub_a( u32 in_a );

	u32 get_raw()	const;
	u32	get_r()	    const;
	u32	get_g()	    const;
	u32	get_b()	    const;
	u32	get_a()	    const;

private:
	u32	m_color;
};
///--

///--	"time"
extern u32 get_time();
///--

///--	"convert unit"
extern f32 dot_to_meter( f32 dot );
extern f32 meter_to_dot( f32 meter );

class meter_t
{
public:
	meter_t();
};
///--

///--	"char-code"
namespace util_chara_code
{
	extern void ConvUtf8toSJis( ct char* ct in_pSrc, TCHAR* out_pDst, int* out_pSize );
}
///--

///--	"enum definition"
//need to define ENUM_KIND 

#define DEF_ENUM_BEGIN()			\
									\
enum BOOST_PP_CAT( e, ENUM_KIND )	\
{

#define DEF_ENUM( _name )						\
												\
	BOOST_PP_CAT( e, ENUM_KIND )##_##_name##,

#define DEF_ENUM_END()										\
															\
	BOOST_PP_CAT( eNof_, ENUM_KIND ),						\
	BOOST_PP_CAT( e, ENUM_KIND )##_Invalid = U32_INVALID,	\
};
///--

///--	"timer"
class CTimer
{
public:
	CTimer() : m_uTime( U32_INVALID ), m_bPause( FALSE ) {}

	void	Update( u32 in_uTimeProceed )
	{
		if( IsProceed() && !IsPause() )
		{
			m_uTime += in_uTimeProceed;
		}
	}

	void	Start()		{ m_uTime = 0; }
	void	Stop()		{ m_uTime = U32_INVALID; }
	void	Reset()		{ if( IsProceed() ){ m_uTime = 0; } }
	void	Pause()		{ m_bPause = TRUE; }
	void	Resume()	{ m_bPause = FALSE; }

	u32		GetTime()	const	{ return m_uTime; }
	b32		IsProceed()	const	{ return ( m_uTime != U32_INVALID ); }
	b32		IsPause()	const	{ return m_bPause; }

private:
	u32	m_uTime;
	b32	m_bPause;
};
///--
