//==================================================================================================
// P r o g r a m                                                                          Interface
// M a k e _ d o c
// C o n s o l e
//                                                                                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 execute the program in console mode. */

// File Name //-------------------------------------------------------------------------------------
#line __LINE__ "program/make_doc/console.hpp"

// Guardian //--------------------------------------------------------------------------------------
#ifndef guProgramMakeDocConsole
#define guProgramMakeDocConsole

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

namespace bpp {

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

// Namespaces //------------------------------------------------------------------------------------
#define public_area  programMakeDocConsole
#define private_area programMakeDocConsole_private

namespace public_area  { /*NAMESPACE*/ using namespace metaModel; }
namespace private_area { using namespace public_area; }

extern_module_name;

// Initialization //--------------------------------------------------------------------------------
#define iniProgramMakeDocConsole
has_initializer;

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

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

// Functions Interface //---------------------------------------------------------------------------
namespace public_area  { function tyReturn run(tyCardinal,tcString []); }
namespace private_area {}

// Errors //----------------------------------------------------------------------------------------
namespace public_area { /*ERROR*/ extern_error erSyntax; /* Syntax error in the command line. */ }

// Constants & Variables //-------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

// 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
 
//==================================================================================================
// P r o g r a m                                                                     Implementation
// M a k e _ d o c
// C o n s o l e
//                                                                                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).

// File Name //-------------------------------------------------------------------------------------
#line __LINE__ "program/make_doc/console.cpp"

// DLL Belonging //---------------------------------------------------------------------------------
#define PROGRAM_MAKE_DOC_DLL

// Headers //---------------------------------------------------------------------------------------
#include <bpp/program/make_doc/console.hpp> /*INTERFACE*/

namespace bpp {

// Namespaces //------------------------------------------------------------------------------------
#define public_area  programMakeDocConsole
#define private_area programMakeDocConsole_private
#define dll_export   DLL_EXPORT

namespace public_area  {}
namespace private_area {}

static_module_name("Program/Make_doc/Console");

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

// Errors //----------------------------------------------------------------------------------------
namespace public_area { static_error erSyntax; }

// Constants & Variables //-------------------------------------------------------------------------
namespace public_area  {}
namespace private_area {}

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

// Functions Implementation //----------------------------------------------------------------------
namespace public_area {
 //----------------------------------------------------------------------------------------------Run
 /*FUNCTION*/
 /* Start function of the program. It deals with the commands the user gives through a command
    line and executes the appropriate functions. */
 function tyReturn run(tyCardinal agCounter,tcString agParameterS[]) {
  method_name("run");

  clString             lcCommand;
  tyBoolean            lcError;
  clModuleInformationX lcModuleInformationX;
  clString             lcTargetFolder;

  tyCardinal       lcCounter   = 1;
  tyBoolean        lcDisplayed = true;
  clHtmlTemplate * lcTemplate  = nil;

  environment_private::goProgramName = "M a k e   D o c";

  try {
   if (agCounter==1) send_error(erSyntax);

   while (lcCounter<agCounter) {
    lcCommand=agParameterS[lcCounter];
    lcError=true;

    //---------------------------------------------------------------------------------------Context
    if (lcCommand=="+context") {
     lcError=false;
     environment::nextLine();
     environment::outContext();
    }

    //------------------------------------------------------------------------------------------Help
    else if (lcCommand=="+help") {
     lcError=false;
     environment::nextLine();
     environment::inform("-=-=- H E L P -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
     environment::out(" This program generates HTML documentation from C++ library source files.",true,true);
     environment::nextLine();
     environment::out(" * Syntax: [options] [commands]",true,true);
     environment::nextLine();
     environment::out(" * Options:",true,true);
     environment::out("   -hide         = deactivates the display of information.",true,true);
     environment::out("   -template <f> = uses the template in the file <f> to generate",true,true);
     environment::out("                   HTML files.",true,true);
     environment::nextLine();
     environment::out(" * Commands:",true,true);
     environment::out("   +context        = shows the context of the program's running.",true,true);
     environment::out("   +help           = shows this help.",true,true);
     environment::out("   +info           = shows information about the program.",true,true);
     environment::out("   +license        = shows the license of the program.",true,true);
     environment::out("   +add <f>        = adds a source file to the list of files to document.",true,true);
     environment::out("   +create <f> <g> = generates in the folder <g> the HTML",true,true);
     environment::out("                     documentation of the source files in the folder <f>",true,true);
     environment::out("                     and in the list.",true,true);
     environment::out("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-",true,true);
    }

    //------------------------------------------------------------------------------------------Info
    else if (lcCommand=="+info") {
     lcError=false;
     environment::nextLine();
     environment::outInformation();
    }

    //---------------------------------------------------------------------------------------License
    else if (lcCommand=="+license") {
     lcError=false;
     environment::nextLine();
     environment::outLicense();
    }

    //------------------------------------------------------------------------------------------Hide
    else if (lcCommand=="-hide") {
     lcDisplayed=false;
     lcError=false;
    }

    //--------------------------------------------------------------------------------------Template
    else if (lcCommand=="-template") {
     if (agCounter-lcCounter>1) {
      clInFile lcFile;

      if (lcDisplayed) {
       environment::nextLine();
       environment::inform("Reading HTML Template File...");
      }

      open(lcFile,agParameterS[lcCounter+1],ios::in);
      if (lcFile.fail()) send_error(erFileReading);
      lcTemplate=new_object(clHtmlTemplate(lcFile));
      close(lcFile);
      if (lcFile.fail()) send_error(erFileReading);
      lcCounter+=1;
      lcError=false;
     }
    }

    //-------------------------------------------------------------------------------------------Add
    else if (lcCommand=="+add") {
     if (agCounter-lcCounter>1) {
      clString              lcBody;
      clString              lcExtension;
      clString              lcFullName;
      clInFile              lcFile;
      clModuleInformation * lcModuleInformation;
      clString              lcPath;
      clString              lcShortName;

      extractShortName(lcPath,lcShortName,clString(agParameterS[lcCounter+1]));
      separateFileName(lcBody,lcExtension,lcShortName);

      metaModelInformationExtraction_private::registerModule(lcModuleInformationX,lcShortName,
                                                             lcShortName,lcShortName);

      lcModuleInformation=lcModuleInformationX[lcShortName];

      if (lcExtension=="") {
       lcShortName=lcBody+"."+hppExtension();
       buildFullName(lcFullName,lcPath,lcShortName);
       lcModuleInformation->hppSourceFile()=lcFullName;

       lcShortName=lcBody+"."+cppExtension();
       buildFullName(lcFullName,lcPath,lcShortName);
       lcModuleInformation->cppSourceFile()=lcFullName;
       lcShortName=lcBody;
      }
      else if (lcExtension==hppExtension())
       lcModuleInformation->hppSourceFile()=agParameterS[lcCounter+1];
      else if (lcExtension==cppExtension())
       lcModuleInformation->cppSourceFile()=agParameterS[lcCounter+1];

      if (lcDisplayed) {
       environment::nextLine();
       environment::inform("Extracting Information From '",false);
       environment::out(lcShortName.data());
       environment::out("'...",true);
      }

      if (lcModuleInformation->hppSourceFile()!="") {
       open(lcFile,lcModuleInformation->hppSourceFile().data(),ios::in);
       getModuleInformation(lcFile,*lcModuleInformation);
       close(lcFile);
       if (lcFile.fail()) send_error(erFileReading);
      }

      if (lcModuleInformation->cppSourceFile()!="") {
       open(lcFile,lcModuleInformation->cppSourceFile().data(),ios::in);
       getModuleInformation(lcFile,*lcModuleInformation);
       close(lcFile);
       if (lcFile.fail()) send_error(erFileReading);
      }

      lcCounter+=1;
      lcError=false;
     }
    }

    //----------------------------------------------------------------------------------------Create
    else if (lcCommand=="+create") {
     if (agCounter-lcCounter>2) {
      clModuleInformationX::const_iterator lcCurrentModule;
      clModuleInformationX::const_iterator lcLastModule;

      if (lcDisplayed) {
       environment::nextLine();
       environment::inform("Extracting Modules Information...");
       environment::nextLine();
      }

      getModulesInformation(agParameterS[lcCounter+1],lcModuleInformationX,lcDisplayed);

      if (lcDisplayed) {
       environment::nextLine();
       environment::inform("Generating HTML Documentation...");
       environment::nextLine();
      }

      if (lcTemplate!=nil)
       makeDocumentation(agParameterS[lcCounter+2],lcModuleInformationX,*lcTemplate,lcDisplayed);
      else
       makeDocumentation(agParameterS[lcCounter+2],lcModuleInformationX,defaultHtmlTemplate(),
                         lcDisplayed);

      lcCurrentModule=lcModuleInformationX.begin();
      lcLastModule=lcModuleInformationX.end();

      while (lcCurrentModule!=lcLastModule) {
       delete_object((*lcCurrentModule).second);
       lcCurrentModule++;
      }

      lcCounter+=2;
      lcError=false;
     }
    }

    if (lcError) send_error(erSyntax);
    lcCounter++;
   }

   if (lcTemplate!=nil) delete_object(lcTemplate);
  }

  program_catch;
 }
}

namespace private_area {}

// 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);

    erSyntax.create("Make Doc - Use the '+help' parameter to get some help.");
   }

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

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