//-----------------------------------------------------------
// Copyright Christian Arnault LAL-Orsay CNRS
// arnault@lal.in2p3.fr
// Modified by Grigory Rybkin
// See the complete license in cmt_license.txt "http://www.cecill.info". 
//-----------------------------------------------------------

#ifndef __cmt_generators_h__
#define __cmt_generators_h__

#include "cmt_constituent.h"
#include "cmt_fragment.h"
#include "cmt_generator.h"
#include "cmt_deps_builder.h"

class AnyDocumentGenerator : public CmtGenerator
{
public:
  AnyDocumentGenerator ();

protected:
  void reset ();

  Variable m_TITLE;
  Variable m_STRUCTURED_OUTPUT;

  FragmentHandle make_header_fragment;
  FragmentHandle cleanup_header_fragment;
  FragmentHandle cleanup_fragment;
  FragmentHandle dependencies_fragment;
  FragmentHandle dependencies_and_triggers_fragment;
};

class DocumentGenerator : public AnyDocumentGenerator
{
public:
  DocumentGenerator ();
  void build (const cmt_string& package,
              const Constituent& constituent,
	      bool& dependencies,
	      const cmt_string& file = "");
  // returned bool& value indicates whether dependencies_fragment added to makefile

private:
  void reset ();
  bool analyze_file (const cmt_string& file,
		     const cmt_string& constituent_name,
		     const cmt_string& output_suffix);

  Variable m_FILEEXTENSION;

  FragmentHandle document_header_fragment;
  FragmentHandle dependency_fragment;
};

class LibraryGenerator : public AnyDocumentGenerator
{
public:
  LibraryGenerator ();
  void build (const cmt_string& package,
              const Constituent& constituent,
	      bool& dependencies,
	      const cmt_string& file = "");
  // returned bool& value indicates whether dependencies_fragment added to makefile

protected:
  void reset ();
  bool analyze_file (const Constituent& constituent,
		     const cmt_string& file);
  void java_file_action (SourceFile& file, const Constituent& constituent);
  void proto_file_action (const cmt_string& file, const Constituent& constituent);
  void prepare_proto_file (const cmt_string& file);
  void module_file_action (SourceFile& file, const Constituent& constituent);
  void fill_names_outputs ();

  FragmentHandle library_header_fragment;
  FragmentHandle application_header_fragment;
  FragmentHandle java_header_fragment;
  FragmentHandle jar_header_fragment;
  FragmentHandle library_fragment;
  FragmentHandle library_no_share_fragment;
  FragmentHandle library_no_static_fragment;
  FragmentHandle application_fragment;
  FragmentHandle jar_fragment;
  FragmentHandle java_fragment;
  FragmentHandle java_copy_fragment;
  FragmentHandle cleanup_library_fragment;
  FragmentHandle cleanup_application_fragment;
  FragmentHandle cleanup_java_fragment;
  FragmentHandle cleanup_objects_fragment;
  FragmentHandle buildproto_fragment;
  FragmentHandle check_application_fragment;
  FragmentHandle check_java_fragment;
  FragmentHandle protos_header_fragment;
};

class ApplicationGenerator : public LibraryGenerator
{
public:
};

class ReadmeGenerator : public CmtGenerator
{
public:
  ReadmeGenerator ();
  void build (const CmtSystem::cmt_string_vector& arguments);

private:
  void reset ();

  FragmentHandle readme_header_fragment;
  FragmentHandle readme_fragment;
  FragmentHandle readme_doc_fragment;
  FragmentHandle readme_use_fragment;
  FragmentHandle readme_trailer_fragment;
};

class PrototypeGenerator : public CmtGenerator
{
public:
  void build (const cmt_string& file_name);
};

class DefaultMakefileGenerator : public CmtGenerator
{
public:
  void build ();
};

class MSDEVGenerator : public CmtGenerator
{
public:
  MSDEVGenerator ();
  int build_workspace (const Constituent::ConstituentVector& constituents);
  int build_project (const Constituent& constituent);

private:
  void reset ();

  cmt_string msdevdir;

  FragmentHandle dsw_header_fragment;
  FragmentHandle dsw_project_fragment;
  FragmentHandle dsw_all_project_header_fragment;
  FragmentHandle dsw_all_project_dependency_fragment;
  FragmentHandle dsw_all_project_trailer_fragment;
  FragmentHandle dsw_trailer_fragment;

  FragmentHandle dsp_all_fragment;
  FragmentHandle dsp_library_header_fragment;
  FragmentHandle dsp_application_header_fragment;
  FragmentHandle dsp_windows_header_fragment;
  FragmentHandle dsp_contents_fragment;
  FragmentHandle dsp_trailer_fragment;

};

class VSNETGenerator : public CmtGenerator
{
public:
  VSNETGenerator ();
  int build_workspace (const Constituent::ConstituentVector& constituents);
  int build_project (const Constituent& constituent);

private:
  void reset ();

  void pseudoGUID (const cmt_string& a, 
                   const cmt_string& b, 
                   const cmt_string& c, 
                   cmt_string& d);

  cmt_string vsnetdir;

    //Visual Studio.net Support
  FragmentHandle sln_header_fragment;
  FragmentHandle sln_project_fragment;
  FragmentHandle sln_dependency_header_fragment;
  FragmentHandle sln_dependency_project_fragment;
  FragmentHandle sln_dependency_trailer_fragment;
  FragmentHandle sln_project_config_fragment;
  FragmentHandle sln_trailer_fragment;

  FragmentHandle vcproj_all_fragment;
  FragmentHandle vcproj_library_header_fragment;
  FragmentHandle vcproj_application_header_fragment;
  FragmentHandle vcproj_windows_header_fragment;
  FragmentHandle vcproj_contents_fragment;
  FragmentHandle vcproj_directory_header_fragment;
  FragmentHandle vcproj_directory_trailer_fragment;
  FragmentHandle vcproj_trailer_fragment;
};

class MakeSetupGenerator : public CmtGenerator
{
public:
  MakeSetupGenerator ();
  void build (const cmt_string& package);

private:
  void reset ();

  FragmentHandle make_setup_header_fragment;
  FragmentHandle make_setup_fragment;
};

class ConstituentsMakefileGenerator : public CmtGenerator
{
public:
  ConstituentsMakefileGenerator ();
  void build (const cmt_string& package,
	      const cmt_string& file);
  //	      const CmtSystem::cmt_string_vector& arguments);

private:
  void reset ();

  FragmentHandle constituents_header_fragment;
  FragmentHandle constituents_trailer_fragment;
  FragmentHandle group_fragment;
  FragmentHandle constituent_fragment;
  FragmentHandle constituent_lock_fragment;
  FragmentHandle constituent_app_lib_fragment;
  FragmentHandle check_application_header_fragment;
};

class PackagesMakefileGenerator : public CmtGenerator
{
public:
  PackagesMakefileGenerator ();
  void build (const cmt_string& package,
	      const cmt_string& file);
  //	      const CmtSystem::cmt_string_vector& arguments);

private:
  void reset ();

  Variable m_DEPENDENCIES;
  Variable m_PACKAGEMGRPATH;
  Variable m_PACKAGEFULLNAME;
  Variable m_ISLOCAL;
  Variable m_ISINCLUDED;

  FragmentHandle packages_header_fragment;
  FragmentHandle packages_trailer_fragment;
  FragmentHandle package_fragment;
};

class DependencyGenerator : public CmtGenerator
{
public:
  void build (const CmtSystem::cmt_string_vector& arguments);
  void prepare_includes ();
  void prepare_header_file_filters ();
  void reset ();

protected:
  int set_source_files ();
  int set_source_files (const CmtSystem::cmt_string_vector& files);
  int validate (const CmtSystem::cmt_string_vector& files) const;

private:
  void add_line_to_text (const cmt_string& line, cmt_string& text) const;
  cmt_string build (const cmt_string& file_name);
  int fill_dependencies (cmt_string& dependencies,
			 const CmtSystem::cmt_string_vector& source);
  int fill_dependencies (cmt_string& dependencies);
  DepsBuilder m_deps_builder;
  bool m_stamps;
  cmt_string m_name;
};

#endif
