#include "FontUndoAction.h"

#include "gui/Redrawable.h"
#include "model/Font.h"
#include "model/Text.h"

#include <i18n.h>
#include <Rectangle.h>

class FontUndoActionEntry
{
public:
	FontUndoActionEntry(Text* e, XojFont& oldFont, XojFont& newFont)
	{
		this->e = e;
		this->oldFont = oldFont;
		this->newFont = newFont;
	}

	Text* e;
	XojFont oldFont;
	XojFont newFont;
};

FontUndoAction::FontUndoAction(PageRef page, Layer* layer)
 : UndoAction("FontUndoAction")
{
	XOJ_INIT_TYPE(FontUndoAction);

	this->page = page;
	this->layer = layer;
}

FontUndoAction::~FontUndoAction()
{
	XOJ_CHECK_TYPE(FontUndoAction);

	for (FontUndoActionEntry* e : this->data)
	{
		delete e;
	}
	this->data.clear();

	XOJ_RELEASE_TYPE(FontUndoAction);
}

void FontUndoAction::addStroke(Text* e, XojFont& oldFont, XojFont& newFont)
{
	XOJ_CHECK_TYPE(FontUndoAction);

	this->data.push_back(new FontUndoActionEntry(e, oldFont, newFont));
}

bool FontUndoAction::undo(Control* control)
{
	XOJ_CHECK_TYPE(FontUndoAction);

	if (this->data.empty())
	{
		return true;
	}

	FontUndoActionEntry* e = this->data.front();
	double x1 = e->e->getX();
	double x2 = e->e->getX() + e->e->getElementWidth();
	double y1 = e->e->getY();
	double y2 = e->e->getY() + e->e->getElementHeight();

	for (FontUndoActionEntry* e : this->data)
	{
		// size with old font
		x1 = MIN(x1, e->e->getX());
		x2 = MAX(x2, e->e->getX() + e->e->getElementWidth());
		y1 = MIN(y1, e->e->getY());
		y2 = MAX(y2, e->e->getY() + e->e->getElementHeight());

		e->e->setFont(e->oldFont);

		// size with new font
		x1 = MIN(x1, e->e->getX());
		x2 = MAX(x2, e->e->getX() + e->e->getElementWidth());
		y1 = MIN(y1, e->e->getY());
		y2 = MAX(y2, e->e->getY() + e->e->getElementHeight());
	}

	Rectangle rect(x1, y1, x2 - x1, y2 - y1);
	this->page->fireRectChanged(rect);

	return true;
}

bool FontUndoAction::redo(Control* control)
{
	XOJ_CHECK_TYPE(FontUndoAction);

	if (this->data.empty())
	{
		return true;
	}

	FontUndoActionEntry* e = this->data.front();
	double x1 = e->e->getX();
	double x2 = e->e->getX() + e->e->getElementWidth();
	double y1 = e->e->getY();
	double y2 = e->e->getY() + e->e->getElementHeight();

	for (FontUndoActionEntry* e : this->data)
	{
		// size with old font
		x1 = MIN(x1, e->e->getX());
		x2 = MAX(x2, e->e->getX() + e->e->getElementWidth());
		y1 = MIN(y1, e->e->getY());
		y2 = MAX(y2, e->e->getY() + e->e->getElementHeight());

		e->e->setFont(e->newFont);

		// size with new font
		x1 = MIN(x1, e->e->getX());
		x2 = MAX(x2, e->e->getX() + e->e->getElementWidth());
		y1 = MIN(y1, e->e->getY());
		y2 = MAX(y2, e->e->getY() + e->e->getElementHeight());
	}

	Rectangle rect(x1, y1, x2 - x1, y2 - y1);
	this->page->fireRectChanged(rect);

	return true;
}

string FontUndoAction::getText()
{
	XOJ_CHECK_TYPE(FontUndoAction);

	return _("Change font");
}
