/*
* 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
*/

#pragma once

#include <string>
#include <thread>
#include <mutex>
#include "stitchs/OE_stitchs.h"
#include "curves/OE_pointcurve.h"
#include "instructions/OE_instruction.h"
#include "OE_thread.h"
#include "OE_pattern.h"

class OE_actions;

namespace Pakal { class Archive; }

class OE_document
{
	public:
		class ScopeLock : public std::lock_guard<std::recursive_mutex>
		{
			public:
				ScopeLock(OE_document& doc);// : std::lock_guard<std::recursive_mutex>(doc.accessLock) {};
		};
		bool saveToFile(std::string path);
		bool loadFromFile(std::string path);

		/** Default constructor */
		OE_document();
		// OE_document(std::string filename);
		/** Default destructor */
		virtual ~OE_document();
	
		void persist(Pakal::Archive* archive);

		/** \brief the list of stitchs */
		std::list<OE_stitchs*> stitchs;

		/** \brief the list of curves */
		std::list<OE_pointcurve*> curves;
		
		/** \brief the list of threads */
		std::list<OE_thread*> threads;

		/** \brief the list of patterns */
		std::list<OE_pattern*> patterns;
	
		/** \brief the list of selected stitchs */
		std::list<OE_stitchs*> selectedStitchs;

		/** \brief the list of selected curves */
		std::list<OE_pointcurve*> selectedCurves;

		/** \brief the array of points to send to the embroideress */
		std::vector<vector_2d> instPoints;

		/** \brief the array of commands to send to the embroideress */
		std::vector<OE_instruction*> instCommand;

		/** \brief the stack of active actions */
		std::list<OE_actions*> activeActionsStack;

		/** \brief the stack of undoed actions */
		std::list<OE_actions*> undoActionsStack;

		
		/** \brief the current points stitched by the embroideress */
		unsigned int curPoint = 0;
		
		BoundingBox getBound() const;

		vector_2d getHoopSize();
		unsigned int getPulsePerMm();
		vector_2d getZeroPoint();
		void setHoopSize(vector_2d hoopSize);
		void setPulsePerMm(unsigned int pulsePerMm);
		void setZeroPoint(vector_2d zeroPoint);

		bool addCurve(OE_pointcurve* curve);
		bool addStitch(OE_stitchs* stitch);
		bool addThread(OE_thread* thread);

		void removeCurve(OE_pointcurve* curve);
		void removeStitch(OE_stitchs* stitch);
		void removeThread(OE_thread* thread);

		bool refresh();

		void lock(); // lock write
		bool trylock(); // try to lock write, return true on success
		void unlock(); // unlock write

		static std::string getWriteDialogFilters();
		static std::string getReadDialogFilters();

	private:
		/** \brief Width of the document. */
		float width;
	
		/** \brief Height of the document. */
		float height;
	
		unsigned int pulsePerMm = 20;
	
		float scale = 0.50f;
	
		vector_2d hoopSize = vector_2d(150,160) ;
	
		vector_2d zeroPoint = vector_2d(0,0) ;

		std::recursive_mutex accessLock;
};

