module gedo.file.path;



private import std.file;
private import std.string;

version(Windows)
{
	private import std.c.windows.windows;



	extern(Windows)
	{
		export BOOL SHGetSpecialFolderPathA(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
		private const int CSIDL_APPDATA = 26;
	}
}
else
{
	private import std.c.stdlib;
}



private enum SpecialDirectory
{
	UNKNOWN,
	LIB,
	HOME,
}



private SpecialDirectory _currentDirectory = SpecialDirectory.UNKNOWN;
private char[] _libDir = "/tmp";



public void setLibDirectory(char[] libdir)
{
	chdir(libdir);

	_libDir = getcwd();
}



public char[] toString(char[] vp)
{
	auto result = vp;

	if(vp[0 .. 5] == "$LIB/")
	{
		if(_currentDirectory != SpecialDirectory.LIB)
		{
			version(Windows)
			{
				char[MAX_PATH] buffer;

				GetModuleFileNameA(null, buffer.ptr, buffer.length);

				uint lastSeperatorPos = 0;
				foreach(i, c; buffer)
				{
					if(c == 0)
					{
						break;
					}
					else if(c == '\\')
					{
						lastSeperatorPos = i;
					}
				}

				buffer[lastSeperatorPos] = 0;

				SetCurrentDirectoryA(buffer.ptr);
			}
			else
			{
				chdir(_libDir);
			}
			_currentDirectory = SpecialDirectory.LIB;
		}

		result = `./` ~ vp[5..length];
	}
	else if(vp[0 .. 6] == "$HOME/")
	{
		if(_currentDirectory != SpecialDirectory.HOME)
		{
			version(Windows)
			{
				char[MAX_PATH] buffer;

				SHGetSpecialFolderPathA(null, buffer.ptr, CSIDL_APPDATA, false);

				SetCurrentDirectoryA(buffer.ptr);
			}
			else
			{
				if(auto sz = getenv("HOME"))
				{
					chdir(.std.string.toString(sz));
				}
				else
				{
					throw new Exception("getenv(\"HOME\") failed!");
				}
			}
			_currentDirectory = SpecialDirectory.HOME;
		}

		result = `./` ~ vp[6..length];
	}

	version(Windows)
	{
		foreach(inout c; result)
		{
			if(c == '/')
			{
				c = '\\';
			}
		}
	}

	return result;
}



public char* toStringz(char[] vp)
{
	return .std.string.toStringz(toString(vp));
}



public bool exist(char[] vp)
{
	return (.std.file.exists(toString(vp)) != 0);
}



public void[] read(char[] vp)
{
	return .std.file.read(toString(vp));
}



public void write(char[] vp, void[] data)
{
	.std.file.write(toString(vp), data);
}



public char[] dirname(char[] vp)
{
	foreach_reverse(i, c; vp)
	{
		if(c == '/')
		{
			return vp[0 .. i];
		}
	}

	return "";
}



public char[] join(char[] p1, char[] p2)
{
	if(p1.length > 0)
	{
		if(p1[length - 1] == '/')
		{
			return p1 ~ p2;
		}
		else
		{
			return p1 ~ "/" ~ p2;
		}
	}
	else
	{
		return p2;
	}
}



public string[] listdir(string vp)
{
	return .std.file.listdir(toString(vp));
}
