//==================================================================================================
// S i m u l a t o r                                                                      Interface
// U r b a n _ b u s
// 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 simulator from the console mode. */

// File Name //-------------------------------------------------------------------------------------
#line __LINE__ "simulator/urban_bus/console.hpp"

// Guardian //--------------------------------------------------------------------------------------
#ifndef guSimulatorUrbanBusConsole
#define guSimulatorUrbanBusConsole

// Headers //---------------------------------------------------------------------------------------
#include <bpp/calendar.hpp> /*INCLUDE*/
#include <bpp/graphic/console.hpp> /*INCLUDE*/
#include <bpp/simulator/urban_bus/model.hpp> /*INCLUDE*/

namespace bpp {

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

// Namespaces //------------------------------------------------------------------------------------
#define public_area  simulatorUrbanBusConsole
#define private_area simulatorUrbanBusConsole_private

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

extern_module_name;

// Initialization //--------------------------------------------------------------------------------
#define iniSimulatorUrbanBusConsole
has_initializer;

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

// Types & Classes //-------------------------------------------------------------------------------
namespace public_area {
 function tyReturn run(tyCardinal,tcString [],displayConsole::clDisplay &);
}

namespace private_area {}

// Functions Interface //---------------------------------------------------------------------------
namespace public_area  {}
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
 
//==================================================================================================
// S i m u l a t o r                                                                 Implementation
// U r b a n _ b u s
// 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__ "simulator/urban_bus/console.cpp"

// DLL Belonging //---------------------------------------------------------------------------------
#define SIMULATOR_URBAN_BUS_DLL

// Headers //---------------------------------------------------------------------------------------
#include <bpp/simulator/urban_bus/console.hpp> /*INTERFACE*/
#include <jirk/bpp/graphic/textareastream.hpp> /*NEED*/
#include <jirk/java/awt/textarea.hpp> /*NEED*/
#include <jirk/java/lang/string.hpp> /*NEED*/
#include <jirk/java/lang/thread.hpp> /*NEED*/

namespace bpp {

// Namespaces //------------------------------------------------------------------------------------
#define public_area  simulatorUrbanBusConsole
#define private_area simulatorUrbanBusConsole_private
#define dll_export   DLL_EXPORT

namespace public_area  {}
namespace private_area {}

static_module_name("Simulator/Urban_bus/Console");

// Initialization //--------------------------------------------------------------------------------
#undef iniSimulatorUrbanBusConsole
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. The display, where messages have to appear, must
    be provided. */
 function tyReturn run(tyCardinal agCounter,tcString agParameterS[],
                       displayConsole::clDisplay & agDisplay) {
  method_name("run");

  clString  lcCommand;
  tyBoolean lcError;

  tyCardinal                  lcCounter   = 1;
  graphicConsole::clDisplay * lcDisplay   = dynamic_cast<graphicConsole::clDisplay *>(&agDisplay);
  tyBoolean                   lcDisplayed = false;
  tyBoolean                   lcGraphic   = (lcDisplay!=nil);

  environment_private::goProgramName = "U r b a n   B u s   S i m u l a t o r";

  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 simulates flows of customers in an urban bus network.",true,true);
     environment::nextLine();
     environment::out(" * Syntax: [options] [commands] [experiment file]",true,true);
     environment::nextLine();
     environment::out(" * Options:",true,true);
     environment::out("   -graphic = runs a graphical simulation.",true,true);
     environment::out("   -verbose = displays additional information.",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("   +run     = performs the experiment.",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();
    }

    //---------------------------------------------------------------------------------------Graphic
    else if (lcCommand=="-graphic") { lcError=false; }

    //---------------------------------------------------------------------------------------Verbose
    else if (lcCommand=="-verbose") {
     lcDisplayed=true;
     lcError=false;
    }

    //-------------------------------------------------------------------------------------------Run
    else if (lcCommand=="+run") {
     if (agCounter-lcCounter>1) {
      if (lcGraphic) {
       using namespace jirk::bpp::graphic;
       using namespace jirk::bpp::simulation;
       using namespace jirk::java::awt;
       using namespace jirk::java::lang;

       java::loadVirtualMachine();

       {
        jaString         lcTitle  = jaString::j_new("B + +  S i m u l a t o r");
        jaString         lcFile   = jaString::j_new(agParameterS[lcCounter+1]);
        jaSimulatorFrame lcFrame  = jaSimulatorFrame::j_new(lcTitle,lcFile,java_false);
        jaTextAreaStream lcStream = jaTextAreaStream::j_new(jaTextArea(lcFrame.j_console()));

        lcDisplay->setStream(java::clContext().jniPointer(),lcStream.jniPointer());

        clModel lcModel(lcFrame.jniPointer(),lcFile.native().data(),lcDisplayed);

        do {
         lcFrame.j_setRestarted(java_false);
         lcModel.run();
         while (not lcFrame.j_closing() and not lcFrame.j_restarted()) jaThread::j_sleep(100);
        }
        while (lcFrame.j_restarted()==java_true);

        lcDisplay->setStream(nil,nil);
       }

       java::unloadVirtualMachine();
      }
      else {
       clModel lcModel(nil,agParameterS[lcCounter+1],lcDisplayed);
       lcModel.run();
      }

      lcCounter+=1;
      lcError=false;
     }
    }

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

  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("Urban Bus - Use the '+help' parameter to get some help.");
   }

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

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