/*! \file pichar.h
 * \ingroup Text
 * \~\brief
 * \~english Single string character
 * \~russian Один символ строки
*/
/*
	PIP - Platform Independent Primitives
	Unicode char
	Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef PICHAR_H
#define PICHAR_H

#include "piincludes.h"

extern PIP_EXPORT char * __syslocname__;
extern PIP_EXPORT char * __sysoemname__;
extern PIP_EXPORT char * __utf8name__;

//! \ingroup Text
//! \~\brief
//! \~english %PIChar represents a single character.
//! \~russian %PIChar представляет собой один символ строки.
class PIP_EXPORT PIChar
{
	friend class PIString;
	friend PICout operator <<(PICout s, const PIChar & v);
public:
	//! \~english Contructs Ascii symbol
	//! \~russian Создает символ Ascii
	PIChar(char c) {ch = c;}

	//! \~english Contructs ascii symbol
	//! \~russian Создает символ Ascii
	PIChar(uchar c) {ch = c;}

	//! \~english Contructs 2-bytes symbol
	//! \~russian Создает 2-байтный символ
	PIChar(ushort c = 0) {ch = c;}

	//! \~english Contructs 2-bytes symbol from `wchar_t`
	//! \~russian Создает 2-байтный символ из `wchar_t`
	PIChar(wchar_t c) {ch = c;}

	//! \~english Contructs symbol from system locale and no more than 4 bytes of string
	//! \~russian Создает символ из системной локали не более 4 байт длины
	PIChar(const char * c, int * bytes = 0);

	//! \~english Copy operator
	//! \~russian Оператор присваивания
	PIChar & operator =(const char v) {ch = v; return *this;}

	//! \~english Copy operator
	//! \~russian Оператор присваивания
	PIChar & operator =(const wchar_t v) {ch = v; return *this;}

	//! \~english Compare operator
	//! \~russian Оператор сравнения
	bool operator ==(const PIChar & o) const;

	//! \~english Compare operator
	//! \~russian Оператор сравнения
	bool operator !=(const PIChar & o) const {return !(o == *this);}

	//! \~english Compare operator
	//! \~russian Оператор сравнения
	bool operator >(const PIChar & o) const;

	//! \~english Compare operator
	//! \~russian Оператор сравнения
	bool operator <(const PIChar & o) const;

	//! \~english Compare operator
	//! \~russian Оператор сравнения
	bool operator >=(const PIChar & o) const;

	//! \~english Compare operator
	//! \~russian Оператор сравнения
	bool operator <=(const PIChar & o) const;

	//! \~english Returns \b true if symbol is digit ('0' to '9')
	//! \~russian Возвращает \b true если символ является
	bool isDigit() const;
	
	//! \~english Returns \b true if symbol is HEX digit ('0' to '9', 'a' to 'f', 'A' to 'F')
	//! \~russian Возвращает \b true если символ является HEX цифрой ('0' до '9', 'a' до 'f', 'A' до 'F')
	bool isHex() const;
	
	//! \~english Returns \b true if symbol is drawable (without space)
	//! \~russian Возвращает \b true если символ является графическим (исключая пробельные)
	bool isGraphical() const;
	
	//! \~english Returns \b true if symbol is control byte (< 32 or 127)
	//! \~russian Возвращает \b true если символ является контрольным (< 32 or 127)
	bool isControl() const;
	
	//! \~english Returns \b true if symbol is in lower case
	//! \~russian Возвращает \b true если символ в нижнем регистре
	bool isLower() const;

	//! \~english Returns \b true if symbol is in upper case
	//! \~russian Возвращает \b true если символ в верхнем регистре
	bool isUpper() const;
	
	//! \~english Returns \b true if symbol is printable (with space)
	//! \~russian Возвращает \b true если символ является печатным (включая пробельные)
	bool isPrint() const;
	
	//! \~english Returns \b true if symbol is space or tab
	//! \~russian Возвращает \b true если символ является пробельным или табуляцией
	bool isSpace() const;
	
	//! \~english Returns \b true if symbol is alphabetical letter
	//! \~russian Возвращает \b true если символ является алфавитной буквой
	bool isAlpha() const;
	
	//! \~english Returns \b true if symbol is Ascii (< 128)
	//! \~russian Возвращает \b true если символ является Ascii (< 128)
	bool isAscii() const;

	const wchar_t * toWCharPtr() const;
	
	//! \~english Returns as `char *` string
	//! \~russian Возвращает символ как указатель на `char *`
	const char * toCharPtr() const;
	
	wchar_t toWChar() const;

	//! \~english Returns symbol as Ascii
	//! \~russian Возвращает символ в Ascii
	char toAscii() const {return ch % 256;}

	//! \~english Returns symbol as console codepage
	//! \~russian Возвращает символ в консольной кодировке
	char toConsole1Byte() const;

	//! \~english Returns symbol as system codepage
	//! \~russian Возвращает символ в системной кодировке
	char toSystem() const;

	ushort unicode16Code() const {return ch;}
	
	//! \~english Returns symbol in upper case
	//! \~russian Возвращает символ в нижнем регистре
	PIChar toUpper() const;
	
	//! \~english Returns symbol in lower case
	//! \~russian Возвращает символ в верхнем регистре
	PIChar toLower() const;
	
	//! \~english Returns symbol from console codepage
	//! \~russian Возвращает символ из консольной кодировки
	static PIChar fromConsole(char c);

	//! \~english Returns symbol from system codepage
	//! \~russian Возвращает символ из системной кодировки
	static PIChar fromSystem(char c);

	//! \~english Returns symbol from UTF8 codepage
	//! \~russian Возвращает символ из UTF8 кодировки
	static PIChar fromUTF8(const char * c);

private:
	ushort ch;

};

//! \relatesalso PIChar
//! \~english Output operator to \a PICout
//! \~russian Оператор вывода в \a PICout
PIP_EXPORT PICout operator <<(PICout s, const PIChar & v);

//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator ==(const char v, const PIChar & c) {return (PIChar(v) == c);}

//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator >(const char v, const PIChar & c) {return (PIChar(v) > c);}

//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator <(const char v, const PIChar & c) {return (PIChar(v) < c);}

//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator >=(const char v, const PIChar & c) {return (PIChar(v) >= c);}

//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator <=(const char v, const PIChar & c) {return (PIChar(v) <= c);}


//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator ==(const char * v, const PIChar & c) {return (PIChar(v) == c);}

//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator >(const char * v, const PIChar & c) {return (PIChar(v) > c);}

//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator <(const char * v, const PIChar & c) {return (PIChar(v) < c);}

//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator >=(const char * v, const PIChar & c) {return (PIChar(v) >= c);}

//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator <=(const char * v, const PIChar & c) {return (PIChar(v) <= c);}


//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator ==(const int v, const PIChar & c) {return (PIChar((ushort)v) == c);}

//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator >(const int v, const PIChar & c) {return (PIChar((ushort)v) > c);}

//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator <(const int v, const PIChar & c) {return (PIChar((ushort)v) < c);}

//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator >=(const int v, const PIChar & c) {return (PIChar((ushort)v) >= c);}

//! \relatesalso PIChar
//! \~english Compare operator
//! \~russian Оператор сравнения
inline bool operator <=(const int v, const PIChar & c) {return (PIChar((ushort)v) <= c);}

#endif // PICHAR_H
