/*
 * Copyright (C) 2014-2024 CZ.NIC
 *
 * This program 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 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations including
 * the two.
 */

#pragma once

#include <QDialog>

#include "src/datovka_shared/json/basic.h" /* Json::Int64StringList is used in slots. Q_MOC_INCLUDE */
#include "src/delegates/tags_delegate.h"
#include "src/io/tag_client.h"
#include "src/json/tag_entry.h" /* Json::TagEntryList is used in slots. Q_MOC_INCLUDE */
#include "src/models/combo_box_model.h"
#include "src/models/tags_model.h"

class TagContainer; /* Forward declaration. */
class TagContainerSettings; /* Forward declaration. */
class TagDb; /* Forward declaration. */

namespace Ui {
	class DlgTagSettings;
}

/*!
 * @brief Create new tag settings dialogue.
 */
class DlgTagSettings : public QDialog {
	Q_OBJECT

private:
	/*!
	 * @brief Constructor.
	 *
	 * @param[in] tagContSet Tag container settings to be modified.
	 * @param[in] parent Parent widget.
	 */
	explicit DlgTagSettings(const TagContainerSettings &tagContSet,
	    TagDb *localTagDb, QWidget *parent = Q_NULLPTR);

public:
	/*!
	 * @brief Destructor.
	 */
	~DlgTagSettings(void);

	/*!
	 * @brief Edit tag container settings.
	 *
	 * @param[in,out] tagContSet Tag container settings to be modified.
	 * @param[in,out] tagCont Tag container to be modified.
	 * @param[in] parent Parent widget.
	 * @return True when settings been changed.
	 */
	static
	bool editTagContSettings(TagContainerSettings &tagContSet,
	    TagContainer &tagCont, QWidget *parent = Q_NULLPTR);

private slots:
	/*!
	 * @brief Enables buttons according to content.
	 */
	void activateServiceButtons(void);

	/*!
	 * @brief Enable client part if client selected.
	 */
	void clientSelected(bool selected);

	/*!
	 * @brief Choose certificate file.
	 */
	void selectCertFile(void);

	/*!
	 * @brief Check client connection.
	 */
	void checkClientConnection(void);

	/*!
	 * @brief Download profile list.
	 */
	void downloadProfileList(void);

	/*!
	 * @brief Change profile for local client.
	 *
	 * @param[in] index Profile index.
	 */
	void changeProfile(int index);

	/*!
	 * @brief Activate/deactivate buttons on local selection change.
	 */
	void handleLocalSelectionChange(void);

	/*!
	 * @brief Update local tag (update data in database).
	 */
	void updateLocalTag(void);

	/*!
	 * @brief Send selected tag(s) to server (insert into database).
	 */
	void sendSelectedTagsToServer(void);

	/*!
	 * @brief Activate/deactivate buttons on server selection change.
	 */
	void handleServerSelectionChange(void);

	/*!
	 * @brief Update server tag (update data in database).
	 */
	void updateServerTag(void);

	/*!
	 * @brief Watch client connected.
	 */
	void watchConnected(void);

	/*!
	 * @brief Watch client disconnected.
	 */
	void watchDisconnected(void);

/* Handle database signals. */
	/*!
	 * @brief Update model data when new tags are created.
	 *
	 * @param[in] entries Newly added tag entries.
	 */
	void watchLocalTagsInserted(const Json::TagEntryList &entries);

	/*!
	 * @brief Update model data when tags updated.
	 *
	 * @param[in] entries Updated tag entries.
	 */
	void watchLocalTagsUpdated(const Json::TagEntryList &entries);

	/*!
	 * @brief Update model data when tags deleted.
	 *
	 * @param[in] ids Deleted tag identifiers.
	 */
	void watchLocalTagsDeleted(const Json::Int64StringList &ids);

	/*!
	 * @brief Update model data when new tags are created.
	 *
	 * @param[in] entries Newly added tag entries.
	 */
	void watchServerTagsInserted(const Json::TagEntryList &entries);

	/*!
	 * @brief Update model data when tags updated.
	 *
	 * @param[in] entries Updated tag entries.
	 */
	void watchServerTagsUpdated(const Json::TagEntryList &entries);

	/*!
	 * @brief Update model data when tags deleted.
	 *
	 * @param[in] ids Deleted tag identifiers.
	 */
	void watchServerTagsDeleted(const Json::Int64StringList &ids);

private:
	/*!
	 * @brief Initialise dialogue content.
	 */
	void initDialogue(const TagContainerSettings &tagContSet);

	/*!
	 * @brief Set icon set to buttons.
	 */
	void setIcons(void);

	Ui::DlgTagSettings *m_ui; /*!< UI generated from UI file. */

	const TagContainerSettings &m_tagContSet; /*!< Tag container settings to be modified. */
	TagClient m_tagClient; /*!< Tag client used to check the connection. */
	CBoxModel m_profileModel; /*!< Profile list for combo box. */

	TagDb *m_localTagDb; /*!< Local tag database. */
	TagsDelegate m_localTagsDelegate; /*!< Responsible for painting. */
	TagsModel m_localTagsModel; /*!< Local tags model. */

	TagsDelegate m_serverTagsDelegate; /*!< Responsible for painting. */
	TagsModel m_serverTagsModel; /*!< Server tags model. */
};
