/*
 * GDevelop C++ Platform
 * Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
 * reserved. This project is released under the MIT License.
 */

#if defined(GD_IDE_ONLY)

#ifndef CPPCODEEVENT_H
#define CPPCODEEVENT_H
#include "GDCore/Events/Event.h"
namespace gd {
class Instruction;
class Project;
class SerializerElement;
class Layout;
}

/**
 * \brief Builtin internal event that pick an object of a list each time it is
 * repeated
 */
class CppCodeEvent : public gd::BaseEvent {
 public:
  CppCodeEvent();
  CppCodeEvent(const CppCodeEvent& event);
  virtual ~CppCodeEvent(){};

  CppCodeEvent& operator=(const CppCodeEvent& event);
  virtual CppCodeEvent* Clone() const { return new CppCodeEvent(*this); }

  virtual bool IsExecutable() const { return true; }
  virtual bool CanHaveSubEvents() const { return false; }

  void EnsureAssociatedSourceFileIsUpToDate(gd::Project& parentGame) const;

  const std::vector<gd::String>& GetIncludeFiles() const {
    return includeFiles;
  };
  void SetIncludeFiles(const std::vector<gd::String>& include_) {
    includeFiles = include_;
  };

  const gd::String& GetInlineCode() const { return inlineCode; };
  void SetInlineCode(const gd::String& code) { inlineCode = code; };

  const gd::String& GetFunctionToCall() const;
  void SetFunctionToCall(const gd::String& functionToCall_) {
    functionToCall = functionToCall_;
  };

  bool IsFunctionNameAutoGenerated() const {
    return functionNameAutogenerated;
  };
  void SetFunctionNameAutoGenerated(bool autogenerate) {
    functionNameAutogenerated = autogenerate;
  };

  const gd::String& GetAssociatedGDManagedSourceFile(
      gd::Project& parentGame) const {
    return associatedGDManagedSourceFile;
  };

  void SetLastChangeTimeStamp(time_t lastChangeTimeStamp_) {
    lastChangeTimeStamp = lastChangeTimeStamp_;
  }

  const std::vector<gd::String>& GetSourceFileDependencies() const {
    return dependencies;
  };
  void SetDependencies(const std::vector<gd::String>& dependencies_) {
    dependencies = dependencies_;
  };

  bool GetPassSceneAsParameter() const { return passSceneAsParameter; };
  void SetPassSceneAsParameter(bool passScene) {
    passSceneAsParameter = passScene;
  };

  bool GetPassObjectListAsParameter() const {
    return passObjectListAsParameter;
  };
  void SetPassObjectListAsParameter(bool passObjectList) {
    passObjectListAsParameter = passObjectList;
  };

  gd::String GetObjectToPassAsParameter() const {
    return objectToPassAsParameter;
  };
  void SetObjectToPassAsParameter(gd::String objectName) {
    objectToPassAsParameter = objectName;
  };

  bool IsCodeDisplayedInEditor() const { return codeDisplayedInEditor; };
  void EnableCodeDisplayedInEditor(bool enable) {
    codeDisplayedInEditor = enable;
  };

  const gd::String& GetDisplayedName() const { return displayedName; };
  void SetDisplayedName(const gd::String& displayedName_) {
    displayedName = displayedName_;
  };

  virtual void SerializeTo(gd::SerializerElement& element) const;
  virtual void UnserializeFrom(gd::Project& project,
                               const gd::SerializerElement& element);

 private:
  void Init(const CppCodeEvent& event);
  void AutogenerateFunctionName() const;

  std::vector<gd::String> includeFiles;
  std::vector<gd::String>
      dependencies;  ///< List of source files that must be compiled and loaded
                     ///< at the same time as the C++ event function.
  mutable gd::String
      functionToCall;  ///< The name of the function to call ( Typically located
                       ///< in the include file )
  bool functionNameAutogenerated;  ///< If true, the name of the function being
                                   ///< called ( and containing the inline code
                                   ///< ) will be automatically generated.
  gd::String
      inlineCode;  ///< Contains the C++ code of the event, which is inserted
                   ///< into the associated GD-managed source file
  mutable gd::String
      associatedGDManagedSourceFile;  ///< "Inline" C++ code is simulated by a
                                      ///< call to a function containing the
                                      ///< code, function located in a separate
                                      ///< source file managed by GD.
  time_t
      lastChangeTimeStamp;  ///< Time of the last change. Used to check if the
                            ///< associated source file must be regenerated.

  bool passSceneAsParameter;
  bool passObjectListAsParameter;
  gd::String objectToPassAsParameter;

  bool codeDisplayedInEditor;
  gd::String displayedName;

  bool objectsToPickSelected;
};

#endif  // CPPCODEEVENT_H

#endif
