/*[bugsicon]       GNU General Public Licence
   
   This is the "classic" interface to BUGS with no Windows stuff.
   
   The brugs dynamic link library is used in the same way as in the R interface to BUGS:
   via dlopen and dlsym.
   
   The names of commands typed at the command prompt are the same as the names in the
   BUGS scipt language and of the R functions in BRugs.
   
   The mappings between the command names and the Component Pascal procedures to
   execute them are in the file Bugs/Rsrc/Script.txt
   
*/


/*

   Save this file as a .c file before compiling with a C compiler.

   Compile with gcc -o CBugs CBugs.c -ldl   on Linux and use the shell script LinBUGS to
   provide the command line arguments.
   
   Compile with the Cygwin c compiler gcc -o CBugs.exe CBugs.c    on Windows
   The Windows version needs the library cygwin1.dll. Use the short cut ClassicBUGS to provide       the command line arguments.

*/

#include <dlfcn.h>
#include <stdio.h>
#include <string.h>

int
main (int argc, char **argv)
{
   void * handle;
   void (*SetRootDir) (char **string, int *len);
   void (*SetTempDir) (char **string, int *len);   
   void (*EmbedCommand) (char ** string, int *len);
   char ch;   
   char *error;
   char *root;
   char *tempDir;
   char *dll;
   char *library;
   char *buffer;
   char *logFile;
   char *cmd;
   char cmdLine[256];
   int i;   
   int len;
   int len1;
   int len2;
   int len3;
   int pos;   
   int res;
   int tabs[20];
   FILE *fp;
   FILE *log;

   if(argc != 4) {
      fprintf(stderr, "%s\n", "error must give root directory of BUGS, temp directory and library name as command line parameter");
      exit(1);
   }   
   root = argv[1],   
   len1 = strlen(root);
   tempDir = argv[2];
   len2 = strlen(tempDir);
   dll = argv[3];
   len3 = strlen(dll);
   library = (char *) malloc((len1 + len3 + 1) * sizeof(char));
   strcpy(library, root);
   strcat(library, dll);
   buffer = (char *) malloc((len2 + 12) * sizeof(char));
   strcpy(buffer, tempDir);
   strcat(buffer, "/buffer.txt");
   logFile = (char *) malloc((len2 + 13) * sizeof(char));
   strcpy(logFile, tempDir);
   strcat(logFile, "/bugslog.txt");
   
   handle = dlopen(library, RTLD_LAZY);
   if (!handle)
   {
      fputs(dlerror(), stderr);
      exit(1);
   }
   
   SetRootDir = dlsym(handle, "SetRootDir");
   error = dlerror();
   if(error != NULL)
   {
      fprintf(stderr, "%s\n", error);
      exit(1);
   }
   
   SetTempDir = dlsym(handle, "SetTempDir");
   error = dlerror();
   if(error != NULL)
   {
      fprintf(stderr, "%s\n", error);
      exit(1);
   }

   EmbedCommand = dlsym(handle, "EmbedCommand");
   error = dlerror();
   if(error != NULL)
   {
      fprintf(stderr, "%s\n", error);
      exit(1);
   }   
   
   len = strlen(root);
   SetRootDir(&root, &len);
   
   len = strlen(tempDir);
   SetTempDir(&tempDir, &len);
   
   
/*   Initialize by executing Pascal procedures corresponding to INIT()   */
   len = 6;
   cmd = (char *) malloc ((len + 1) * sizeof(char));
   strcpy(cmd, "INIT()");
   EmbedCommand(&cmd, &len);
   free(cmd);
   
   log = fopen(logFile, "w");

   tabs[0] = 1;
   tabs[1] = 20;
   i = 2;
   while (i < 20) {
      tabs[i] = 12;
      i = i + 1;
   }
   while (1){
      printf("%s", "Bugs> ");
      fprintf(log, "%s", "Bugs> ");
      gets(cmdLine);
      fprintf(log, "%s", cmdLine);
      fprintf(log, "%c", '\n');
      if (strcmp(cmdLine, "modelQuit()") == 0) exit(0);
      len = strlen(cmdLine);
      cmd = (char *) malloc((len + 1) * sizeof(char));
      strcpy(cmd, cmdLine);
      
      EmbedCommand(&cmd, &len);
      free(cmd);
      
      fp = fopen(buffer, "r");
      ch = fgetc(fp);
      pos = 0;
      i = 0;
      while (ch != EOF) {
         pos = pos + 1;
         if (ch == '\n') {
            pos = 0;
            i = 0;
         }
         if (ch == '\t') {
            pos = pos % tabs[i];
            while (pos < tabs[i]) {
               pos = pos + 1;
               printf("%c", ' ');
               fprintf(log, "%c", ' ');
            }
            i = i + 1;
            pos = 0;
         }
         if (ch != '\t') {
            printf("%c", ch);
            fprintf(log, "%c", ch);
            
         }
         ch = fgetc(fp);
      }
      fclose(fp);
      
   }
   fclose(log);
   dlclose(handle);
   return 0;
}