//==================================================================================================
// M e t a _ m o d e l                                                                    Interface
// H t m l _ g e n e r a t i o n
//                                                                                By Bruno Bachelet
//==================================================================================================
// Copyright (c) 1999-2016
// Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net
//
// This file is part of the B++ Library. This library is free software; you can redistribute it
// and/or modify it under the terms of the GNU Library General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This library 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 Library General Public License for more details (http://www.gnu.org).

/*DESCRIPTION*/
/* This module provides facilities to generate HTML documentation from an instantiation of the
   meta-model. */

// File Name //-------------------------------------------------------------------------------------
#line __LINE__ "meta_model/html_generation.hpp"

// Guardian //--------------------------------------------------------------------------------------
#ifndef guMetaModelHtmlGeneration
#define guMetaModelHtmlGeneration

// Headers //---------------------------------------------------------------------------------------
#include <bpp/meta_model/structure.hpp> /*INCLUDE*/
#include <bpp/text_format.hpp> /*INCLUDE*/

namespace bpp {

// Importation/Exportation //-----------------------------------------------------------------------
#ifdef META_MODEL_DLL
 #define dll_export DLL_EXPORT
#else
 #define dll_export DLL_IMPORT
#endif

// Namespaces //------------------------------------------------------------------------------------
#define public_area  metaModelHtmlGeneration
#define private_area metaModelHtmlGeneration_private

namespace public_area  {
 /*NAMESPACE*/ using namespace metaModelStructure;
 /*NAMESPACE*/ using namespace textFormatHtml;
}

namespace private_area { using namespace public_area; }

extern_module_name;

// Initialization //--------------------------------------------------------------------------------
#define iniMetaModelHtmlGeneration
has_initializer;

// Macrocommands //---------------------------------------------------------------------------------

// Types & Classes //-------------------------------------------------------------------------------
namespace public_area {}

namespace private_area {
 structure {
  tyCardinal classes;
  tyCardinal functions;
  tyCardinal macrocommands;
  tyCardinal methods;
 }
 tyElementCounters;
}

// Functions Interface //---------------------------------------------------------------------------
namespace public_area {
 function void makeDocumentation(tcString,clModuleInformationX &,ctModuleInformation &,
                                 ctHtmlTemplate &);

 function void makeDocumentation(tcString,clModuleInformationX &,ctHtmlTemplate &,tyBoolean=true);
 function void makeSourceCodePage(tcString,ctModuleInformation &,ctHtmlTemplate &);
}

namespace private_area {
 function void      copySourceCode(clHtmlFile &,tcString,tyElementCounters &);
 function void      copySourceCodeUntil(clHtmlFile &,clInFile &,tyStreamPosition,tyBoolean=false);
 function tyBoolean getCharacter(clInFile &,tyCharacter &,tyStreamPosition);
 function void      makeAliases(clHtmlFile &,clHtmlFile &,ctModuleInformation &);

 function void makeChildren(clHtmlFile &,clHtmlFile &,clModuleInformationX &,
                            ctModuleInformation &);

 function void makeClasses(clHtmlFile &,clHtmlFile &,ctModuleInformation &);
 function void makeConstants(clHtmlFile &,clHtmlFile &,ctModuleInformation &);
 function void makeDescription(clHtmlFile &,clHtmlFile &,ctModuleInformation &);
 function void makeErrors(clHtmlFile &,clHtmlFile &,ctModuleInformation &);
 function void makeFileList(clHtmlFile &,const std_vector(clString) &,clModuleInformationX &);
 function void makeFunctions(clHtmlFile &,clHtmlFile &,ctModuleInformation &);

 function void makeIncludes(clHtmlFile &,clHtmlFile &,clModuleInformationX &,
                            ctModuleInformation &);

 function void makeMacrocommands(clHtmlFile &,clHtmlFile &,ctModuleInformation &);

 function void makeNamespaces(clHtmlFile &,clHtmlFile &,clModuleInformationX &,
                              ctModuleInformation &);

 function void makeNeeds(clHtmlFile &,clHtmlFile &,clModuleInformationX &,
                         ctModuleInformation &);

 function void makeParent(clHtmlFile &,clHtmlFile &,clModuleInformationX &,
                          ctModuleInformation &);

 function void makeSourceFiles(clHtmlFile &,clHtmlFile &,ctModuleInformation &);
 function void makeSubtitle(clHtmlFile &,clHtmlFile &,tcString,tcString,ctModuleInformation &);
 function void makeTitle(clHtmlFile &,ctModuleInformation &);
 function void makeTypes(clHtmlFile &,clHtmlFile &,ctModuleInformation &);
 function void makeVariables(clHtmlFile &,clHtmlFile &,ctModuleInformation &);
}

// Errors //----------------------------------------------------------------------------------------
namespace public_area {}

// Constants & Variables //-------------------------------------------------------------------------
extern_static_constant(private,tcString,goListFileName,?);

extern_static_constant(private,tcString,goAliasesFlag,?);
extern_static_constant(private,tcString,goChildrenFlag,?);
extern_static_constant(private,tcString,goClassesFlag,?);
extern_static_constant(private,tcString,goConstantsFlag,?);
extern_static_constant(private,tcString,goDescriptionFlag,?);
extern_static_constant(private,tcString,goErrorsFlag,?);
extern_static_constant(private,tcString,goFunctionsFlag,?);
extern_static_constant(private,tcString,goImplementationFlag,?);
extern_static_constant(private,tcString,goIncludes,?);
extern_static_constant(private,tcString,goInterfaceFlag,?);
extern_static_constant(private,tcString,goMacrocommands,?);
extern_static_constant(private,tcString,goNamespaces,?);
extern_static_constant(private,tcString,goNeeds,?);
extern_static_constant(private,tcString,goParentFlag,?);
extern_static_constant(private,tcString,goSourceFilesFlag,?);
extern_static_constant(private,tcString,goTypesFlag,?);
extern_static_constant(private,tcString,goVariablesFlag,?);

extern_static_constant(private,tcString,goClassFlag,?);
extern_static_constant(private,tcString,goFunctionFlag,?);
extern_static_constant(private,tcString,goMacrocommandFlag,?);
extern_static_constant(private,tcString,goMethodFlag,?);

extern_static_constant(private,tcString,goCodeWindowName,?);

// X X X  Interface //------------------------------------------------------------------------------
namespace {}

// Functions Inline //------------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// X X X  Inline //---------------------------------------------------------------------------------
namespace {}

// End //-------------------------------------------------------------------------------------------
}
#undef dll_export
#undef public_area
#undef private_area
#endif
 
//==================================================================================================
// M e t a _ m o d e l                                                               Implementation
// H t m l _ g e n e r a t i o n
//                                                                                By Bruno Bachelet
//==================================================================================================
// Copyright (c) 1999-2016
// Bruno Bachelet - bruno@nawouak.net
//
// This file is part of the B++ Library. This library is free software you can redistribute it
// and/or modify it under the terms of the GNU Library General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your option) any later
// version.
//
// This library 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 Library General Public License for more details.
//
// You should have received a copy of the GNU Library General Public License along with this
// library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.

// File Name //-------------------------------------------------------------------------------------
#line __LINE__ "meta_model/html_generation.cpp"

// DLL Belonging //---------------------------------------------------------------------------------
#define META_MODEL_DLL

// Headers //---------------------------------------------------------------------------------------
#include <bpp/calendar.hpp> /*NEED*/
#include <bpp/meta_model/html_generation.hpp> /*INTERFACE*/
#include <bpp/meta_model/information_extraction.hpp> /*NEED*/

namespace bpp {

// Namespaces //------------------------------------------------------------------------------------
#define public_area  metaModelHtmlGeneration
#define private_area metaModelHtmlGeneration_private
#define dll_export   DLL_EXPORT

namespace public_area  {}
namespace private_area {}

static_module_name("Meta_model/Html_generation");

// Initialization //--------------------------------------------------------------------------------
#undef iniMetaModelHtmlGeneration
static_constant(private_area::clInitializer,goInitializer);

// Errors //----------------------------------------------------------------------------------------
namespace public_area {}

// Constants & Variables //-------------------------------------------------------------------------
static_constant(tcString,goListFileName);

static_constant(tcString,goAliasesFlag);
static_constant(tcString,goChildrenFlag);
static_constant(tcString,goClassesFlag);
static_constant(tcString,goConstantsFlag);
static_constant(tcString,goDescriptionFlag);
static_constant(tcString,goErrorsFlag);
static_constant(tcString,goFunctionsFlag);
static_constant(tcString,goImplementationFlag);
static_constant(tcString,goIncludesFlag);
static_constant(tcString,goInterfaceFlag);
static_constant(tcString,goMacrocommandsFlag);
static_constant(tcString,goNamespacesFlag);
static_constant(tcString,goNeedsFlag);
static_constant(tcString,goParentFlag);
static_constant(tcString,goSourceFilesFlag);
static_constant(tcString,goTypesFlag);
static_constant(tcString,goVariablesFlag);

static_constant(tcString,goClassFlag);
static_constant(tcString,goFunctionFlag);
static_constant(tcString,goMacrocommandFlag);
static_constant(tcString,goMethodFlag);

static_constant(tcString,goCodeWindowName);

// Static Members //--------------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// Functions Implementation //----------------------------------------------------------------------
namespace public_area  {
 //--------------------------------------------------------------------------------MakeDocumentation
 /*FUNCTION*/ /* Generates the HTML documentation of a module. */
 function void makeDocumentation(tcString agFolder,clModuleInformationX & agInformationX,
                                 ctModuleInformation & agInformation,ctHtmlTemplate & agTemplate) {
  clHtmlFile lcIndexFile(agTemplate);
  clHtmlFile lcHomeFile(agTemplate);
  clHtmlFile lcMenuFile(agTemplate);

  clString lcFullName;
  clString lcString;

  buildFullName(lcFullName,clString(agFolder),agInformation.indexTargetFile());
  lcIndexFile=lcFullName.data();
  buildFullName(lcFullName,clString(agFolder),agInformation.homeTargetFile());
  lcHomeFile=lcFullName.data();
  buildFullName(lcFullName,clString(agFolder),agInformation.menuTargetFile());
  lcMenuFile=lcFullName.data();

  lcIndexFile.signature().framePage("");
  lcString=clString("B++ Library / \"")+agInformation.name()+"\" Module";
  lcHomeFile.signature().normalPage(lcString.data());
  lcMenuFile.signature().menuPage("");

  lcIndexFile.frame(lcIndexFile.mainFrameName(),agInformation.homeTargetFile().data());

  lcIndexFile.frame("",agInformation.menuTargetFile().data());
  lcIndexFile.terminate();

  private_area::makeTitle(lcHomeFile,agInformation);

  if (agInformation.description()!="")
   private_area::makeDescription(lcHomeFile,lcMenuFile,agInformation);
  else lcMenuFile << "Description";

  lcMenuFile << " - ";

  if (agInformation.hppSourceFile()!="")
   private_area::makeSourceFiles(lcHomeFile,lcMenuFile,agInformation);
  else lcMenuFile << "Source Files";

  lcMenuFile << " - ";

  if (agInformation.parent()!="")
   private_area::makeParent(lcHomeFile,lcMenuFile,agInformationX,agInformation);
  else lcMenuFile << "Parent Module";

  lcMenuFile << " - ";

  if (agInformation.children().size()>0)
   private_area::makeChildren(lcHomeFile,lcMenuFile,agInformationX,agInformation);
  else lcMenuFile << "Child Modules";

  lcMenuFile << " - ";

  if (agInformation.includes().size()>0)
   private_area::makeIncludes(lcHomeFile,lcMenuFile,agInformationX,agInformation);
  else lcMenuFile << "Included Files";

  lcMenuFile << " - ";

  if (agInformation.needs().size()>0)
   private_area::makeNeeds(lcHomeFile,lcMenuFile,agInformationX,agInformation);
  else lcMenuFile << "Needed Files";

  lcMenuFile.breakLine();

  if (agInformation.namespaces().size()>0)
   private_area::makeNamespaces(lcHomeFile,lcMenuFile,agInformationX,agInformation);
  else lcMenuFile << "Integrated Namespaces";

  lcMenuFile << " - ";

  if (agInformation.aliases().size()>0)
   private_area::makeAliases(lcHomeFile,lcMenuFile,agInformation);
  else lcMenuFile << "Aliases";

  lcMenuFile << " - ";

  if (agInformation.macrocommands().size()>0)
   private_area::makeMacrocommands(lcHomeFile,lcMenuFile,agInformation);
  else lcMenuFile << "Macrocommands";

  lcMenuFile << " - ";

  if (agInformation.types().size()>0)
   private_area::makeTypes(lcHomeFile,lcMenuFile,agInformation);
  else lcMenuFile << "Types";

  lcMenuFile << " - ";

  if (agInformation.errors().size()>0)
   private_area::makeErrors(lcHomeFile,lcMenuFile,agInformation);
  else lcMenuFile << "Errors";

  lcMenuFile << " - ";

  if (agInformation.constants().size()>0)
   private_area::makeConstants(lcHomeFile,lcMenuFile,agInformation);
  else lcMenuFile << "Constants";

  lcMenuFile << " - ";

  if (agInformation.variables().size()>0)
   private_area::makeVariables(lcHomeFile,lcMenuFile,agInformation);
  else lcMenuFile << "Variables";

  lcMenuFile << " - ";

  if (agInformation.functions().size()>0)
   private_area::makeFunctions(lcHomeFile,lcMenuFile,agInformation);
  else lcMenuFile << "Functions";

  lcMenuFile << " - ";

  if (agInformation.classes().size()>0)
   private_area::makeClasses(lcHomeFile,lcMenuFile,agInformation);
  else lcMenuFile << "Classes";

  lcHomeFile.copyright();
  //lcHomeFile.table("100%","0").row().cell().center().little() << "Last Update: ";
  //lcHomeFile << calendarGregorian::current().date(calendarGregorian::monthFirstLongDate,false);
  //lcHomeFile << 5;
  lcHomeFile.terminate();
  lcIndexFile.terminate();
  lcMenuFile.terminate();
 }
 //--------------------------------------------------------------------------------MakeDocumentation
 /*FUNCTION*/ /* Generates the HTML documentation of a library. */
 function void makeDocumentation(tcString agFolder,clModuleInformationX & agInformationX,
                                 ctHtmlTemplate & agTemplate,tyBoolean agDisplayed) {
  ctModuleInformationX::const_iterator lcCurrentModule = agInformationX.begin();
  ctModuleInformationX::const_iterator lcLastModule    = agInformationX.end();

  clString              lcFullName;
  clModuleInformation * lcInformation;

  clHtmlFile lcListFile(agTemplate);

  buildFullName(lcFullName,clString(agFolder),clString(private_area::goListFileName));
  lcListFile=lcFullName.data();
  lcListFile.signature().normalPage("B++ Library / Modules").title1();
  lcListFile << "THE MODULES";
  lcListFile.breakLine() << "OF THE B++ LIBRARY" << 1;
  lcListFile.table("","0").row().cell().code();

  while (lcCurrentModule!=lcLastModule) {
   lcInformation=(*lcCurrentModule).second;
   if (agDisplayed) environment::out(lcInformation->name().data(),true,true);
   if (lcInformation->level()!=0) lcListFile.horizontalSpace(2*lcInformation->level());
   lcListFile << "- ";
   lcListFile.link(lcListFile.homeFrameName(),lcInformation->indexTargetFile().data());
   lcListFile << lcInformation->shortName().data() << 1;

   if (lcInformation->isJava()) lcListFile.horizontalSpace(1).little() << "(Java)" << 1;
   else lcListFile.horizontalSpace(1).little() << "(C++)" << 1;

   lcListFile.breakLine();
   makeDocumentation(agFolder,agInformationX,*lcInformation,agTemplate);

   if (lcInformation->codeTargetFile()!="")
    makeSourceCodePage(agFolder,*lcInformation,agTemplate);

   lcCurrentModule++;
  }

  lcListFile << 4;
  lcListFile.copyright();
  //lcListFile.table("100%","0").row().cell().center().little() << "Last Update: ";
  //lcListFile << calendarGregorian::current().date(calendarGregorian::monthFirstLongDate,false);
  //lcListFile << 3;
  lcListFile.terminate();
 }
 //-------------------------------------------------------------------------------MakeSourceCodePage
 /*FUNCTION*/ /* Generates an HTML version of the source code of a module. */
 function void makeSourceCodePage(tcString agFolder,ctModuleInformation & agInformation,
                                  ctHtmlTemplate & agTemplate) {
  private_area::tyElementCounters lcCounters = { 0 };

  clString lcExtension;
  clInFile lcFile1;
  clInFile lcFile2;
  clString lcFullName;
  clString lcModulePath;
  clString lcString;

  clHtmlFile lcCodeFile(agTemplate);

  buildFullName(lcFullName,clString(agFolder),agInformation.codeTargetFile());
  lcCodeFile=lcFullName.data();
  lcString="B++ Library / \""+agInformation.name()+"\"";
  separateFileName(lcModulePath,lcExtension,agInformation.name());
  if (lcExtension=="") lcString+=" Module";
  lcString+=" Source Code";
  lcCodeFile.signature().codePage(lcString.data());

  if (agInformation.isJava()) {
   lcCodeFile.table("100%","0");
   lcCodeFile.row().cell().code();
   private_area::copySourceCode(lcCodeFile,agInformation.hppSourceFile().data(),lcCounters);
   lcCodeFile << 4;
  }
  else {
   if (agInformation.hppSourceFile()!="") {
    lcCodeFile.bookmark(private_area::goInterfaceFlag);
    lcCodeFile.table("100%","0");
    lcCodeFile.row().cell().code();
    private_area::copySourceCode(lcCodeFile,agInformation.hppSourceFile().data(),lcCounters);
    lcCodeFile << 4;
   }

   if (agInformation.cppSourceFile()!="") {
    lcCodeFile.bookmark(private_area::goImplementationFlag);
    lcCodeFile.table("100%","0");
    lcCodeFile.row().cell().code();
    private_area::copySourceCode(lcCodeFile,agInformation.cppSourceFile().data(),lcCounters);
    lcCodeFile << 4;
   }
  }

  lcCodeFile.terminate();
 }
}

namespace private_area {
 //-----------------------------------------------------------------------------------CopySourceCode
 function void copySourceCode(clHtmlFile & agTarget,tcString agSourceName,
                              tyElementCounters & agCounters) {
  method_name("copySourceCode");

  tyStreamPosition lcBefore;
  clInFile         lcSource1;
  clInFile         lcSource2;
  clString         lcString1;
  clString         lcString2;

  open(lcSource1,agSourceName,ios::in|ios::binary);
  open(lcSource2,agSourceName,ios::in|ios::binary);
  if (lcSource1.fail() or lcSource2.fail()) send_error(erFileReading);

  lcBefore=lcSource1.tellg();
  lcSource1 >> lcString1;

  while (lcString1!="" && !lcSource1.eof()) {
   if (lcString1==metaModelInformationExtraction_private::goMacrocommandFlag) {
    copySourceCodeUntil(agTarget,lcSource2,lcBefore);
    lcString2=clString(goMacrocommandFlag)+standardMaths::string(agCounters.macrocommands++);
    agTarget.bookmark(lcString2.data());
    copySourceCodeUntil(agTarget,lcSource2,lcSource1.tellg());
   }
   else if (lcString1==metaModelInformationExtraction_private::goFunctionFlag) {
    copySourceCodeUntil(agTarget,lcSource2,lcBefore);
    lcString2=clString(goFunctionFlag)+standardMaths::string(agCounters.functions++);
    agTarget.bookmark(lcString2.data());
    copySourceCodeUntil(agTarget,lcSource2,lcSource1.tellg());
   }
   else if (lcString1==metaModelInformationExtraction_private::goClassFlag) {
    copySourceCodeUntil(agTarget,lcSource2,lcBefore);
    lcString2=clString(goClassFlag)+standardMaths::string(agCounters.classes++);
    agTarget.bookmark(lcString2.data());
    copySourceCodeUntil(agTarget,lcSource2,lcSource1.tellg());
   }
   else if (lcString1==metaModelInformationExtraction_private::goMethodFlag) {
    copySourceCodeUntil(agTarget,lcSource2,lcBefore);
    lcString2=clString(goMethodFlag)+standardMaths::string(agCounters.methods++);
    agTarget.bookmark(lcString2.data());
    copySourceCodeUntil(agTarget,lcSource2,lcSource1.tellg());
   }
   else if (lcString1==metaModelInformationExtraction_private::goAbstractMethodFlag) {
    copySourceCodeUntil(agTarget,lcSource2,lcBefore);
    lcString2=clString(goMethodFlag)+standardMaths::string(agCounters.methods++);
    agTarget.bookmark(lcString2.data());
    copySourceCodeUntil(agTarget,lcSource2,lcSource1.tellg());
   }

   while (lcSource1.tellg()<lcSource2.tellg()) lcSource1.get((tyCharacter &)lcBefore);

   lcBefore=lcSource1.tellg();
   lcSource1 >> lcString1;
  }

  if (lcSource1.eof()) lcSource1.seekg(0,ios::end);
  copySourceCodeUntil(agTarget,lcSource2,lcSource1.tellg(),true);
  close(lcSource1);
  close(lcSource2);
  if (lcSource1.fail()) send_error(erFileReading);
  if (lcSource2.fail()) send_error(erFileReading);
 }
 //------------------------------------------------------------------------------CopySourceCodeUntil
 function void copySourceCodeUntil(clHtmlFile & agTarget,clInFile & agSource,
                                   tyStreamPosition agEnd,tyBoolean agLast) {
  tyCharacter lcPrevious = 13;

  tyBoolean   lcAgain;
  tyCharacter lcCharacter;
  tyCardinal  lcNumberSpace;
  clString    lcString;

  lcAgain=getCharacter(agSource,lcCharacter,agEnd);

  while (lcAgain) {
   switch (lcCharacter) {
    case ' ':
     lcNumberSpace=0;

     while (lcAgain and lcCharacter==' ') {
      lcAgain=getCharacter(agSource,lcCharacter,agEnd);
      lcNumberSpace++;
     }

     if (lcPrevious==10 or lcPrevious==13) {
      agTarget.convert(lcString.data());
      agTarget.horizontalSpace(lcNumberSpace);
     }
     else {
      lcString+=" ";
      agTarget.convert(lcString.data());
      if (lcNumberSpace>1) agTarget.horizontalSpace(lcNumberSpace-1);
     }

     lcString="";
     lcPrevious=' ';
     break;

    default:
     lcPrevious=lcCharacter;
     lcString+="X";
     lcString[lcString.size()-1]=lcCharacter;
     lcAgain=getCharacter(agSource,lcCharacter,agEnd);
   }
  }

  if (lcCharacter==13)
   while (not agSource.eof() and agSource.peek()==10) agSource.get(lcCharacter);
  else if (lcCharacter==10)
   while (not agSource.eof() and agSource.peek()==13) agSource.get(lcCharacter);

  if (agLast) {
   while (lcString.size()>0 and (lastCharacter(lcString)==13 or lastCharacter(lcString)==10))
    lcString.resize(lcString.size()-1);
  }

  agTarget.convert(lcString.data());
 }
 //-------------------------------------------------------------------------------------GetCharacter
 function tyBoolean getCharacter(clInFile & agFile,tyCharacter & agCharacter,
                                 tyStreamPosition agEnd) {
  if (not agFile.eof() and agFile.peek()!=-1 and agFile.tellg()!=agEnd) {
   agFile.get(agCharacter);
   return (true);
  }
  else return (false);
 }
 //--------------------------------------------------------------------------------------MakeAliases
 function void makeAliases(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                           ctModuleInformation & agInformation) {
  clEntityInformationS::const_iterator lcCurrentAlias = agInformation.aliases().begin();
  clEntityInformationS::const_iterator lcLastAlias    = agInformation.aliases().end();

  makeSubtitle(agHomeFile,agMenuFile,"Aliases",goAliasesFlag,agInformation);
  agHomeFile.paragraph();
  agHomeFile << "The aliases listed below are only used internally by the interface. They are ";
  agHomeFile << "here just to lighten the writing of certain declarations. Never use them, they ";
  agHomeFile << "are local to the interface and can not be used outside of it." << 1;
  agHomeFile.unorderedList();

  while (lcCurrentAlias!=lcLastAlias) {
   agHomeFile.listItem().paragraph().code().cite().convert((*lcCurrentAlias).name().data());
   agHomeFile << 1 << " = ";
   agHomeFile.convert((*lcCurrentAlias).description().data()) << 3;
   lcCurrentAlias++;
  }

  agHomeFile << 1;
 }
 //-------------------------------------------------------------------------------------MakeChildren
 function void makeChildren(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                            clModuleInformationX & agInformationX,
                            ctModuleInformation & agInformation) {
  std_set(clString)::const_iterator lcCurrentChild = agInformation.children().begin();
  std_set(clString)::const_iterator lcLastChild    = agInformation.children().end();

  makeSubtitle(agHomeFile,agMenuFile,"Child Modules",goChildrenFlag,agInformation);
  agHomeFile.paragraph() << "The modules listed below are parts of this module." << 1;
  agHomeFile.unorderedList();

  while (lcCurrentChild!=lcLastChild) {
   agHomeFile.listItem().paragraph().code().link(agHomeFile.homeFrameName(),
   agInformationX[*lcCurrentChild]->indexTargetFile().data());

   agHomeFile.cite().convert(agInformationX[*lcCurrentChild]->name().data());
   agHomeFile << 5;
   lcCurrentChild++;
  }

  agHomeFile << 1;
 }
 //--------------------------------------------------------------------------------------MakeClasses
 function void makeClasses(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                           ctModuleInformation & agInformation) {
  typedef clEntityInformationS::const_iterator clIterator;

  clIterator lcCurrentClass = agInformation.classes().begin();
  clIterator lcLastClass    = agInformation.classes().end();

  ctEntityInformation * lcAttribute;
  ctEntityInformation * lcClass;
  clIterator            lcCurrentAttribute;
  clIterator            lcCurrentMethod;
  clIterator            lcCurrentType;
  tyBoolean             lcFound;
  clIterator            lcLastAttribute;
  clIterator            lcLastMethod;
  clIterator            lcLastType;
  ctEntityInformation * lcMethod;
  clString              lcString;
  ctEntityInformation * lcType;

  makeSubtitle(agHomeFile,agMenuFile,"Classes",goClassesFlag,agInformation);
  agHomeFile.paragraph() << "Here are listed the classes provided by the module. ";
  agHomeFile << "To use one of them, you have to specify the namespace of the module." << 1;

  if (agInformation.classes().size()>1) {
   agHomeFile.unorderedList();

   while (lcCurrentClass!=lcLastClass) {
    lcClass=&(*lcCurrentClass);
    agHomeFile.listItem().paragraph().code();
    lcString=clString("#")+goClassFlag+standardMaths::string(lcClass->reference());
    agHomeFile.link("",lcString.data());
    agHomeFile.cite().convert(lcClass->name().data()) << 5;
    lcCurrentClass++;
   }

   agHomeFile << 1;
   lcCurrentClass=agInformation.classes().begin();
  }

  while (lcCurrentClass!=lcLastClass) {
   lcClass=&(*lcCurrentClass);
   lcString=clString(goClassFlag)+standardMaths::string(lcClass->reference());
   agHomeFile.title3().bookmark(lcString.data());
   agHomeFile.convert(lcClass->name().data()) << 1;
   agHomeFile.title4() << "Declaration" << 1;
   lcString=clString("javascript:openCode('")+agInformation.codeTargetFile()+"#"+goClassFlag;
   lcString+=standardMaths::string(lcClass->reference())+"')";
   agHomeFile.paragraph().code().link("",lcString.data());

   agHomeFile.cite().convert(lcClass->declaration().data()) << 4;
   agHomeFile.title4() << "Description" << 1;
   agHomeFile.paragraph() << lcClass->description() << 1;

   lcCurrentType=agInformation.classTypes().begin();
   lcLastType=agInformation.classTypes().end();
   lcFound=false;

   while (lcCurrentType!=lcLastType) {
    if ((*lcCurrentType).name()==lcClass->name()) lcFound=true;
    lcCurrentType++;
   }

   if (lcFound) {
    agHomeFile.title4() << "Types" << 1;
    agHomeFile.unorderedList();
    lcCurrentType=agInformation.classTypes().begin();
    lcLastType=agInformation.classTypes().end();

    while (lcCurrentType!=lcLastType) {
     lcType=&(*lcCurrentType);

     if (lcType->name()==lcClass->name()) {
      agHomeFile.listItem().paragraph().code().cite();
      agHomeFile.convert(lcType->declaration().data()) << 2;
      agHomeFile.breakLine() << lcType->description() << 2;
     }

     lcCurrentType++;
    }

    agHomeFile << 1;
   }

   lcCurrentAttribute=agInformation.attributes().begin();
   lcLastAttribute=agInformation.attributes().end();
   lcFound=false;

   while (lcCurrentAttribute!=lcLastAttribute) {
    if ((*lcCurrentAttribute).name()==lcClass->name()) lcFound=true;
    lcCurrentAttribute++;
   }

   if (lcFound) {
    agHomeFile.title4() << "Attributes" << 1;
    agHomeFile.unorderedList();
    lcCurrentAttribute=agInformation.attributes().begin();
    lcLastAttribute=agInformation.attributes().end();

    while (lcCurrentAttribute!=lcLastAttribute) {
     lcAttribute=&(*lcCurrentAttribute);

     if (lcAttribute->name()==lcClass->name()) {
      agHomeFile.listItem().paragraph().code().cite();
      agHomeFile.convert(lcAttribute->declaration().data()) << 2;
      agHomeFile.breakLine() << lcAttribute->description() << 2;
     }

     lcCurrentAttribute++;
    }

    agHomeFile << 1;
   }

   lcCurrentMethod=agInformation.methods().begin();
   lcLastMethod=agInformation.methods().end();
   lcFound=false;

   while (lcCurrentMethod!=lcLastMethod) {
    if ((*lcCurrentMethod).name()==lcClass->name()) lcFound=true;
    lcCurrentMethod++;
   }

   if (lcFound) {
    agHomeFile.title4() << "Methods" << 1;
    agHomeFile.unorderedList();
    lcCurrentMethod=agInformation.methods().begin();
    lcLastMethod=agInformation.methods().end();

    while (lcCurrentMethod!=lcLastMethod) {
     lcMethod=&(*lcCurrentMethod);

     if (lcMethod->name()==lcClass->name()) {
      lcString=clString("javascript:openCode('")+agInformation.codeTargetFile()+"#"+goMethodFlag;
      lcString+=standardMaths::string(lcMethod->reference())+"')";
      agHomeFile.listItem().paragraph().code().link("",lcString.data());
      agHomeFile.cite().convert(lcMethod->declaration().data()) << 3;
      agHomeFile.breakLine() << lcMethod->description() << 2;
     }

     lcCurrentMethod++;
    }

    agHomeFile << 1;
   }

   lcCurrentClass++;
  }
 }
 //------------------------------------------------------------------------------------MakeConstants
 function void makeConstants(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                             ctModuleInformation & agInformation) {
  typedef clEntityInformationS::const_iterator clIterator;

  clIterator lcCurrentConstant = agInformation.constants().begin();
  clIterator lcLastConstant    = agInformation.constants().end();

  makeSubtitle(agHomeFile,agMenuFile,"Constants",goConstantsFlag,agInformation);
  agHomeFile.paragraph() << "Here are listed the constants provided by the module. ";
  agHomeFile << "To use one of them, you have to specify the namespace of the module." << 1;
  agHomeFile.unorderedList();

  while (lcCurrentConstant!=lcLastConstant) {
   agHomeFile.listItem().paragraph().code().cite();
   agHomeFile.convert((*lcCurrentConstant).declaration().data());
   agHomeFile << 2;
   agHomeFile.breakLine() << (*lcCurrentConstant).description() << 2;
   lcCurrentConstant++;
  }

  agHomeFile << 1;
 }
 //----------------------------------------------------------------------------------MakeDescription
 function void makeDescription(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                               ctModuleInformation & agInformation) {
  makeSubtitle(agHomeFile,agMenuFile,"Description",goDescriptionFlag,agInformation);
  agHomeFile.paragraph() << agInformation.description() << 1;
 }
 //---------------------------------------------------------------------------------------MakeErrors
 function void makeErrors(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                          ctModuleInformation & agInformation) {
  clEntityInformationS::const_iterator lcCurrentError = agInformation.errors().begin();
  clEntityInformationS::const_iterator lcLastError    = agInformation.errors().end();

  makeSubtitle(agHomeFile,agMenuFile,"Errors",goErrorsFlag,agInformation);
  agHomeFile.paragraph();
  agHomeFile << "Here are listed the errors that are supported or generated by the module. ";
  agHomeFile << "To use one of them, you do not have to specify the namespace of the module." << 1;
  agHomeFile.unorderedList();

  while (lcCurrentError!=lcLastError) {
   agHomeFile.listItem().paragraph().code().cite().convert((*lcCurrentError).name().data()) << 2;
   agHomeFile.breakLine() << (*lcCurrentError).description() << 2;
   lcCurrentError++;
  }

  agHomeFile << 1;
 }
 //-------------------------------------------------------------------------------------MakeFileList
 function void makeFileList(clHtmlFile & agFile,const std_vector(clString) & agFileS,
                            clModuleInformationX & agInformationX) {
  std_vector(clString)::const_iterator lcCurrentFile = agFileS.begin();
  std_vector(clString)::const_iterator lcLastFile    = agFileS.end();

  clString lcExtension;
  clString lcModuleName;
  clString lcModulePath;
  clString lcTempo;

  agFile.unorderedList();

  while (lcCurrentFile!=lcLastFile) {
   agFile.listItem().paragraph().code().cite().convert((*lcCurrentFile).data());
   agFile << 1;
   lcTempo=(*lcCurrentFile).part(1,(*lcCurrentFile).size()-2);
   separateFileName(lcModulePath,lcExtension,lcTempo);

   if (agInformationX.count(lcModulePath)>0) {
    agFile.breakLine();
    agFile.link(agFile.homeFrameName(),agInformationX[lcModulePath]->indexTargetFile().data());
    metaModelInformationExtraction::buildModuleName(lcModuleName,lcModulePath);
    agFile.code().convert(lcModuleName.data());
    agFile << 2;
   }

   agFile << 3;
   lcCurrentFile++;
  }

  agFile << 1;
 }
 //------------------------------------------------------------------------------------MakeFunctions
 function void makeFunctions(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                             ctModuleInformation & agInformation) {
  typedef clEntityInformationS::const_iterator clIterator;

  clIterator lcCurrentFunction = agInformation.functions().begin();
  clIterator lcLastFunction    = agInformation.functions().end();

  ctEntityInformation * lcFunction;
  clString              lcString;

  makeSubtitle(agHomeFile,agMenuFile,"Functions",goFunctionsFlag,agInformation);
  agHomeFile.paragraph() << "Here are listed the functions provided by the module. ";
  agHomeFile << "To use one of them, you have to specify the namespace of the module." << 1;
  agHomeFile.unorderedList();

  while (lcCurrentFunction!=lcLastFunction) {
   lcFunction=&(*lcCurrentFunction);
   lcString=clString("javascript:openCode('")+agInformation.codeTargetFile()+"#"+goFunctionFlag;
   lcString+=standardMaths::string(lcFunction->reference())+"')";
   agHomeFile.listItem().paragraph().code().link("",lcString.data());
   agHomeFile.cite().convert(lcFunction->declaration().data()) << 3;
   agHomeFile.breakLine() << lcFunction->description() << 2;
   lcCurrentFunction++;
  }

  agHomeFile << 1;
 }
 //-------------------------------------------------------------------------------------MakeIncludes
 function void makeIncludes(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                            clModuleInformationX & agInformationX,
                            ctModuleInformation & agInformation) {
  makeSubtitle(agHomeFile,agMenuFile,"Included Files",goIncludesFlag,agInformation);
  agHomeFile.paragraph() << "The files listed below are included in the interface part of the ";
  agHomeFile << "module. So any module dependent of this module is also dependent ";
  agHomeFile << "of the files listed here." << 1;
  makeFileList(agHomeFile,agInformation.includes(),agInformationX);
 }
 //--------------------------------------------------------------------------------MakeMacrocommands
 function void makeMacrocommands(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                                 ctModuleInformation & agInformation) {
  typedef clEntityInformationS::const_iterator clIterator;

  clIterator lcCurrentMacro = agInformation.macrocommands().begin();
  clIterator lcLastMacro    = agInformation.macrocommands().end();

  ctEntityInformation * lcMacro;
  clString              lcString;

  makeSubtitle(agHomeFile,agMenuFile,"Macrocommands",goMacrocommandsFlag,agInformation);
  agHomeFile.paragraph();
  agHomeFile << "The macrocommands listed below can be used without specifying the namespace ";
  agHomeFile << "where they have been defined. That means you can not define an element by your ";
  agHomeFile << "own that have the same name." << 1;
  agHomeFile.unorderedList();

  while (lcCurrentMacro!=lcLastMacro) {
   lcMacro=&(*lcCurrentMacro);
   lcString=clString("javascript:openCode('")+agInformation.codeTargetFile()+"#";
   lcString+=goMacrocommandFlag+standardMaths::string(lcMacro->reference())+"')";
   agHomeFile.listItem().paragraph().code().link("",lcString.data());
   agHomeFile.cite().convert(lcMacro->declaration().data()) << 3;
   agHomeFile.breakLine() << lcMacro->description() << 2;
   lcCurrentMacro++;
  }

  agHomeFile << 1;
 }
 //-----------------------------------------------------------------------------------MakeNamespaces
 function void makeNamespaces(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                              clModuleInformationX & agInformationX,
                              ctModuleInformation & agInformation) {
  std_vector(clString)::const_iterator lcCurrentName = agInformation.namespaces().begin();
  std_vector(clString)::const_iterator lcLastName    = agInformation.namespaces().end();

  clModuleInformationX::const_iterator lcCurrentModule;
  clModuleInformationX::const_iterator lcLastModule;

  makeSubtitle(agHomeFile,agMenuFile,"Integrated Namespaces",goNamespacesFlag,agInformation);
  agHomeFile.paragraph();
  agHomeFile << "The namespaces listed below are integrated in this module. That means ";
  agHomeFile << "any element declared in one of those namespaces can now be directly used by ";
  agHomeFile << "or from this module." << 1;
  agHomeFile.unorderedList();

  while (lcCurrentName!=lcLastName) {
   agHomeFile.listItem().paragraph().code().cite().convert(lcCurrentName->data()) << 1;
   lcCurrentModule=agInformationX.begin();
   lcLastModule=agInformationX.end();

   while (lcCurrentModule!=lcLastModule and (*lcCurrentModule).second->nameSpace()!=*lcCurrentName)
    lcCurrentModule++;

   if (lcCurrentModule!=lcLastModule) {
    agHomeFile.breakLine();
    agHomeFile.link(agHomeFile.homeFrameName(),
                    (*lcCurrentModule).second->indexTargetFile().data());

    agHomeFile.code().convert((*lcCurrentModule).second->name().data());
    agHomeFile << 2;
   }

   agHomeFile << 3;
   lcCurrentName++;
  }

  agHomeFile << 1;
 }
 //----------------------------------------------------------------------------------------MakeNeeds
 function void makeNeeds(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                         clModuleInformationX & agInformationX,
                         ctModuleInformation & agInformation) {
  makeSubtitle(agHomeFile,agMenuFile,"Needed Files",goNeedsFlag,agInformation);
  agHomeFile.paragraph() << "The files listed below are needed by the implementation part of the ";
  agHomeFile << "module. But a module dependent of this module is not necessary dependent ";
  agHomeFile << "of the files listed here." << 1;
  makeFileList(agHomeFile,agInformation.needs(),agInformationX);
 }
 //---------------------------------------------------------------------------------------MakeParent
 function void makeParent(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                          clModuleInformationX & agInformationX,
                          ctModuleInformation & agInformation) {
  makeSubtitle(agHomeFile,agMenuFile,"Parent Module",goParentFlag,agInformation);
  agHomeFile.paragraph() << "This module is part of" ;

  agHomeFile.code().link(agHomeFile.homeFrameName(),
  agInformationX[agInformation.parent()]->indexTargetFile().data());

  agHomeFile.cite() << " ";
  agHomeFile.convert(agInformationX[agInformation.parent()]->name().data());
  agHomeFile << 3 << "." << 1;
 }
 //-------------------------------------------------------------------------------------MakeSubtitle
 function void makeSubtitle(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,tcString agTitle,
                            tcString agName,ctModuleInformation & agInformation) {
  clString lcString;

  tyString lcTitle = new_array(tyCharacter,size(agTitle)+1);

  copy(lcTitle,agTitle);
  upperCase(lcTitle);
  agHomeFile.title2().bookmark(agName) << lcTitle << 1;
  lcString=agInformation.homeTargetFile()+"#"+agName;
  agMenuFile.link(agMenuFile.mainFrameName(),lcString.data());
  agMenuFile << agTitle << 1;
  delete_array(lcTitle);
 }
 //----------------------------------------------------------------------------------MakeSourceFiles
 function void makeSourceFiles(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                               ctModuleInformation & agInformation) {
  clString lcString;

  makeSubtitle(agHomeFile,agMenuFile,"Source Files",goSourceFilesFlag,agInformation);
  agHomeFile.paragraph();

  if (agInformation.isJava())
   agHomeFile << "This section allows you to access the Java source file of the module." << 1;
  else
   agHomeFile << "This section allows you to access the C++ source files of the module." << 1;

  agHomeFile.unorderedList();
  lcString="javascript:openCode('"+agInformation.codeTargetFile();
  if (not agInformation.isJava()) lcString+=clString("#")+goInterfaceFlag;
  lcString+="')";
  agHomeFile.listItem().paragraph().code().link("",lcString.data());
  agHomeFile.cite() << (agInformation.isJava() ? "Implementation" : "Interface") << 5;

  if (agInformation.cppSourceFile()!="") {
   lcString=clString("javascript:openCode('")+agInformation.codeTargetFile();
   lcString+=clString("#")+goImplementationFlag+"')";
   agHomeFile.listItem().paragraph().code().link("",lcString.data());
   agHomeFile.cite() << "Implementation" << 5;
  }

  agHomeFile << 1;
 }
 //----------------------------------------------------------------------------------------MakeTitle
 function void makeTitle(clHtmlFile & agFile,ctModuleInformation & agInformation) {
  tyCardinal lcCounter = 0;
  tyBoolean  lcFirst   = true;
  clString   lcTitle   = agInformation.name();

  agFile.title1();
  agFile.table("100%","0").row().cell().fontSize("24px").sansSerif();

  while (lcCounter<lcTitle.size()) {
   if (lcTitle[lcCounter]=='/') {
    if (lcFirst) {
     lcFirst=false;
     agFile << "/";
    }
    else agFile.breakLine();
   }
   else agFile << lcTitle.part(lcCounter,1);

   lcCounter++;
  }

  agFile << 3;
  agFile.cell("right","MIDDLE","0").fontSize("18px").italic().sansSerif();

  if (agInformation.isJava()) agFile << " Java";
  else agFile <<" C++";

  agFile << 7;
 }
 //----------------------------------------------------------------------------------------MakeTypes
 function void makeTypes(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                         ctModuleInformation & agInformation) {
  clEntityInformationS::const_iterator lcCurrentType = agInformation.types().begin();
  clEntityInformationS::const_iterator lcLastType    = agInformation.types().end();

  makeSubtitle(agHomeFile,agMenuFile,"Types",goTypesFlag,agInformation);
  agHomeFile.paragraph();
  agHomeFile << "Here are listed the types defined in the module. To use one of them, you have ";
  agHomeFile << "to specify the namespace of the module." << 1;
  agHomeFile.unorderedList();

  while (lcCurrentType!=lcLastType) {
   agHomeFile.listItem().paragraph().code().cite().convert((*lcCurrentType).declaration().data());
   agHomeFile << 2;
   agHomeFile.breakLine() << (*lcCurrentType).description() << 2;
   lcCurrentType++;
  }

  agHomeFile << 1;
 }
 //------------------------------------------------------------------------------------MakeVariables
 function void makeVariables(clHtmlFile & agHomeFile,clHtmlFile & agMenuFile,
                             ctModuleInformation & agInformation) {
  typedef clEntityInformationS::const_iterator clIterator;

  clIterator lcCurrentVariable = agInformation.variables().begin();
  clIterator lcLastVariable    = agInformation.variables().end();

  makeSubtitle(agHomeFile,agMenuFile,"Variables",goVariablesFlag,agInformation);
  agHomeFile.paragraph() << "Here are listed the variables managed by the module. ";
  agHomeFile << "To use one of them, you have to specify the namespace of the module." << 1;
  agHomeFile.unorderedList();

  while (lcCurrentVariable!=lcLastVariable) {
   agHomeFile.listItem().paragraph().code().cite();
   agHomeFile.convert((*lcCurrentVariable).declaration().data());
   agHomeFile << 2;
   agHomeFile.breakLine() << (*lcCurrentVariable).description() << 2;
   lcCurrentVariable++;
  }

  agHomeFile << 1;
 }
}

// X X X  Implementation //-------------------------------------------------------------------------
namespace {}

// I n i t i a l i z e r  Implementation //---------------------------------------------------------
namespace private_area {
 //--------------------------------------------------------------------------------------------Start
 property void clInitializer::start(void) {
  if (atCounter++ == 0) {
   try {
    #include <bpp/modules.hpp> /*NEED*/
    registerStop(this);
    environment::informInitialization(goModuleName);

    goListFileName = "modules_list.htm";

    goAliasesFlag        = "aliases";
    goChildrenFlag       = "child_modules";
    goClassesFlag        = "classes";
    goConstantsFlag      = "constants";
    goDescriptionFlag    = "description";
    goErrorsFlag         = "errors";
    goFunctionsFlag      = "functions";
    goImplementationFlag = "implementation";
    goIncludesFlag       = "included_files";
    goInterfaceFlag      = "interface";
    goMacrocommandsFlag  = "macrocommands";
    goNamespacesFlag     = "integrated_namespaces";
    goNeedsFlag          = "needed_files";
    goParentFlag         = "parent_module";
    goSourceFilesFlag    = "source_files";
    goTypesFlag          = "types";
    goVariablesFlag      = "variables";

    goClassFlag        = "class_";
    goFunctionFlag     = "function_";
    goMacrocommandFlag = "macrocommand_";
    goMethodFlag       = "method_";

    goCodeWindowName = "code_window";
   }

   initializer_catch;
  }
 }
 //---------------------------------------------------------------------------------------------Stop
 property void clInitializer::stop(void) { environment::informTermination(goModuleName); }
}

// End //-------------------------------------------------------------------------------------------
}