#include "fileutil.h"
#include <allegro5/allegro.h>
#include "strutil.h"

using namespace std;

bool looksLikeDrive(const string &item)
{
	return (
			item.length() == 2 &&
			item[1] == ':' &&
			item[0] >= 'A' && item[0] <= 'Z'
	);
}

Path Path::parse(const string &s, char delim)
{
	bool isAbsolute = false;
	bool hasDriveComponent = false;
	vector<string> result;

	std::stringstream ss;
	ss.str(s);
	std::string item;

	bool first = true;
	while (std::getline(ss, item, delim))
	{
		if (first)
		{
			if (item == "") // i.e. starts with slash
			{
				isAbsolute = true;
			}

			if (looksLikeDrive(item))
			{
				isAbsolute = true;
				hasDriveComponent = true;
			}

			first = false;
		}

		if (item != "")
			result.push_back (item);
	}

	return Path(result, isAbsolute, hasDriveComponent);
}

Path::Path() : pathComponents(), fAbsolute(false), fHasDriveComponent(false) {}

Path::Path(const vector<string> &data, bool _fAbsolute, bool _hasDriveComponent) : pathComponents(data), fAbsolute(_fAbsolute), fHasDriveComponent(_hasDriveComponent) {}

Path Path::getParentPath() const
{
	if (pathComponents.size() == 0) return *this;

	auto first = pathComponents.begin();
	auto last = pathComponents.end()-1;
	return Path(vector<string>(first, last), fAbsolute, fHasDriveComponent);
}

Path Path::join (const std::string &tail, char sep) const
{
	Path tailPath = Path::parse(tail, sep);
	if (tailPath.isAbsolute())
	{
		throw exception(); // Tail component can not be absolute
	}

	auto result = pathComponents;
	result.insert(result.end(), tailPath.pathComponents.begin(), tailPath.pathComponents.end());
	return Path(result, fAbsolute, fHasDriveComponent);
}

std::string Path::toString(char pathSep) const
{
	std::stringstream ss;
	bool first = true;
	auto it = pathComponents.begin();

	if (it == pathComponents.end()) return "";

	if (fAbsolute)
	{
		if (fHasDriveComponent)
		{
			ss << (*it);
			it++;
		}
		ss << pathSep;
	}

	while (it != pathComponents.end())
	{
		if (first)
		{
			first = false;

		}
		else
		{
			ss << pathSep;
		}
		ss << (*it);
		it++;
	}
	return ss.str();
}

string Path::getDriveComponent() const
{
	if (fHasDriveComponent) { return pathComponents[0]; } else return "";
}

