/** \file
 *  Game Develop
 *  2008-2014 Florian Rival (Florian.Rival@gmail.com)
 */

#ifndef PLATFORM_H
#define PLATFORM_H
#include "GDCore/PlatformDefinition/Platform.h"
#include "GDCore/PlatformDefinition/PlatformExtension.h"
#include "GDCore/Tools/Localization.h"
#include "GDCpp/CommonTools.h"
#include "GDCpp/IDE/ChangesNotifier.h"
namespace gd { class Automatism; }
namespace gd { class Object; }
class RuntimeObject;
class RuntimeScene;

typedef void (*DestroyRuntimeObjectFunPtr)(RuntimeObject*);
typedef RuntimeObject * (*CreateRuntimeObjectFunPtr)(RuntimeScene & scene, const gd::Object & object);

/**
 * \brief Game Develop C++ Platform
 *
 * Platform designed to be used to create 2D games based on SFML and OpenGL libraries for rendering,
 * events being translated to C++ and then compiled using GCC.
 */
class GD_API CppPlatform : public gd::Platform
{
public:

    virtual std::string GetName() const { return "Game Develop C++ platform"; }
    #if defined(GD_IDE_ONLY)
    virtual std::string GetFullName() const { return ToString(_("Native platform")); }
    virtual std::string GetSubtitle() const { return ToString(_("C++ and OpenGL based games for Windows or Linux.")); }
    virtual std::string GetDescription() const;
    #endif

    /**
     * \brief Create a RuntimeObject from a gd::Object for a scene.
     *
     * \param scene The scene the object is going to be used on.
     * \param scene The gd::Object the RuntimeObject must be based on.
     */
    boost::shared_ptr<RuntimeObject> CreateRuntimeObject(RuntimeScene & scene, gd::Object & object);

    /**
     * \brief Our platform need to do a bit of extra work when adding an extension
     * ( i.e : Storing pointers to creation/destruction functions ).
     */
    bool AddExtension(boost::shared_ptr<gd::PlatformExtension> platformExtension);

    /** \brief The name of the function searched in an extension file to create the extension
     */
    virtual std::string GetExtensionCreateFunctionName() { return "CreateGDExtension"; }

    /** \brief The name of the function searched in an extension file to destroy the extension
     */
    virtual std::string GetExtensionDestroyFunctionName() { return "DestroyGDExtension"; }

#if defined(GD_IDE_ONLY)
    virtual std::string GetIcon() const { return "CppPlatform/icon32.png"; }

    /**
     * \brief We provide a specific ChangesNotifier to ensure that compilation jobs are done properly.
     */
    virtual ChangesNotifier & GetChangesNotifier() const { return changesNotifier; };

#if !defined(GD_NO_WX_GUI)
    /**
     * \brief Preview can be done directly inside the editor thanks to CppLayoutPreviewer
     */
    virtual boost::shared_ptr<gd::LayoutEditorPreviewer> GetLayoutPreviewer(gd::LayoutEditorCanvas & editor) const;
#endif

    /**
     * \brief Expose to the IDE how to export games.
     */
    virtual boost::shared_ptr<gd::ProjectExporter> GetProjectExporter() const;

    /**
     * \brief When destroyed, our platform need to do ensure the destruction of some singletons.
     */
    virtual void OnIDEClosed();
#endif

    /**
     * \brief Get access to the CppPlatform instance. ( CppPlatform is a singleton ).
     */
    static CppPlatform & Get();

    /**
     * \brief Destroy the singleton.
     *
     * \note You do not need usually to call this method.
     **/
    static void DestroySingleton();

    CppPlatform();
    virtual ~CppPlatform() {};
private:

    std::map < std::string, CreateRuntimeObjectFunPtr > runtimeObjCreationFunctionTable; ///< The C++ Platform also need to store functions to create runtime objects.
    std::map < std::string, DestroyRuntimeObjectFunPtr > runtimeObjDestroyFunctionTable; ///< The C++ Platform also need to store functions to destroy runtime objects.
#if defined(GD_IDE_ONLY)
    static ChangesNotifier changesNotifier;
#if !defined(GD_NO_WX_GUI)
    wxBitmap icon32;
#endif
#endif

    static CppPlatform * singleton;
};

#endif // PLATFORM_H
