/*-------------------------------------------------------------------------
 * drawElements C++ Base Library
 * -----------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief String utilities.
 *//*--------------------------------------------------------------------*/

#include "deStringUtil.hpp"
#include "deString.h"

#include <algorithm>
#include <iterator>
#include <sstream>
#include <locale>
#include <iomanip>
#include <cctype>

using std::locale;
using std::string;
using std::vector;
using std::istringstream;
using std::istream_iterator;

namespace de
{
namespace
{

// Always use locale::classic to ensure consistent behavior in all environments.

struct ToLower
{
	const locale&	loc;
					ToLower		(void) : loc(locale::classic()) {}
	char			operator()	(char c) { return std::tolower(c, loc); }
};

struct ToUpper
{
	const locale&	loc;
					ToUpper		(void) : loc(locale::classic()) {}
	char			operator()	(char c) { return std::toupper(c, loc); }
};

} // anonymous

//! Convert string to lowercase using the classic "C" locale
string toLower (const string& str)
{
	string ret;
	std::transform(str.begin(), str.end(), std::inserter(ret, ret.begin()), ToLower());
	return ret;
}

//! Convert string to uppercase using the classic "C" locale
string toUpper (const string& str)
{
	string ret;
	std::transform(str.begin(), str.end(), std::inserter(ret, ret.begin()), ToUpper());
	return ret;
}

//! Convert string's first character to uppercase using the classic "C" locale
string capitalize (const string& str)
{
	if (str.empty())
		return str;
	return ToUpper()(str[0]) + str.substr(1);
}

//! Split a string into tokens. If `delim` is `'\0'`, separate by spans of
//! whitespace. Otherwise use a single character `delim` as the separator.

vector<string> splitString (const string& s, char delim)
{
	istringstream tokenStream(s);

	if (delim == '\0')
		return vector<string>(istream_iterator<string>(tokenStream),
							  istream_iterator<string>());
	else
	{
		vector<string>	ret;
		string			token;

		while (std::getline(tokenStream, token, delim))
			ret.push_back(token);

		return ret;
	}
}

//! Convert floating-point value to string with fixed number of fractional decimals.
std::string floatToString (float val, int precision)
{
	std::ostringstream s;
	s << std::fixed << std::setprecision(precision) << val;
	return s.str();
}

bool beginsWith (const std::string& s, const std::string& prefix)
{
	return deStringBeginsWith(s.c_str(), prefix.c_str()) == DE_TRUE;
}

bool endsWith (const std::string& s, const std::string& suffix)
{
	if (suffix.length() > s.length())
		return false;
	else
	{
		const std::string::size_type offset = s.length() - suffix.length();
		return s.find(suffix, offset) == offset;
	}
}

char toUpper (char c)
{
	return std::toupper(c, std::locale::classic());
}

char toLower (char c)
{
	return std::tolower(c, std::locale::classic());
}

bool isUpper (char c)
{
	return std::isupper(c, std::locale::classic());
}

bool isLower (char c)
{
	return std::islower(c, std::locale::classic());
}

bool isDigit (char c)
{
	return std::isdigit(c, std::locale::classic());
}

void StringUtil_selfTest (void)
{

	DE_TEST_ASSERT(toString(42) == "42");
	DE_TEST_ASSERT(toString("foo") == "foo");
	DE_TEST_ASSERT(toLower("FooBar") == "foobar");
	DE_TEST_ASSERT(toUpper("FooBar") == "FOOBAR");

	{
		vector <string> tokens(splitString(" foo bar\n\tbaz   "));
		DE_TEST_ASSERT(tokens.size() == 3);
		DE_TEST_ASSERT(tokens[0] == "foo");
		DE_TEST_ASSERT(tokens[1] == "bar");
		DE_TEST_ASSERT(tokens[2] == "baz");
	}

	DE_TEST_ASSERT(floatToString(4, 1) == "4.0");

	DE_TEST_ASSERT(beginsWith("foobar", "foobar"));
	DE_TEST_ASSERT(beginsWith("foobar", "foo"));
	DE_TEST_ASSERT(beginsWith("foobar", "f"));
	DE_TEST_ASSERT(beginsWith("foobar", ""));
	DE_TEST_ASSERT(beginsWith("", ""));
	DE_TEST_ASSERT(!beginsWith("foobar", "bar"));
	DE_TEST_ASSERT(!beginsWith("foobar", "foobarbaz"));
	DE_TEST_ASSERT(!beginsWith("", "foo"));

	DE_TEST_ASSERT(endsWith("foobar", "foobar"));
	DE_TEST_ASSERT(endsWith("foobar", "bar"));
	DE_TEST_ASSERT(endsWith("foobar", "r"));
	DE_TEST_ASSERT(endsWith("foobar", ""));
	DE_TEST_ASSERT(endsWith("", ""));
	DE_TEST_ASSERT(!endsWith("foobar", "foo"));
	DE_TEST_ASSERT(!endsWith("foobar", "bazfoobar"));
	DE_TEST_ASSERT(!endsWith("foobar", "foobarbaz"));
	DE_TEST_ASSERT(!endsWith("", "foo"));

	DE_TEST_ASSERT(toUpper('a') == 'A');
	DE_TEST_ASSERT(toUpper('A') == 'A');
	DE_TEST_ASSERT(toLower('a') == 'a');
	DE_TEST_ASSERT(toLower('A') == 'a');
	DE_TEST_ASSERT(isUpper('A'));
	DE_TEST_ASSERT(!isUpper('a'));
	DE_TEST_ASSERT(isLower('a'));
	DE_TEST_ASSERT(!isLower('A'));
	DE_TEST_ASSERT(isDigit('0'));
	DE_TEST_ASSERT(!isDigit('a'));
}

} // de
