/*****************************************************************************
 * $CAMITK_LICENCE_BEGIN$
 *
 * CamiTK - Computer Assisted Medical Intervention ToolKit
 * (c) 2001-2016 Univ. Grenoble Alpes, CNRS, TIMC-IMAG UMR 5525 (GMCAO)
 *
 * Visit http://camitk.imag.fr for more information
 *
 * This file is part of CamiTK.
 *
 * CamiTK is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * CamiTK 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 Lesser General Public License version 3 for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with CamiTK.  If not, see <http://www.gnu.org/licenses/>.
 *
 * $CAMITK_LICENCE_END$
 ****************************************************************************/

#ifndef CEPGENERATOR_H
#define CEPGENERATOR_H

// includes from STL (for Linux) for std::auto_ptr
#include <memory>

// includes from Qt
#include <QDir>
#include <QString>
#include <QFileInfo>
#include <QVector>

// Hide warning for Exception + declspec(nothrow)
#if defined(_WIN32) && !defined(__MINGW32__) // MSVC only
#pragma warning( disable : 4290 )
#endif // MSVC only

// Dependency from cepcoreschema
// Declaration here to avoid declaration in dependant projects.
namespace cepcoreschema {
class Cep;
}

class ExtensionGenerator;

/**
 * @ingroup group_sdk_libraries_cepgenerator
 *
 * @brief
 * This class contains the entry points to generate CEP.
 *
 * A CEP is generated form an XML file or from a dom xml-schema. \n
 * See https://forge.imag.fr/plugins/mediawiki/wiki/camitk/index.php/CEP to understand how a CEP is buildt. \n
 * <b>Release 3.5: Suppose that the CEP does NOT already exist. </b>
 *
 **/
class CepGenerator {
public :

    /**
    * Create a CEPGenerator from the XML file \c xmlFileName in the directory \c devDirectoryName. \n
    *
    * <b>Supposes that the CEP does NOT exist.</b>
    * Create a domCep from the XML file
    *
    **/
    CepGenerator(QString xmlFilename, QString devDirectoryName);

    /**
    * Create a CEPGenerator from the DOM XML-schema \c domCep in the directory \c devDirectoryName. \n
    *
    * <b>Supposes that the CEP does NOT exist.</b>
    *
    **/
    CepGenerator(std::auto_ptr<cepcoreschema::Cep> domCep, QString devDirectoryName);

    ~CepGenerator();

    /// call all methods to generate the CEP from the DomTree.
    void process() throw (QString);

protected:


    /// Set the input XML CEP manifest (ant check its xml validity)
    virtual void setXmlFileName(QString xmlFileName) throw (QString);

    /// Where to generate the CEP directories and files
    virtual void setDevDirectoryName(QString devDirectoryName) throw (QString);

    /** Create the general directory tree (the same for every CEP)
            Copies the default files in the right directories:

                cepdirectoryname
                    |
                    +--- actions
                        |
                        ---- CMakeLists.txt
                    ----- CMakeLists.txt
                    +--- components
                        |
                        ---- CMakeLists.txt
                    ---- COPYRIGHT
                    ---- FindCamiTK.cmake
                    +--- libraries
                        |
                        --- CMakeLists.txt
                    ---- Manifest.xml
                    ---- README
        */
    virtual void generateDirectoryTree() throw(QString);

    /** @{ Helping Functions  for generateDirectoryTree */

    /// Serialize the manifest ie serialize the domCep to a std::string
    virtual void serializeManifest();

    /// Generate CMakeLists file
    virtual void generateGlobalCMakeLists();

    /// Generate copyright file
    virtual void generateCopyright();

    /// Generate Readme File
    virtual void generateReadme();

    /// Generate the FindCamiTK file
    virtual void copyFindCamiTK();

    /// Generate the Actions directory
    virtual void generateActionsDirectory();

    /// Generate the Applications directory
    virtual void generateApplicationsDirectory();

    /// Generate the Components directory
    virtual void generateComponentsDirectory();

    /// Generate the Libraries directory
    virtual void generateLibrariesDirectory();

    /// Set the licence ine the \c licence variable to be included later in the generated files.
    virtual void setLicence();
    /** @} */

    /**
    Create the ActionExtensionDom if needed and call the appropriate methods to generate the actions Extensions.
    */
    virtual void createActionExtensionDoms();

    /**
    Create the ComponentExtensionDom if needed and call the appropriate methods to generate the components Extensions.
    */
    virtual void createComponentExtensionDoms();

    /**
    Create the LibrariesDom if needed and call the appropriate methods to generate the libraries.
    */
    virtual void createLibrarieDoms();

    virtual void generateExtensions();

private:

    /// Create the DOM attribute domCep from the XML CEP manifest
    virtual void createDomTree() throw (QString);



    /** XML DOM Element create by CodeSynthesis
            This cep instance contains all of the informations of the xml file
        */
    std::auto_ptr<cepcoreschema::Cep> domCep;

    /// Where to find the original XML description of the CEP
    QFileInfo xmlFileName;

    /// Where to store the produced files
    QDir devDirectoryName;

    /// Subdirectory where the CEP sources will be stored (updated when generating the directory tree)
    QString cepDirectoryName;


    /// Action or Component Extensions
    QVector<ExtensionGenerator *> extensions;

    /// Action Extensions
//    QVector<ActionExtensionGenerator *> actionExtensions;

    /// Component Extensions
//    QVector<ComponentExtensionGenerator *> componentExtensions;

    QString licence;

};

#endif // CEPGENERATOR_H
