#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "..\..\lingd18.h"

/*

  This code calls the LINGO DLL to solve a sparse transportation model
  contained in the model file transparse.lng;

*/
/////////////////////////////////////////////////////////////////////////////

int __stdcall MyCallback( void* pModel, int nReserved, void* pUserData)
{

   // this callback function will be called periodically by the Lingo solver 

   int* pnCallbacks = (int*) pUserData;
   ++*pnCallbacks;
   if ( !(*pnCallbacks % 10)) printf( "In Callback: %d\n", *pnCallbacks);
   return( 0);

}

/////////////////////////////////////////////////////////////////////////////

void __stdcall MyErrorCallback( void* pModel, void* pUserData, int nErrorCode,
 char* pcErrorText)
{
   // this callback function will be called whenever Lingo hits an error

   printf( "In Error Callback: Error %d:\n%s \n", nErrorCode, pcErrorText);
   return;

}

/////////////////////////////////////////////////////////////////////////////

void main()
{

   char cScript[256];

   char cWarehouses[64] = "RENO\nCHICAGO\nNEWARK";
   char cCustomers[64] = "FRESNO\nDALLAS\nSTLOUIS\nMIAMI";
   char cRoutes[128] = "RENO\nFRESNO\nRENO\nSTLOUIS\nCHICAGO\nDALLAS\nNEWARK\nSTLOUIS\nNEWARK\nMIAMI";
   char cRoutes2[128];
   int nError=-1, nPointersNow;
   int nCallbacks = 0;
   double dObjective, dStatus=-1.;
   double dCapacity[] = {44., 25., 34.};
   double dDemand[] = {15., 17., 22., 12.};
   double dCost[] = {10., 22., 12., 14., 16.};
   double dVolume[] = {-1.,-1.,-1.,-1.,-1.};

   // create the LINGO environment object
   pLSenvLINGO pLINGO;
   pLINGO = LScreateEnvLng();
   if ( !pLINGO) 
   {
      printf( "Can''t create LINGO environment!\n");
      goto FinalExit;
   }

   // Pass LINGO a pointer to our callback function
   nCallbacks = 0;
   nError = LSsetCallbackSolverLng( pLINGO, &MyCallback, &nCallbacks);
   if ( nError) goto ErrorExit;

   // Pass LINGO a pointer to our callback function
   nCallbacks = 0;
   nError = LSsetCallbackErrorLng( pLINGO, &MyErrorCallback, NULL);
   if ( nError) goto ErrorExit;

   // Open LINGO's log file  
   nError = LSopenLogFileLng( pLINGO, "LINGO.log");
   if ( nError) goto ErrorExit;

   // Pass memory transfer pointers to LINGO

   // @POINTER(1)
   nError = LSsetPointerLng( pLINGO, cWarehouses, &nPointersNow); 
   if ( nError) goto ErrorExit;

   // @POINTER(2)
   nError = LSsetPointerLng( pLINGO, cCustomers, &nPointersNow); 
   if ( nError) goto ErrorExit;

   // @POINTER(3)
   nError = LSsetPointerLng( pLINGO, cRoutes, &nPointersNow); 
   if ( nError) goto ErrorExit;

   // @POINTER(4)
   nError = LSsetPointerLng( pLINGO, &dCapacity, &nPointersNow); 
   if ( nError) goto ErrorExit;

   // @POINTER(5)
   nError = LSsetPointerLng( pLINGO, &dDemand, &nPointersNow); 
   if ( nError) goto ErrorExit;

   // @POINTER(6)
   nError = LSsetPointerLng( pLINGO, dCost, &nPointersNow); 
   if ( nError) goto ErrorExit;

   // @POINTER(7)
   nError = LSsetPointerLng( pLINGO, cRoutes2, &nPointersNow); 
   if ( nError) goto ErrorExit;

   // @POINTER(8)
   nError = LSsetPointerLng( pLINGO, dVolume, &nPointersNow); 
   if ( nError) goto ErrorExit;

   // @POINTER(9)
   nError = LSsetPointerLng( pLINGO, &dObjective, &nPointersNow); 
   if ( nError) goto ErrorExit;

   // @POINTER(10)
   nError = LSsetPointerLng( pLINGO, &dStatus, &nPointersNow); 
   if ( nError) goto ErrorExit;

   // Here is the script we want LINGO to run
   strcpy_s( cScript, sizeof( cScript), 
    "SET ECHOIN 1 \n TAKE TRANSPARSE.LNG \n GO \n QUIT \n");

   // Run the script
   nError = LSexecuteScriptLng( pLINGO, cScript);
   if ( nError) goto ErrorExit;

   // Close the log file
   LScloseLogFileLng( pLINGO);

   // Any problems?
   if ( nError || dStatus != LS_STATUS_GLOBAL_LNG)
   {

      // Had a problem   
      printf( "Unable to solve!");

   } else {

      int i = 0, j, k, n = 0;
      while ( cRoutes2[ i])  
      {
          for ( j = 0; j<2; j++) 
          {
             while ( cRoutes2[ i] != '\n') putchar( cRoutes2[ i++]);
             for ( k = 0; k<3; k++) putchar( ' ');
             i++;
          }
          printf( "%g", dVolume[ n++]);
          putchar( '\n');
      }
         
   }

   goto NormalExit;

ErrorExit:
   printf("LINGO Error Code: %d\n", nError);

NormalExit:
   LSdeleteEnvLng( pLINGO);

FinalExit: ;

}

