#ifndef UTILS
#define UTILS

#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>
#include <stdlib.h>
#include <time.h>
#include <vector>

// Convert an int to a string.
inline std::string ToString(int x)
{
	std::ostringstream o;
	o << x;
	return o.str();
}

// Convert a double to a string.
inline std::string ToString(double x)
{
	std::ostringstream o;
	o << x;
	return o.str();
}

// Convert a float to a string.
inline std::string ToString(float x)
{
	std::ostringstream o;
	o << x;
	return o.str();
}

// Convert a string to a bool.
inline bool ToBool(std::string x)
{
	if (x == "1")
		return true;
	else
		return false;
}

// Convert a string to uppercase.
inline std::string ToUpper(std::string x)
{
    for (size_t i = 0; i < x.length(); ++i)
        x[i]=toupper(x[i]);
    
	return x;
}

// Convert a string to lowercase.
inline std::string ToLower(std::string x)
{
    for (size_t i = 0; i < x.length(); ++i)
        x[i]=tolower(x[i]);
    
	return x;
}

// Generate a random number from seed and multiplier values.
inline float Random(float seed, float multiplier)
{
	srand(seed);
	return ((float)rand()/(float)RAND_MAX)*multiplier;
}

// Generate a random number from multiplier value.
inline float Random(float multiplier)
{
	return Random(timeGetTime(), multiplier);
}

// Generate a random number between 0.0f anf 1.0f.
inline float Random()
{
	return Random(1.0f);
}

// Return a list of strings from an argument string.
inline std::vector<std::string> parseCmdLine(const char* szcmdline)
{
	std::vector<std::string> arguments;
	std::string cmdline = szcmdline;
    cmdline += ' ';
    bool bQuotes = false;
    int lpos = 0;
    int i = 0;
    for (i = 0; i < cmdline.length(); ++i)
    {
          char c = cmdline[i];
          switch(c)
          {
          case '"':
                bQuotes = !bQuotes;   break;
          case ' ':
                if (bQuotes)
                     break;
                if (i > lpos)
                     arguments.push_back(cmdline.substr(lpos, i - lpos));
                lpos = i+1;
          }
    }
    return arguments;
}

// Check if file name is of a certain type.
inline bool IsFileType(std::string file, std::string extension)
{
	std::string subStr = file.substr(file.size()-3, 3);

	if (subStr.compare(extension) == 0)
		return true;

	return false;
}

// Gets the absolute path from an inpur relative path.
inline std::string GetFullPath(std::string path)
{
	TCHAR fullPath[4096]; 
    TCHAR** lppPart = {NULL};

	GetFullPathName(path.c_str(), 4096, fullPath, lppPart);
	return fullPath;
}

#endif