#include"CString.h"
#include"macro.h"

#include<stdio.h>

namespace Maid
{
	namespace CString
	{
		//!	指定した1byteがSJISかどうか判断する
		/*!	
			@retval true SJISである
			@retval false SJISでない
		*/
		bool IsSJIS1( char x )
		{
			return ((unsigned char)((x^0x20)-0xA1)<=0x3B);
		}

		//!	SJIS -> MJIS への変換
		/*!	
			@return MJISになった文字列
		*/
		mstring ConvertSJIStoMAID( const MySTL::string& str )
		{
			mstring ret;
			
			ret.reserve( str.length() );

			for( int i=0; i<(int)str.length(); ++i )
			{
				const char c = str[i];
				unt32 v;

				if( IsSJIS1(c) )
				{
					unt32 a = unt32(c)&0xFF;
					unt32 b = unt32(str[i+1])&0xFF;

					v = (a<<8) | b;
					++i;
				}else
				{
					v = unt32(c)&0xFF;
				}

				ret.push_back(v);
			}

			return ret;
		}

		unt32 ConvertCharaMAIDtoSJIS( const MySTL::string& str )
		{
			if( str.empty() ) { return 0; }
			const char c = str[0];
			unt32 v;

			if( IsSJIS1(c) )
			{
				unt32 a = unt32(c)&0xFF;
				unt32 b = unt32(str[1])&0xFF;

				v = (a<<8) | b;
			}else
			{
				v = unt32(c)&0xFF;
			}

			return v;
		}

		//!	MJIS -> SJIS への変換
		/*!	
			@return SJISになった文字列
		*/
		MySTL::string ConvertMAIDtoSJIS( const mstring& str )
		{
			MySTL::string ret;
			ret.reserve( str.length() );

			for( int i=0; i<(int)str.length(); ++i )
			{
				const unt32 c = str[i];

				ret += ConvertMAIDtoSJIS(c);
			}
			return ret;
		}



		MySTL::string ConvertMAIDtoSJIS( unt32 c )
		{
			MySTL::string ret;
			if( IsHankaku(c) )
			{
				ret.push_back((char)(c));
			}
			ef( IsGaizi(c) )
			{
				//	外字の場合は表示できないのでバグっぽくしておく
				ret += "■";
			}
			else
			{
				ret.push_back((c>>8)&0xFF);
				ret.push_back(c&0xFF);
			}

			return ret;
		}

		//!	半角文字か？
		/*!
		 	@param	c	[i ]	調べる文字
		 	@return	半角なら true
		 */
		bool  IsHankaku( unt32 c )
		{
			return c <= 0xFF;
		}

		//!	外字か？
		/*!
		 	@param	c	[i ]	調べる文字
		 	@return	半角なら true
		 */
		bool  IsGaizi( unt32 c )
		{
			return IsBitOn(c,31);
		}

		unt32 MakeGaizi( unt32 c )
		{
			return BitOn( c, 31 );
		}

		int		CountByte( const mstring& str )
		{
			int ret = 0;
			for( int i=0; i<(int)str.length(); ++i )
			{
				const unt32 a = str[i];

				if( IsHankaku(a) ){ ret += 1;	}
				else			  { ret += 2;	}
			}

			return ret;
		}

		//!	すべて小文字化する
		/*!
		 	@param	str	[i ]	小文字化する文字列
		 	@return	小文字化された文字列
		 */
		mstring ToLower( const mstring& str )
		{
			mstring ret;
			ret.resize( str.length() );
			for( int i=0; i<(int)str.length(); ++i )
			{
				const unt32 a = str[i];

				if( IsHankaku(a) ){ ret[i] = ::tolower((char)a);	}
				else			  { ret[i] = a;	}
			}

			return ret;
		}


		//!	パスからディレクトリ名を割り出す
		/*!
		 	"hoge/huga" だったら "hoge" が返ります ( / は付きません )
		 
		 	@param	Path	[i ]	抜き出したいディレクトリ名
		 
		 	@return	ディレクトリ名
		 */
		mstring GetDirectory( const mstring& Path )
		{
			//	パス名を後ろから見ていって、 / or \ が見つかったら切り取って終了
			for( int i=int(Path.length())-1; i>=0; --i )
			{
				const unt32 c = Path[i];

				if( c=='\\' || c=='/' ) 
				{
					return Path.substr(0,i);
				}
			}

			return mstring();
		}


		//!	パスから拡張子を割り出す
		/*!
		 	"hoge/huga.bmp" だったら "bmp" が返ります ( . は付きません )
		 	"hoge/huga" だったら "" が返ります ( 拡張子なしと判定します )
		 
		 	@param	Path	[i ]	抜き出したいディレクトリ名
		 
		 	@return	拡張子
		 */
		mstring GetExtension( const mstring& Path )
		{
			for( int i=0; i<(int)Path.length(); ++i )
			{
				const unt32 a = Path[i];

				if( a == '.'  )
				{
					return Path.substr(i+1);
				}
			}

			return mstring();
		}




		//!	パスからファイル名を割り出す
		/*!
		 	"hoge/huga" だったら "huga" が返ります
		 
		 	@param	Path	[i ]	抜き出したいディレクトリ名
		 
		 	@return	ファイル名
		 */
		mstring GetFileName( const mstring& Path )
		{
			//	パス名を後ろから見ていって、 / or \ が見つかったら切り取って終了
			for( int i=int(Path.length())-1; i>=0; --i )
			{
				const wchar_t c = Path[i];

				if( c=='\\' || c=='/' ) 
				{
					return Path.substr(i+1);
				}
			}

			return Path;
		}

		int   AtoI( const mstring& str )
		{
			return ::atoi( ConvertMAIDtoSJIS(str).c_str() );
		}

		float AtoF( const mstring& str )
		{
			return (float)::atof( ConvertMAIDtoSJIS(str).c_str() );
		}

		mstring ItoA( int value )
		{
			char buf[256];
			::sprintf_s( buf, "%d", value );

			return ConvertSJIStoMAID(buf);
		}

		mstring FtoA( float value )
		{
			char buf[256];
			::sprintf_s( buf, "%f", value );

			return ConvertSJIStoMAID(buf);
		}
	}


}
