//************************************
//
// Name : Launch.c
//
//************************************

//**** Header files

//** OS Include files

#include <exec/memory.h>
#include <workbench/startup.h>
#include <libraries/wbstart.h>
#include <dos/dos.h>
#include <dos/dostags.h>

//** OS function prototypes

#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/wbstart_protos.h>
#include <clib/macros.h>

//** OS function inline calls

#include <pragmas/exec_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/wbstart_pragmas.h>

//** ANSI C includes

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

//** Application include

#include "Prefs.h"
#include "launch.h"
#include "Librarian.h"


//**** Local Storage

static ULONG ConIOTags[] = { SYS_Output, 0, SYS_Input, 0, SYS_Asynch, 1,
                             SYS_UserShell, 1, TAG_DONE };
static ULONG NoIOTags[]  = { SYS_Asynch, 1, SYS_UserShell, 1, TAG_DONE, };


//**** Aux functions

void Launch_WB(struct ProgNode *pn, long argc, struct WBArg *argv);
void Launch_CLI(struct ProgNode *pn, long argc, struct WBArg *argv);
void Launch_Rexx(struct ProgNode *pn, long argc, struct WBArg *argv);
void Launch_Batch(struct ProgNode *pn, long argc, struct WBArg *argv);


void Launch(struct ProgNode *pn, long argc, struct WBArg *argv) {
  if (NULL==pn) {
    Launch_WB(pn,argc, argv);
  } else
  switch ( pn->pn_LaunchCode & LC_ENV_MASK ) {
    case LC_WB :
      Launch_WB(pn,argc, argv);
      break;
    case LC_CLI:
      Launch_CLI(pn,argc, argv);
      break;
    case LC_REXX:
      Launch_Rexx(pn,argc, argv);
      break;
    case LC_BATCH:
      Launch_Batch(pn,argc, argv);
      break;
    default:
      //intf("unknown LC_ENV\n");
      break;
  } // switch
} // Launch

void Launch_WB(struct ProgNode *pn, long argc, struct WBArg *argv) {
  static ULONG mytags[]={
    WBStart_Name,		0L,
    WBStart_DirectoryName,	0L,
    WBStart_Stack,		0L,
    WBStart_Priority,		0L,
    WBStart_ArgumentCount,	0L,
    WBStart_ArgumentList,	0L
  };

  if (NULL==pn) {
    mytags[1]=(ULONG)PrefsProgName;
    mytags[3]=(ULONG)PrefsProgDir;
    mytags[5]=4096;
    mytags[7]=0;
    mytags[9]=0L;
    mytags[11]=0L;
    WBStartTagList( (struct TagItem *)mytags);
  } else {
    mytags[1]=(ULONG)pn->pn_Filename;
    mytags[3]=(ULONG)pn->pn_Directory;
    mytags[5]=MAX(4096,pn->pn_Stack);
    mytags[7]=pn->pn_Priority;
    switch ( pn->pn_LaunchCode & LC_ARG_MASK ) {
      case LC_EACH :
        if (NULL!=argc) {
          mytags[9]=1L;
          for ( ; argc-- ; ) {
            mytags[11]=(ULONG)argv++;
            WBStartTagList( (struct TagItem *)mytags);
          } // for
          break;
        }; // fall through to NONE
      case LC_NONE :
        mytags[9]=0L;
        mytags[11]=0L;
        WBStartTagList( (struct TagItem *)mytags);
        break;
      case LC_ALL  :
        mytags[9]=argc;
        mytags[11]=(ULONG)argv;
        WBStartTagList( (struct TagItem *)mytags);
        break;
      default :
        //intf("Bad ARG (WB)\n");
        break;
    } // switch
  }
} // Launch_WB

void MyRun(struct ProgNode *pn, STRPTR cline) {

  STRPTR ConsoleName="CON:0/0/640/128/Output/AUTO/WAIT/CLOSE";
  APTR ConsoleTask=0;

  if (ConIOTags[1]=Open(ConsoleName, MODE_NEWFILE)) {
    struct Process *Proc=((struct Process *)FindTask(0L));
    struct FileHandle *FH;

    ConsoleTask=Proc->pr_ConsoleTask;
    FH=BADDR(ConIOTags[1]);
    SetConsoleTask(FH->fh_Type);
    ConIOTags[3]=Open("*", MODE_OLDFILE);
  }; // if

  if (ConIOTags[1])
    System(cline, (struct TagItem *)&ConIOTags);
  else
    System(cline, (struct TagItem *)&NoIOTags);

  if (ConsoleTask) SetConsoleTask(ConsoleTask);
} // MyRun

void Launch_CLI(struct ProgNode *pn, long argc, struct WBArg *argv) {
  long templsize=0;
  STRPTR templ=NULL;
  long clinesize=0;
  STRPTR cline=NULL;
  BPTR newl,oldl;
  long i,j;
  struct WBArg *ta;
  char *p;
  char *q;


  // Create Template
  templsize=strlen(pn->pn_Directory)+2+strlen(pn->pn_Filename);
  templ=AllocVec(templsize,MEMF_CLEAR);
  strcpy(templ,pn->pn_Directory);
  AddPart( templ, pn->pn_Filename, templsize );
  //intf("Template = '-%s'\n",templ);

  switch ( (strstr(templ,"%s"))?pn->pn_LaunchCode & LC_ARG_MASK:LC_NONE ) {
    case LC_NONE:
      MyRun(pn,templ);
      break;
    case LC_EACH:
      // Count longest wbarg name
      for ( i=argc, ta=argv; i--; ta++) {
        j=strlen(ta->wa_Name);
        if (j>clinesize) clinesize=j;
      } // for
      // create space for command line
      cline=AllocVec(clinesize+templsize,NULL);
      // copy command part
      p=strstr(templ,"%s");
      *p=0;
      strcpy(cline,templ);
      q=cline+(p-templ);
      p+=2;
      // Launch programs
      for( ; argc-- ; argv++) {
        newl = DupLock(argv->wa_Lock);
        oldl = CurrentDir(newl);
        strcpy(q,argv->wa_Name);
        strcat(q,p);
        MyRun(pn,cline);
        CurrentDir(oldl);
        UnLock(newl);
      } // for
      FreeVec(cline);
      break;
    case LC_ALL:
      {
        char buffer[512];
        // eval size
        for ( i=argc, ta=argv; i--; ta++) {
          NameFromLock(ta->wa_Lock, buffer, 512);
          clinesize +=strlen(ta->wa_Name)+strlen(buffer)+2;
        } // for
        // create space for command line
        cline=AllocVec(clinesize+templsize,NULL);
        // copy command part
        p=strstr(templ,"%s");
        *p=0;
        strcpy(cline,templ);
        // Add each argument
        for ( i=argc, ta=argv; i--; ta++) {
          NameFromLock(ta->wa_Lock, buffer, 512);
          AddPart(buffer,ta->wa_Name,512);
          strcat(cline,buffer);
          strcat(cline," ");
        } // for
        // copy tail of command line
        strcat(cline,p+=2);
        //intf("%s\n",cline);
        MyRun(pn,cline);
        // CleanUp
        FreeVec(cline);
      } // nada
      break;
    default :
      //intf("Unknown ARG code\n");
      break;
  } // switch
  FreeVec(templ);
} // Launch_CLI

void Launch_Rexx(struct ProgNode *pn, long argc, struct WBArg *argv) {
} // Launch_Rexx

void Launch_Batch(struct ProgNode *pn, long argc, struct WBArg *argv) {
} // Launch_Batch

//**** End of file
