//==================================================================================================
// E x c h a n g e                                                                        Interface
// A m p l
//                                                                                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 interact with the AMPL software. */

// File Name //-------------------------------------------------------------------------------------
#line __LINE__ "exchange/ampl.hpp"

// Guardian //--------------------------------------------------------------------------------------
#ifndef guExchangeAmpl
#define guExchangeAmpl

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

namespace bpp {

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

// Namespaces //------------------------------------------------------------------------------------
#define public_area  exchangeAmpl
#define private_area exchangeAmpl_private

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

extern_module_name;

// Initialization //--------------------------------------------------------------------------------
#define iniExchangeAmpl
has_initializer;

// Macrocommands //---------------------------------------------------------------------------------
#ifdef AMPL_YES
 /*MACROCOMMAND*/
 /* The expression <CODE>prLine</CODE> is integrated into the source code if AMPL is used. */
 #define ampl_yes(prLine) prLine

 /*MACROCOMMAND*/
 /* The expression <CODE>prLine</CODE> is integrated into the source code if AMPL is not used. */
 #define ampl_no(prLine)
#else
 #define ampl_yes(prLine)
 #define ampl_no(prLine) prLine
#endif


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

// Functions Interface //---------------------------------------------------------------------------
namespace public_area {
 inline   void      execute(tcString);
 function void      outInformation(void);
 inline   tyBoolean valid(void);
}

namespace private_area {}

// Errors //----------------------------------------------------------------------------------------
namespace public_area {
 /*ERROR*/ extern_error erLocationParameter;
 /* The <CODE>ampl_location</CODE> parameter is missing in the initialization file. */

 /*ERROR*/ extern_error erProgramExecution; /* Can not execute the AMPL software. */
}

// Constants & Variables //-------------------------------------------------------------------------
/*CONSTANT*/ /* Location of the AMPL software. */
extern_static_constant(public,tyString,goLocation,location);

/*CONSTANT*/ /* Solver used by the AMPL software. */
extern_static_constant(public,tcString,goSolver,solver);

/*CONSTANT*/ /* Version of the AMPL software. */
extern_static_constant(public,tcString,goVersion,version);

extern_dynamic_constant(private,clString,goDummyLocationFlag,?);

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

// Functions Inline //------------------------------------------------------------------------------
namespace public_area {
 //--------------------------------------------------------------------------------------------Valid
 /*FUNCTION*/ /* Indicates if the AMPL can be used. */
 inline tyBoolean valid(void) { return (location()!=*private_area::goDummyLocationFlag); }
 //------------------------------------------------------------------------------------------Execute
 /*FUNCTION*/ /* Makes the AMPL software execute a command. */
 inline void execute(tcString agCommand) {
  if (not valid()) send_inline_error(erProgramExecution,"execute");

  if (system((clString(location())+" "+agCommand).data())!=0)
   send_inline_error(erProgramExecution,"execute");
 }
}

namespace private_area {}

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

// End //-------------------------------------------------------------------------------------------
}
#undef dll_export
#undef public_area
#undef private_area
#endif
 
//==================================================================================================
// E x c h a n g e                                                                   Implementation
// A m p l
//                                                                                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__ "exchange/ampl.cpp"

// DLL Belonging //---------------------------------------------------------------------------------
#define EXCHANGE_DLL

// Headers //---------------------------------------------------------------------------------------
#include <bpp/exchange/ampl.hpp> /*INTERFACE*/

namespace bpp {

// Namespaces //------------------------------------------------------------------------------------
#define public_area  exchangeAmpl
#define private_area exchangeAmpl_private
#define dll_export   DLL_EXPORT

namespace public_area  {}
namespace private_area {}

static_module_name("Exchange/Ampl");

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

// Errors //----------------------------------------------------------------------------------------
namespace public_area {
 static_error erLocationParameter;
 static_error erProgramExecution;
}

// Constants & Variables //-------------------------------------------------------------------------
static_constant(tyString,goLocation);
static_constant(tcString,goSolver);
static_constant(tcString,goVersion);

dynamic_constant(clString,goDummyLocationFlag);

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

// Functions Implementation //----------------------------------------------------------------------
namespace public_area {
 //-----------------------------------------------------------------------------------OutInformation
 /*FUNCTION*/ /* Displays information about the AMPL software. */
 function void outInformation(void) {
  using namespace environment;

  inform("-=-=- A M P L   I N F O R M A T I O N -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-");
  out(" ",false,true); out(version(),true);
  out(" Uses ",false,true); out(solver()); out(" solver",true);
  out(" Located at ",false,true); out(location(),true);
  out("-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-",true,true);
 }
}

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

    method_name("initializer::constructor");

    erLocationParameter.create("The 'ampl_location' parameter is missing.");
    erProgramExecution.create("AMPL - Can't execute the program.");

    if (environment::parameters().count(clString("ampl_location"))==0)
     send_error(erLocationParameter);

    goLocation = copy(environment::parameter(clString("ampl_location")));
    goSolver   = AMPL_SOLVER;
    goVersion  = AMPL_VERSION;

    goDummyLocationFlag = new_object(clString("dummy.exe"));
   }

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

   delete_array(goLocation);
   delete_object(goDummyLocationFlag);
  }

  initializer_catch;
 }
}

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