/*
	Copyright 2006-2021 The QElectroTech Team
	This file is part of QElectroTech.
	
	QElectroTech is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 2 of the License, or
	(at your option) any later version.
	
	QElectroTech is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License
	along with QElectroTech.  If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CUSTOM_ELEMENT_EDITOR_H
#define CUSTOM_ELEMENT_EDITOR_H
#include "../ElementsCollection/elementslocation.h"
#include "../qet.h"
#include "../qetmainwindow.h"
#include "elementscene.h"

class ElementItemEditor;
class ElementView;

/**
	This class represents an element editor, allowing users to draw, change and
	configure a particular electrical element.
*/
class QETElementEditor : public QETMainWindow {
	Q_OBJECT

	// constructor, destructor
	public:
		QETElementEditor(QWidget * = nullptr);
		~QETElementEditor() override;
	private:
		QETElementEditor(const QETElementEditor &);
		void setupActions();
		void setupMenus();
		void setupInterface();

	// attributes
	private:
		/// whether the editor is "read-only"
		bool read_only;
		/// menus
		QMenu *file_menu, *edit_menu, *paste_from_menu, *display_menu, *tools_menu;
		/// view widget for the editing scene
		ElementView *m_view;
		/// editing scene
		ElementScene *m_elmt_scene;
		/// container for widgets dedicated to primitive edition
		QDockWidget *m_tools_dock;
		/// Stack of widgets for tools_dock
		QStackedWidget *m_tools_dock_stack;
		/// label displayed when several primitives are selected
		QLabel *m_default_informations;
		/// Hash associating primitive names with their matching edition widget
		QHash<QString, ElementItemEditor *> m_editors;
		/// container for the undo list
		QDockWidget *m_undo_dock;
		/// Container for the list of existing primitives
		QDockWidget *m_parts_dock;
		/// List of primitives
		QListWidget *m_parts_list;
		/// actions for the "file" menu
		QAction *new_element, *open, *open_dxf, *open_file, *save, *save_as, *save_as_file, *reload, *quit;
		/// actions for the "edit" menu
		QAction *selectall, *deselectall, *inv_select;
		QAction *cut, *copy, *paste, *paste_in_area, *paste_from_file, *paste_from_elmt;
		QAction *undo, *redo;
		QAction *edit_delete, *edit_size_hs, *edit_names, *edit_author, *m_edit_properties;
		/// toolbars
		QToolBar *parts_toolbar, *main_toolbar, *view_toolbar, *depth_toolbar, *element_toolbar;
		/// Action group
		QActionGroup *parts, *m_zoom_ag, *m_depth_action_group;
		/// minimum window title
		QString min_title;
		/// filename of the currently edited element
		QString filename_;
		/// location of the currently edited element
		ElementsLocation location_;
		/// whether the currently edited element comes from a file or a location
		bool opened_from_file;

	// methods
	public:
		void setNames(const NamesList &);
		void setLocation(const ElementsLocation &);
		ElementsLocation location() const;
		void setFileName(const QString &);
		QString fileName() const;
		void setReadOnly(bool);
		bool isReadOnly() const;
		void fromFile(const QString &);
		void fromLocation(const ElementsLocation &);
		bool toFile(const QString &);
		bool toLocation(const ElementsLocation &location);
		bool isEditing(const ElementsLocation &);
		bool isEditing(const QString &);
		ElementScene *elementScene() const;
		void readSettings();
		void writeSettings();
		static QPointF pasteOffset();
		static QString getOpenElementFileName(QWidget * = nullptr, const QString & = QString());
		void contextMenu(QPoint p, QList<QAction *> actions = QList<QAction*>());

	signals:
		void saveToLocation(ElementsLocation loc);

	protected:
		void closeEvent(QCloseEvent *) override;
		void firstActivation(QEvent *) override;

	private:
		bool canClose();
		QWidget *clearToolsDock();
		void copyAndPasteXml(const QDomDocument &);
	
	public slots:
		void addLine();
		void addRect();
		void addEllipse();
		void addPolygon();
		void addArc();
		void addText();
		void addTerminal();
		void addDynamicTextField();
		void UncheckAddPrimitive();

		void slot_new();
		void slot_open();
		void slot_openDxf();
		void slot_openFile();
		void openRecentFile(const QString &);
		void openElement(const QString &);
		void slot_reload();
		bool slot_save();
		bool slot_saveAs();
		bool slot_saveAsFile();
		void slot_setRubberBandToView();
		void slot_setNoDragToView();
		void slot_updateInformations();
		void slot_updateMenus();
		void slot_updateTitle();
		void slot_createPartsList();
		void slot_updatePartsList();
		void slot_updateSelectionFromPartsList();
		bool checkElement();
		void pasteFromFile();
		void pasteFromElement();
		void updateCurrentPartEditor();
};

/**
	@param nameslist the new list of names for the currently edited element
*/
inline void QETElementEditor::setNames(const NamesList &nameslist) {
	m_elmt_scene -> setNames(nameslist);
}

/**
	@return the location of the currently edited element
*/
inline ElementsLocation QETElementEditor::location() const
{
	return(location_);
}

/**
	@return the filename of the currently edited element
*/
inline QString QETElementEditor::fileName() const
{
	return(filename_);
}

/**
	@return the editing scene
*/
inline ElementScene *QETElementEditor::elementScene() const
{
	return(m_elmt_scene);
}

#endif
