/*
* This file is part of project OpenEmbroidery. It's copyrighted by
* the contributors recorded in the version control history of the file.
* Original project location https://code.electrolab.fr/openEmbroidery/openEmbroidery_software
*
* SPDX-License-Identifier: CECILL-2.1
* License-Filename: Licence_CeCILL_V2.1-en.txt
*/

#include "actions/OE_actionsStitchs.h"
#include "actions/OE_actionsFillStitchs.h"
#include "OE_document.h"

///////// actionNewFillStitch ///////////////
/// \brief OE_actionNewFillStitch::OE_actionNewFillStitch
/// \param curve
/// \param len
/// \param width
/// \param Pattern
/// \param offset
///
OE_actionNewFillStitch::OE_actionNewFillStitch(OE_document* doc, float len, float width, OE_pattern* pattern) :
    OE_actions(doc), action(nullptr), FillStitch(nullptr)
{
	if (document)
	{
		FillStitch = new OE_fillstitch(document->threads.front(), len, width, pattern);
		action = new OE_actionNewStitch(document, FillStitch);
	}
}

OE_actionNewFillStitch::~OE_actionNewFillStitch()
{
	if (!active)
	{
		if (action)
		{
			delete action;
		}
		if (FillStitch)
		{
			delete FillStitch;
		}
	}
}

void OE_actionNewFillStitch::undo()
{
	if (active&&action)
	{
		action->undo();
	}
	active = false;
}

void OE_actionNewFillStitch::redo()
{
	if (!active&&action)
	{
		action->redo();
	}
	active = true;
}

///////// OE_actionSetFillStitchPattern ///////////////
/// \brief OE_actionSetFillStitchPattern::OE_actionSetFillStitchPattern
/// \param stitch
/// \param pattern
///
OE_actionSetFillStitchPattern::OE_actionSetFillStitchPattern(OE_document* doc, OE_fillstitch* stitch, OE_pattern* pattern) :
    OE_actions(doc), actionStitch(nullptr), oldPattern(nullptr), newPattern(nullptr)
{
	if (document&&stitch)
	{
		actionStitch = stitch;
		oldPattern = actionStitch->getPattern();
		newPattern = pattern;

		actionStitch->setPattern(pattern);
	}
}

OE_actionSetFillStitchPattern::~OE_actionSetFillStitchPattern()
{
}

void OE_actionSetFillStitchPattern::undo()
{
	if (active)
	{
		actionStitch->setPattern(oldPattern);
		active = false;
	}
}

void OE_actionSetFillStitchPattern::redo()
{
	if (!active)
	{
		actionStitch->setPattern(newPattern);
		active = true;
	}
}

///////// OE_actionSetFillStitchLen ///////////////
/// \brief OE_actionSetFillStitchLen::OE_actionSetFillStitchLen
/// \param stitch
/// \param len
///
OE_actionSetFillStitchLen::OE_actionSetFillStitchLen(OE_document* doc, OE_fillstitch* stitch, float len) :
    OE_actions(doc), actionStitch(nullptr)
{
	if (document && stitch)
	{
		actionStitch = stitch;
		oldLen = actionStitch->getLen();

		actionStitch->setLen(len);
	}
}

OE_actionSetFillStitchLen::~OE_actionSetFillStitchLen()
{
}

void OE_actionSetFillStitchLen::undo()
{
	if (active)
	{
		actionStitch->setLen(switchVal(actionStitch->getLen(), &oldLen));
		active = false;
	}
}

void OE_actionSetFillStitchLen::redo()
{
	if (!active)
	{
		actionStitch->setLen(switchVal(actionStitch->getLen(), &oldLen));
		active = true;
	}
}


///////// OE_actionSetFillStitchWidth ///////////////
/// \brief OE_actionSetFillStitchWidth::OE_actionSetFillStitchWidth
/// \param stitch
/// \param width
///
OE_actionSetFillStitchWidth::OE_actionSetFillStitchWidth(OE_document* doc, OE_fillstitch* stitch, float width) :
    OE_actions(doc), actionStitch(nullptr), oldWidth(0), oldOffset(0)
{
	if (document && stitch)
	{
		actionStitch = stitch;
		oldWidth = actionStitch->getWidth();

		actionStitch->setWidth(width);
	}
}

OE_actionSetFillStitchWidth::~OE_actionSetFillStitchWidth()
{
}

void OE_actionSetFillStitchWidth::undo()
{
	if (active)
	{
		actionStitch->setWidth(switchVal(actionStitch->getWidth(), &oldWidth));
		active = false;
	}
}

void OE_actionSetFillStitchWidth::redo()
{
	if (!active)
	{
		actionStitch->setWidth(switchVal(actionStitch->getWidth(), &oldWidth));
		active = true;
	}
}

void OE_actionSetFillStitchWidth::setWidth(float width)
{
	if (document)
	{
		actionStitch->setWidth(width);
	}
}

void OE_actionSetFillStitchWidth::offsetWidth(float offset)
{
	if (document)
	{
		actionStitch->setWidth(actionStitch->getWidth()-oldOffset+offset);
	}
	oldOffset = offset;
}

float OE_actionSetFillStitchWidth::getWidth()
{
	if (document)
	{
		return actionStitch->getWidth();
	}
	return 0;
}

///////// OE_actionSetSelectedFillStitchWidth ///////////////
/// \brief OE_actionSetSelectedFillStitchWidth::OE_actionSetFillStitchWidth
/// \param scale
///
OE_actionScaleSelectedFillStitchWidth::OE_actionScaleSelectedFillStitchWidth(OE_document* doc, float scale) : OE_actions(doc)
{
	if (document)
	{
		OE_fillstitch* tmpFillStitch;
		for(auto selStitch : document->selectedStitchs)
		{
			tmpFillStitch = dynamic_cast<OE_fillstitch*>(selStitch);
			if (tmpFillStitch)
			{
				actions.push_back(new OE_actionSetFillStitchWidth(document, tmpFillStitch,tmpFillStitch->getWidth()*scale));
			}
		}
		oldScale = scale;
	}
}

OE_actionScaleSelectedFillStitchWidth::~OE_actionScaleSelectedFillStitchWidth()
{
}

void OE_actionScaleSelectedFillStitchWidth::undo()
{
	if (active)
	{
		for(auto action : actions)
		{
			action->undo();
		}
		active = false;
	}
}

void OE_actionScaleSelectedFillStitchWidth::redo()
{
	if (!active)
	{
		for(auto action : actions)
		{
			action->redo();
		}
		active = true;
	}
}

void OE_actionScaleSelectedFillStitchWidth::scaleWidth(float scale)
{
	for(auto action : actions)
	{
		action->setWidth(action->getWidth()/oldScale*scale);
	}
	oldScale = scale;
}

///////// OE_actionSetSelectedFillStitchLen///////////////
/// \brief OE_actionSetSelectedFillStitchLen::OE_actionSetSelectedFillStitchLen
/// \param scale
///
OE_actionScaleSelectedFillStitchLen::OE_actionScaleSelectedFillStitchLen(OE_document* doc, float scale) : OE_actions(doc)
{
	if (document)
	{
		OE_fillstitch* tmpFillStitch;
		for(auto selStitch : document->selectedStitchs)
		{
			tmpFillStitch = dynamic_cast<OE_fillstitch*>(selStitch);
			if (tmpFillStitch)
			{
				actions.push_back(new OE_actionSetFillStitchLen(document, tmpFillStitch, tmpFillStitch->getLen()*scale));
			}
		}
	}
}

OE_actionScaleSelectedFillStitchLen::~OE_actionScaleSelectedFillStitchLen()
{
}

void OE_actionScaleSelectedFillStitchLen::undo()
{
	if (active)
	{
		for(auto action : actions)
		{
			action->undo();
		}
		active = false;
	}
}

void OE_actionScaleSelectedFillStitchLen::redo()
{
	if (!active)
	{
		for(auto action : actions)
		{
			action->redo();
		}
		active = true;
	}
}

void OE_actionScaleSelectedFillStitchLen::scaleLen(float /*scale*/)
{
}

///////// OE_actionSetSelectedFillStitchPattern ///////////////
/// \brief OE_actionSetSelectedFillStitchPattern::OE_actionSetSelectedFillStitchPattern
/// \param pattern
///
OE_actionSetSelectedFillStitchPattern::OE_actionSetSelectedFillStitchPattern(OE_document* doc, OE_pattern* pattern) : OE_actions(doc)
{
	if (document)
	{
		OE_fillstitch* tmpFillStitch;
		for(auto selStitch : document->selectedStitchs)
		{
			tmpFillStitch = dynamic_cast<OE_fillstitch*>(selStitch);
			if (tmpFillStitch)
			{
				actions.push_back(new OE_actionSetFillStitchPattern(document, tmpFillStitch, pattern));
			}
		}
	}
}

OE_actionSetSelectedFillStitchPattern::~OE_actionSetSelectedFillStitchPattern()
{
}

void OE_actionSetSelectedFillStitchPattern::undo()
{
	if (active)
	{
		for(auto action : actions)
		{
			action->undo();
		}
		active = false;
	}
}

void OE_actionSetSelectedFillStitchPattern::redo()
{
	if (!active)
	{
		for(auto action : actions)
		{
			action->redo();
		}
		active = true;
	}
}


///////// OE_actionMovePointFillStitch ///////////////
/// \brief OE_actionMovePointFillStitch::OE_actionMovePointFillStitch
/// \param pos
/// \param offset
OE_actionMovePointFillStitch::OE_actionMovePointFillStitch(OE_document* doc, OE_fillstitch* stitch, int _pos, vector_2d _offset) :
    OE_actions(doc), actionStitch(nullptr)
{
	if (!document || !stitch)
	{
		return;
	}

	pos = _pos;
	offset = _offset;
	actionStitch = stitch;
	oldPoint = actionStitch->getGridControlPoint(pos);
	actionStitch->setGridControlPoint(pos, oldPoint + offset);
}

OE_actionMovePointFillStitch::~OE_actionMovePointFillStitch()
{
}

void OE_actionMovePointFillStitch::undo()
{
	if (active)
	{
		actionStitch->setGridControlPoint(pos, oldPoint);
		active = false;
	}
}

void OE_actionMovePointFillStitch::redo()
{
	if (!active)
	{
		actionStitch->setGridControlPoint(pos, oldPoint + offset);
		active = true;
	}
}

void OE_actionMovePointFillStitch::setOffset(vector_2d _offset)
{
	if (!actionStitch || !active)
	{
		return;
	}

	offset = _offset;
	actionStitch->setGridControlPoint(pos,oldPoint + offset);
}
