#include "text.h"

using namespace std;

namespace CBK
{
	Text::Text(IDirect3DDevice9* device, const std::string& facename, const std::string& text, const int height, const unsigned int width, const unsigned int weight, const bool italic)
	{
		_format = DT_TOP | DT_LEFT | DT_NOCLIP | DT_SINGLELINE;
		_rect.left = 0;
		_rect.right = 0;
		_rect.top = 0;
		_rect.bottom = 0;
		_autoSize = true;
		setColor(255u, 255u, 255u, 255u);
		setText(text);

		_device = device;
		D3DXCreateFont(_device, height, width, weight, 0, italic, 0, 0, 0, 0, facename.c_str(), &_font);
		D3DXCreateSprite(_device, &_sprite);
		_font->PreloadCharacters('a', 'z');
		_font->PreloadCharacters('A', 'Z');
		_font->PreloadCharacters('0', '9');
	}

	Text::~Text(void)
	{
		_font->Release();
		_sprite->Release();
	}

	Text& Text::setText(const std::string& text)
	{
		_text = text;
		return *this;
	}

	const std::string& Text::getText(void) const
	{
		return _text;
	}

	Text& Text::setPoint1(const long x, const long y)
	{
		_rect.left = x;
		_rect.top = y;
		return *this;
	}

	Text& Text::setPoint2(const long x, const long y)
	{
		_rect.right = x;
		_rect.bottom = y;
		_autoSize = false;
		return *this;
	}

	Text& Text::setSize(const long width, const long height)
	{
		_rect.right = _rect.left + width;
		_rect.bottom = _rect.top + height;
		_autoSize = false;
		return *this;
	}

	void Text::getPoint1(long* x, long* y) const
	{
		if (x != 0)
			*x = _rect.left;
		if (y != 0)
			*y = _rect.top;
	}

	void Text::getPoint2(long* x, long* y) const
	{
		updateSize();

		if (x != 0)
			*x = _rect.right;
		if (y != 0)
			*y = _rect.bottom;
	}

	void Text::getSize(long* x, long* y) const
	{
		updateSize();

		if (x != 0)
			*x = _rect.right - _rect.left;
		if (y != 0)
			*y = _rect.bottom - _rect.top;
	}

	void Text::updateSize(void) const
	{
		if (_autoSize)
			_font->DrawTextA(_sprite, _text.c_str(), -1, &_rect, _format | DT_CALCRECT, _color);
	}

	Text& Text::enableAutoSize(const bool enabled)
	{
		_autoSize = enabled;
		return *this;
	}

	Text& Text::disableAutoSize(void)
	{
		return enableAutoSize(false);
	}

	const bool Text::getIsAutoSized(void) const
	{
		return _autoSize;
	}

	Text& Text::setAlignmentVertical(const VerticalAlignment& vAlignment)
	{
		_format &= ~DT_BOTTOM;
		_format &= ~DT_VCENTER;
		_format |= vAlignment;
		return *this;
	}

	Text& Text::setAlignmentHorizontal(const HorizontalAlignment& hAlignment)
	{
		_format &= ~DT_RIGHT;
		_format &= ~DT_CENTER;
		_format |= hAlignment;
		return *this;
	}

	const Text::VerticalAlignment Text::getAlignmentVertical(void)
	{
		if (_format & VOFF_Bottom)
			return VOFF_Bottom;
		else if (_format & VOFF_Center)
			return VOFF_Center;
		else
			return VOFF_Top;
	}

	const Text::HorizontalAlignment Text::getAlignmentHorizontal(void)
	{
		if (_format & HOFF_Right)
			return HOFF_Right;
		else if (_format & HOFF_Center)
			return HOFF_Center;
		else
			return HOFF_Left;
	}

	Text& Text::enableForceSingleLine(const bool enabled)
	{
		if (enabled)
			_format |= DT_SINGLELINE;
		else
			_format &= ~DT_SINGLELINE;

		return *this;
	}

	Text& Text::disableForceSingleLine(void)
	{
		return enableForceSingleLine(false);
	}

	const bool Text::getIsForcedSingleLine(void)
	{
		if (_format & DT_SINGLELINE)
			return true;
		else
			return false;
	}

	Text& Text::setColor(const D3DCOLOR& color)
	{
		_color = color;
		return *this;
	}

	Text& Text::setColor(const float& r, const float& g, const float& b, const float& a)
	{
		_color = D3DCOLOR_ARGB(int(a * 255), int(r * 255), int(g * 255), int(b * 255));
		return *this;
	}

	Text& Text::setColor(const byte r, const byte g, const byte b, const byte a)
	{
		_color = D3DCOLOR_ARGB(a, r, g, b);
		return *this;
	}

	const D3DCOLOR& Text::getColor(void) const
	{
		return _color;
	}

	const bool Text::draw(void) const
	{
		updateSize();
		_sprite->Begin(D3DXSPRITE_ALPHABLEND);
		bool success = (_font->DrawTextA(_sprite, _text.c_str(), -1, &_rect, _format, _color) != 0);
		_sprite->End();
		return success;
	}
/*
	const bool Text::draw(const std::string& text, const long& x, const long& y, const long& width, const long& height, const D3DCOLOR& color, const VerticalOffset& voff, const HorizontalOffset& hoff, const bool resize, const bool forceSingleLine, const bool isWidth, const bool isHeight) const
	{
		RECT rect;
		rect.left = x;
		rect.top = y;
		if (isWidth)
			rect.right = x + width;
		else
			rect.right = width;
		if (isHeight)
			rect.bottom = y + height;
		else
			rect.bottom = height;

		DWORD format = voff | hoff | DT_NOCLIP;
		if (forceSingleLine)
			format |= DT_SINGLELINE;

		if (resize)
			_font->DrawTextA(_sprite, text.c_str(), -1, &rect, format | DT_CALCRECT, color);

		_sprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_SORT_DEPTH_FRONTTOBACK | D3DXSPRITE_SORT_TEXTURE);
		bool success = (_font->DrawTextA(_sprite, text.c_str(), -1, &rect, format, color) != 0);
		_sprite->End();
		return success;
	}

	const bool Text::draw(const std::string& text, const long& x, const long& y, const long& width, const long& height, const float& r, const float& g, const float& b, const float& a, const VerticalOffset& voff, const HorizontalOffset& hoff, const bool resize, const bool forceSingleLine, const bool isWidth, const bool isHeight) const
	{
		return draw(text, x, y, width, height, , voff, hoff, resize, forceSingleLine, isWidth, isHeight);
	}

	const bool Text::draw(const std::string& text, const long& x, const long& y, const long& width, const long& height, const byte& r, const byte& g, const byte& b, const byte& a, const VerticalOffset& voff, const HorizontalOffset& hoff, const bool resize, const bool forceSingleLine, const bool isWidth, const bool isHeight) const
	{
		return draw(text, x, y, width, height, , voff, hoff, resize, forceSingleLine, isWidth, isHeight);
	}
*/
}