#include "Mix/Tool/Win32/Core/Path.h"
#include <shlwapi.h>

namespace Mix{ namespace Tool{ namespace Win32{ namespace Path{

	PATH_TYPE GetType( const char* pPath )
	{
		if( pPath == NULL )
		{
			return PATH_UNKNOWN;
		}

		size_t num = ::strlen( pPath );
		if( num == 0 )
		{
			return PATH_UNKNOWN;
		}
		else if( num < 3 )
		{
			return PATH_RELATIVE;
		}

		if( ( 'A' <= pPath[0] ) &&
			( 'W' >= pPath[0] ) &&
			( pPath[1] == ':' ) &&
			( ( pPath[2] == '\\' ) || ( pPath[2] == '/' ) ) )
		{
			return PATH_ABSOLUTE;
		}

		return PATH_RELATIVE;
	}

	PATH_TYPE GetType( const wchar_t* pPath )
	{
		if( pPath == NULL )
		{
			return PATH_UNKNOWN;
		}

		size_t num = ::wcslen( pPath );
		if( num == 0 )
		{
			return PATH_UNKNOWN;
		}
		else if( num < 3 )
		{
			return PATH_RELATIVE;
		}

		if( ( L'A' <= pPath[0] ) &&
			( L'W' >= pPath[0] ) &&
			( pPath[1] == L':' ) &&
			( ( pPath[2] == L'\\' ) || ( pPath[2] == L'/' ) ) )
		{
			return PATH_ABSOLUTE;
		}

		return PATH_RELATIVE;
	}

	bool GetFileNameWithoutExtension( const wchar_t* pSrc, std::wstring& name )
	{
		if( pSrc == NULL )
		{
			return false;
		}

		size_t num = ::wcslen( pSrc );
		if( num == 0 )
		{
			return false;
		}

		int dotIndex= -1;
		int index;

		for( index = ( num - 1 ); index > 0; index-- )
		{
			if( dotIndex < 0 )
			{
				if( pSrc[index] == L'.' )
				{
					dotIndex = index;
				}
			}

			if(	( pSrc[index] == L'\\' ) ||
				( pSrc[index] == L'/' ) )
			{
				break;
			}
		}

		if( ( dotIndex >= 0 ) &&
			( dotIndex < index ) )
		{
			return false;
		}

		name = pSrc;

		if( dotIndex >= 0 )
		{
			name = name.substr( index + 1, dotIndex - index - 1 );
		}
		else
		{
			name = name.substr( index + 1 );
		}

		return true;
	}

	bool GetDirectoryName( const char* pPath, std::string& name )
	{
		if( pPath == NULL )
		{
			return false;
		}

		size_t num = ::strlen( pPath );
		if( num == 0 )
		{
			return false;
		}
		else if( num < 4 )
		{
			name = pPath;
			return true;
		}

		bool bFindDot = false;
		size_t index;

		for( index = ( num - 1 ); index > 0; index-- )
		{
			if( bFindDot == false )
			{
				if( pPath[index] == '.' )
				{
					bFindDot = true;
				}
			}
			else if(	( pPath[index] == '\\' ) ||
						( pPath[index] == '/' ) )
			{
				break;
			}
		}

		if( bFindDot == false )
		{
			name = pPath;
			return true;
		}

		if( index == 0 )
		{
			return false;
		}

		name = pPath;
		name = name.substr( 0, index );

		return true;
	}

	bool GetDirectoryName( const wchar_t* pPath, std::wstring& name )
	{
		if( pPath == NULL )
		{
			return false;
		}

		size_t num = ::wcslen( pPath );
		if( num == 0 )
		{
			return false;
		}
		else if( num < 4 )
		{
			name = pPath;
			return true;
		}

		bool bFindDot = false;
		size_t index;

		for( index = ( num - 1 ); index > 0; index-- )
		{
			if( bFindDot == false )
			{
				if( pPath[index] == L'.' )
				{
					bFindDot = true;
				}
			}
			else if(	( pPath[index] == L'\\' ) ||
						( pPath[index] == L'/' ) )
			{
				break;
			}
		}

		if( bFindDot == false )
		{
			name = pPath;
			return true;
		}

		if( index == 0 )
		{
			return false;
		}

		name = pPath;
		name = name.substr( 0, index );

		return true;
	}

	bool Combine( const char* pBaseDirectory, const char* pRelativePath, std::string& output )
	{
		if( ( pBaseDirectory == NULL ) ||
			( ::strlen( pBaseDirectory ) == 0 ) ||
			( pRelativePath == NULL ) ||
			( ::strlen( pRelativePath ) == 0 ) )
		{
			return false;
		}

		char temp[MAX_PATH];

		::ZeroMemory( temp, sizeof( temp ) );

		if( ::PathCombineA( temp, pBaseDirectory, pRelativePath ) == NULL )
		{
			return false;
		}

		output = temp;

		return true;
	}

	bool Combine( const wchar_t* pBaseDirectory, const wchar_t* pRelativePath, std::wstring& output )
	{
		if( ( pBaseDirectory == NULL ) ||
			( ::wcslen( pBaseDirectory ) == 0 ) ||
			( pRelativePath == NULL ) ||
			( ::wcslen( pRelativePath ) == 0 ) )
		{
			return false;
		}

		wchar_t temp[MAX_PATH];

		::ZeroMemory( temp, sizeof( temp ) );

		if( ::PathCombineW( temp, pBaseDirectory, pRelativePath ) == NULL )
		{
			return false;
		}

		output = temp;

		return true;
	}

}}}}
