#ifndef MUDLET_XMLEXPORT_H
#define MUDLET_XMLEXPORT_H

/***************************************************************************
 *   Copyright (C) 2008-2011 by Heiko Koehn - KoehnHeiko@googlemail.com    *
 *   Copyright (C) 2014 by Ahmed Charles - acharles@outlook.com            *
 *   Copyright (C) 2017-2019, 2022 by Stephen Lyons                        *
 *                                               - slysven@virginmedia.com *
 *   Copyright (C) 2017 by Ian Adkins - ieadkins@gmail.com                 *
 *                                                                         *
 *   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 2 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, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include <QClipboard>
#include <QFuture>
#include <QPointer>
#include <QSaveFile>
#include <pugixml.hpp>
#include <memory>

class QFile;
class Host;
class LuaInterface;
class TAction;
class TAlias;
class TKey;
class TScript;
class TTimer;
class TTrigger;
class TVar;
class VarUnit;


class XMLexport : public QObject, public std::enable_shared_from_this<XMLexport>
{
    Q_OBJECT

public:
    explicit XMLexport(Host*);
    explicit XMLexport(TTrigger*);
    explicit XMLexport(TTimer*);
    explicit XMLexport(TAlias*);
    explicit XMLexport(TAction*);
    explicit XMLexport(TScript*);
    explicit XMLexport(TKey*);

    void writeHost(Host*, pugi::xml_node hostPackage);
    void writeTrigger(TTrigger*, pugi::xml_node xmlParent);
    void writeTimer(TTimer*, pugi::xml_node xmlParent);
    void writeAlias(TAlias*, pugi::xml_node xmlParent);
    void writeAction(TAction*, pugi::xml_node xmlParent);
    void writeScript(TScript*, pugi::xml_node xmlParent);
    void writeKey(TKey*, pugi::xml_node xmlParent);
    void writeVariable(TVar*, LuaInterface*, VarUnit*, pugi::xml_node xmlParent);
    void writeModuleXML(const QString& moduleName, const QString& fileName, bool async = false);

    bool exportHost(const QString& filename_pugi_xml);
    bool writeGenericPackage(Host* pHost, pugi::xml_node& mMudletPackage, bool ignoreModuleMember = true, bool ignoreVariables = false);
    bool exportProfile(const QString& exportFileName);
    bool exportPackage(const QString &exportFileName, bool ignoreModuleMember = true, bool ignoreVariables = false);
    bool exportTrigger(const QString& fileName);
    bool exportTimer(const QString& fileName);
    bool exportAlias(const QString& fileName);
    bool exportAction(const QString& fileName);
    bool exportScript(const QString& fileName);
    bool exportKey(const QString& fileName);

    void exportToClipboard(TTrigger*);
    void exportToClipboard(TTimer*);
    void exportToClipboard(TAlias*);
    void exportToClipboard(TAction*);
    void exportToClipboard(TScript*);
    void exportToClipboard(TKey*);

    void writeScriptElement(const QString&, pugi::xml_node xmlElement);

    QVector<QFuture<bool>> saveFutures;

private:
    QPointer<Host> mpHost;
    TTrigger* mpTrigger{nullptr};
    TTimer* mpTimer{nullptr};
    TAlias* mpAlias{nullptr};
    TAction* mpAction{nullptr};
    TScript* mpScript{nullptr};
    TKey* mpKey{nullptr};
    pugi::xml_document mExportDoc;

    void writeTriggerPackage(const Host* pHost, pugi::xml_node& mMudletPackage, bool skipModuleMembers);
    void writeTimerPackage(const Host* pHost, pugi::xml_node& mMudletPackage, bool skipModuleMembers);
    void writeAliasPackage(const Host* pHost, pugi::xml_node& mMudletPackage, bool skipModuleMembers);
    void writeActionPackage(const Host* pHost, pugi::xml_node& mMudletPackage, bool skipModuleMembers);
    void writeScriptPackage(const Host* pHost, pugi::xml_node& mMudletPackage, bool skipModuleMembers);
    void writeKeyPackage(const Host* pHost, pugi::xml_node& mMudletPackage, bool skipModuleMembers);
    void writeVariablePackage(Host* pHost, pugi::xml_node& mMudletPackage);
    static inline void replaceAll(std::string& source, const std::string& from, const std::string& to);
    bool saveXmlFile(QSaveFile& file);
    bool saveXml(const QString&);
    static bool saveXmlDocToFile(const QString& fileName, const pugi::xml_document& doc);
    pugi::xml_node writeXmlHeader();
    static void sanitizeForQxml(std::string& output);
    void runAsyncSave(const QString& fileName, const QString& xmlSavedKey);
    QString saveXml();
    QStringList remapAnsiToColorNumber(const QStringList&, const QList<int>&);
};

#endif // MUDLET_XMLEXPORT_H
