#include "EABaseTypesPlus/path.h"

#include "EABaseTypes/string.h"

namespace EA
{
	namespace Types
	{
		namespace Path
		{
			void AppendRelative(EA::RawString& dst, const char *p1c, size_t p1l, const char* p2c)
			{
				if(p2c[0] == '/' || p2c[0] == '\\' || (p1c[0] == '.' && p1l == 1))
				{
					dst.assign(p2c);
				}
				else
				{
					dst.clear();

					dst.append(p1c);

					if(p1l != 0 && p1c[p1l - 1] != '/' && p1c[p1l - 1] != '\\')
					{
						dst.push_back('/');
					}

					dst.append(p2c);
				}
			}

			void AppendRelative(EA::RawString& dst, const EA::RawString& p1, const EA::RawString& p2)
			{
				AppendRelative(dst, p1.c_str(), p1.size(), p2.c_str());
			}
			
			void AppendRelative(EA::RawString& dst, const EA::RawString& p1, const EA::String& p2)
			{
				AppendRelative(dst, p1.c_str(), p1.size(), p2.c_str());
			}

			void AppendRelative(EA::RawString& dst, const EA::RawString& p1, const char* p2c)
			{
				AppendRelative(dst, p1.c_str(), p1.size(), p2c);
			}

			void AppendRelative(EA::RawString& dst, const char* p1c, const char* p2c)
			{
				AppendRelative(dst, p1c, strlen(p1c), p2c);
			}

			void AppendRaw(EA::RawString& dst, const char* p1c, size_t p1l, const char* p2c)
			{
				dst.clear();

				dst.append(p1c);

				if(p1l != 0)
				{
					if(p1c[p1l - 1] != '/' && p1c[p1l - 1] != '\\' && p2c[0] != '/' && p2c[0] != '\\')
					{
						dst.push_back('/');
					}
					else if((p1c[p1l - 1] == '/' || p1c[p1l - 1] == '\\') && (p2c[0] == '/' || p2c[0] == '\\'))
					{
						dst.pop_back();
					}
				}
			
				dst.append(p2c);
			}

			void AppendRaw(EA::RawString& dst, const EA::RawString& p1, const EA::RawString& p2)
			{
				AppendRaw(dst, p1.c_str(), p1.size(), p2.c_str());
			}
			
			void AppendRaw(EA::RawString& dst, const EA::RawString& p1, const EA::String& p2)
			{
				AppendRaw(dst, p1.c_str(), p1.size(), p2.c_str());
			}

			void AppendRaw(EA::RawString& dst, const EA::RawString& p1, const char* p2c)
			{
				AppendRaw(dst, p1.c_str(), p1.size(), p2c);
			}

			void AppendRaw(EA::RawString& dst, const char* p1c, const char* p2c)
			{
				AppendRaw(dst, p1c, strlen(p1c), p2c);
			}

			void GetPath(EA::RawString& dst, const EA::RawString& p)
			{
				GetPath(dst, p.c_str());
			}
			
			void GetPath(EA::RawString& dst, const EA::String& p)
			{
				GetPath(dst, p.c_str());
			}

			void GetPath(EA::RawString& dst, const char* pc)
			{
				const char* lastf = strrchr(pc, '/');
				const char* lastb = strrchr(pc, '\\');

				if(lastf > lastb)
				{
					dst.assign(pc, lastf);
				}
				else if(lastb > lastf)
				{
					dst.assign(pc, lastb);
				}
				else // lastb and lastf are equal, which means they are both NULL
				{
					dst.clear();
				}
			}

			bool IsAbsolute(const EA::RawString& p)
			{
				return IsAbsolute(p.c_str());
			}

			bool IsAbsolute(const EA::String& p)
			{
				return IsAbsolute(p.c_str());
			}

			bool IsAbsolute(const char* pc)
			{
				return pc[0] == '/' || pc[0] == '\\';
			}
		}
	}
}
