/*
* 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_actionsLineStitchs.h"
#include "OE_document.h"

///////// actionNewLineStitch ///////////////
/// \brief OE_actionNewLineStitch::OE_actionNewLineStitch
/// \param curve
/// \param len
/// \param width
/// \param Pattern
/// \param offset
///
OE_actionNewLineStitch::OE_actionNewLineStitch(OE_document* doc, float len, float width, OE_pattern* pattern, unsigned patternSteps,
                                               float xOffset, float yOffset) :
    OE_actions(doc), action(nullptr), linestitch(nullptr)
{
	if (document)
	{
		linestitch = new OE_linestitch(document->threads.front(), len, width, pattern, patternSteps, xOffset, yOffset);
		action = new OE_actionNewStitch(document, linestitch);
	}
}

OE_actionNewLineStitch::~OE_actionNewLineStitch()
{
	if (!active)
	{
		if (action)
		{
			delete action;
		}
		if (linestitch)
		{
			delete linestitch;
		}
	}
}

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

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

///////// OE_actionSetLineStitchPattern ///////////////
/// \brief OE_actionSetLineStitchPattern::OE_actionSetLineStitchPattern
/// \param stitch
/// \param pattern
///
OE_actionSetLineStitchPattern::OE_actionSetLineStitchPattern(OE_document* doc, OE_linestitch* 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_actionSetLineStitchPattern::~OE_actionSetLineStitchPattern()
{
}

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

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

///////// OE_actionSetLineStitchCurve ///////////////
/// \brief OE_actionSetLineStitchCurve::OE_actionSetLineStitchCurve
/// \param stitch
/// \param curve
///
/*
OE_actionSetLineStitchCurve::OE_actionSetLineStitchCurve(OE_linestitch* stitch, OE_curve * curve)
{
	if (document&&stitch)
	{
		actionStitch = stitch;
		oldCurve = actionStitch->getCurve();

		actionStitch->setCurve(curve);
	}
}

OE_actionSetLineStitchCurve::~OE_actionSetLineStitchCurve()
{
}

void OE_actionSetLineStitchCurve::undo()
{
	if (active)
	{
		actionStitch->setCurve(switchVal(actionStitch->getCurve(), &oldCurve));
		active = false;
	}
}

void OE_actionSetLineStitchCurve::redo()
{
	if (!active)
	{
		actionStitch->setCurve(switchVal(actionStitch->getCurve(), &oldCurve));
		active = true;
	}
}
*/

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

        actionStitch->setLen(len);
    }
}

OE_actionSetLineStitchLen::~OE_actionSetLineStitchLen()
{
}

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

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

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

		actionStitch->setWidth(width);
	}
}

OE_actionSetLineStitchWidth::~OE_actionSetLineStitchWidth()
{
}

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

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

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

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

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

///////// OE_actionSetLineStitchReverse ///////////////
/// \brief OE_actionSetLineStitchReverse::OE_actionSetLineStitchReverse
/// \param stitch
/// \param reverse
///
OE_actionSetLineStitchReverse::OE_actionSetLineStitchReverse(OE_document* doc, OE_linestitch* stitch, bool reverse) :
    OE_actions(doc), actionStitch(nullptr), oldReverse(false)
{
	if (document && stitch)
	{
		actionStitch = stitch;
		oldReverse = actionStitch->getReverse();

		actionStitch->setReverse(reverse);
	}
}

OE_actionSetLineStitchReverse::~OE_actionSetLineStitchReverse()
{
}

void OE_actionSetLineStitchReverse::undo()
{
	if (active)
	{
		actionStitch->setReverse(switchVal(actionStitch->getReverse(), &oldReverse));
		active = false;
	}
}

void OE_actionSetLineStitchReverse::redo()
{
	if (!active)
	{
		actionStitch->setReverse(switchVal(actionStitch->getReverse(), &oldReverse));
		active = true;
	}
}

///////// OE_actionSetSelectedLineStitchWidth ///////////////
/// \brief OE_actionSetSelectedLineStitchWidth::OE_actionSetLineStitchWidth
/// \param scale
///
OE_actionScaleSelectedLineStitchWidth::OE_actionScaleSelectedLineStitchWidth(OE_document* doc, float scale) : OE_actions(doc)
{
	if (document)
	{
		OE_linestitch* tmpLineStitch;
		for(auto selStitch : document->selectedStitchs)
		{
			tmpLineStitch = dynamic_cast<OE_linestitch*>(selStitch);
			if (tmpLineStitch)
			{
				actions.push_back(new OE_actionSetLineStitchWidth(document, tmpLineStitch, tmpLineStitch->getWidth()*scale));
			}
		}
		oldScale = scale;
	}
}

OE_actionScaleSelectedLineStitchWidth::~OE_actionScaleSelectedLineStitchWidth()
{
	if (!active)
	{
		while(!actions.empty()) delete actions.front(), actions.pop_front();
	}
}

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

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

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

///////// OE_actionSetSelectedLineStitchLen///////////////
/// \brief OE_actionSetSelectedLineStitchLen::OE_actionSetSelectedLineStitchLen
/// \param scale
///
OE_actionScaleSelectedLineStitchLen::OE_actionScaleSelectedLineStitchLen(OE_document* doc, float scale) : OE_actions(doc)
{
	if (document)
	{
		OE_linestitch* tmpLineStitch;
		for(auto selStitch : document->selectedStitchs)
		{
			tmpLineStitch = dynamic_cast<OE_linestitch*>(selStitch);
			if (tmpLineStitch)
			{
				actions.push_back( new OE_actionSetLineStitchLen(document, tmpLineStitch, tmpLineStitch->getLen()*scale));
			}
		}
	}
}

OE_actionScaleSelectedLineStitchLen::~OE_actionScaleSelectedLineStitchLen()
{
	if (!active)
	{
		while(!actions.empty()) delete actions.front(), actions.pop_front();
	}
}

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

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

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

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

OE_actionSetSelectedLineStitchPattern::~OE_actionSetSelectedLineStitchPattern()
{
	if (!active)
	{
		while(!actions.empty()) delete actions.front(), actions.pop_front();
	}
}

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

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

