/* HippoPlayer ARexx script for Filer.                      (v 1.2) *
 * ================================================================ *
 *                                                                  *
 * Adds selected files into HiP's playlist and randomplays them.    *
 * If HiP isn't already running it is run first.                    *
 *                                                                  *
 * If directories were selected this script recurses through all    *
 * subdirectories, so it is possible to add all your modules to     *
 * HiP's playing list just by selecting your module directory!      *
 *                                                                  *
 * If nothing was selected (user just pushed the button) then       *
 * we tell HiP to Random Play with it's current playlist unless     *
 * there's only one module in it, in which case we eject it.        *
 * But if the playlist is empty already we advice the user to       *
 * select a module before fooling around...                         *
 *                                                                  *
 *------------------------------------------------------------------*
 * NOTE! This script checks if a file has a suffix or prefix that   *
 * indicates something else than a module, for example "foo.info",  *
 * "program.readme" or ".backdrop". Unfortunately this also makes   *
 * the script noticeably slower, so this feature is disabled by     *
 * default. If you want to use it, see CONFIGURATION below.         *
 *------------------------------------------------------------------*
 *                                                                  *
 * Version 1.2: now supports double-clicking of modules! This is    *
 * done by adding the following line to the end of your Filer.RC:   *
 *                                                                  *
 * CLASS "(mod|MED).#?","","RX HippoPlay.filer %f"                  *
 *                                                                  *
 ***** Requirements: rexxsupport.library, HiP, and Filer...    ******
 * Remember to replace the HippoPath variable below with the        *
 * correct path of HiP in your system! You might also want to set   *
 * HiP's screen to FilerScreen in the HiP-prefs, though this script *
 * opens HiP on FilerScreen automatically anyway.                   *
 *                                                                  *
 * Sorry for the messyness, especially in dirpart, but it works! :) *
 * If it fails for you, contact me:                                 *
 * Janne Simonen - jsimonen@cc.joensuu.fi                           */


/* -------------------------------------------------------------------- */
/**** CONFIGURATION: change the following lines to suit your system! ****/
/* -------------------------------------------------------------------- */

HippoPath = 'dh2:HippoPlayer/Hip'               /* Where to find HiP    */

/* This flag controls the printing of extra information on FilerScreen. */
/* 0 = OFF, 1 = ON. If you don't have composers' names in filenotes and */
/* don't want to know how big the mod is, switch this off.              */

Verbose = 1                                     /* Default: speak up!   */

/* This flag turns filename checking on/off, 0 = OFF, 1 = ON    */

CheckFileNames = 0  /* Default: don't check filenames for ".info"s etc. */

/* These suffixes/prefixes indicate that a file really is NOT a module! */
/* You can add your own, just remember to change crapnumbers accordingly*/
/* The more you add, the slower the script gets, so...                  */

IF ~(CheckFileNames = 0) THEN DO    /* if checking is not disabled  */

    crapsufnumber = 3               /* number of crap suffixes  */
    crapsuffix.1 = '.info'          /* disregard these suffixes */
    crapsuffix.2 = '.readme'
    crapsuffix.3 = '.doc'

    crapprefnumber = 1              /* number of crap prefixes  */
    crapprefix.1 = '.'              /* disregard these prefixes */
END

ELSE DO         /* if checking is disabled then accept ALL files    */
    crap = 0    /* regardless of filename. Don't change this!       */
END

/* Random play if nothing selected? If not then show modinfo    */

RandPlay = 0


/* -------------------------------------------------------------------- */
/* ******************* MAIN PROGRAM STARTS HERE *********************** */
/* -------------------------------------------------------------------- */

OPTIONS RESULTS
PARSE ARG doubleclickname   /* Read possible argument (double-clicked mod) */

SIGNAL ON IOERR    /* Trap for IO-Errors (filehandling etc.)    */
SIGNAL ON BREAK_C  /* Trap for control-c break (doesn't work?)  */

/********** Make sure HiP is running (with an open ARexx port) **********/

IF ~SHOW("Ports","HIPPOPLAYER") THEN DO
    ADDRESS 'FilerRexx'
    'STATUS Loading HippoPlayer...'
    ADDRESS 'COMMAND' 'run >NIL: '||HippoPath
    
    /* give HiP exactly 5 seconds time to emerge */
    ADDRESS 'FilerRexx'
    'STATUS Waiting for HippoPlayer to open its ARexx port...'
    TIME('R')
    DO WHILE ((TIME('E')<5) & (~SHOW("Ports","HIPPOPLAYER")))
    END
    
    IF ~SHOW("Ports","HIPPOPLAYER") THEN DO
        ADDRESS 'FilerRexx'
        "STATUS HippoPlayer didn't show up!"
        EXIT
    END

    ADDRESS 'HIPPOPLAYER'
    'PUBSCREEN FilerScreen'     /* open HiP on FilerScreen  */
    'ZIP 0'                     /* and zip the window.      */
END

/****************** Check if a file was double-clicked ******************/

IF ~( doubleclickname = "" ) THEN DO

    /* remove possible '"'s from the file name, because they're  */
    /* automatically added by ARexx below. */
    doubleclickname = COMPRESS( doubleclickname, '"' )

    ADDRESS 'HIPPOPLAYER'
    'CLEAR'
    'ADD '||doubleclickname     /* Add the mod to Hip's playlist */

    Message = 'HiP: Adding module "'||doubleclickname||'" into playlist...'
    IF LENGTH( Message ) < 67 THEN DO
        Message = OVERLAY( 'Please wait!', Message, 68)
    END

    ADDRESS 'FilerRexx'
    'STATUS '||Message              /* tell user what's happening   */

    ADDRESS 'HIPPOPLAYER'
    'CHOOSE 1'
    'PLAY'                          /* tell hip to make some noise  */

    'GET PLAY'                      /* check if anything is playing */
    IF RESULT = 0 THEN DO           /* if not -> we're very sorry...*/
      ADDRESS 'FilerRexx'           /* ...probably out of memory    */
      "STATUS HiP: Sorry, can't play this one!"
    END

    EXIT                            /* Enough done, let's retire... */
END

/****** Open a lib to get SHOWDIR() to be used with directories  ********/

CALL ADDLIB('rexxsupport.library', 0, -30, 0)

/********************* Give HiP the modules to play *********************/

ADDRESS 'FilerRexx'

/* Get source directory name, append "/" if it is not a device name     */
GETSOURCEPATH
srcdir = RESULT
IF RIGHT( srcdir, 1 ) ~= ":" THEN srcdir = srcdir || "/"

GETNUMENTRIES                   /* get number of sourcedir entries  */
numentries = RESULT

DO j = 1 TO numentries          /* loop through all entries         */
  GETNAME j                     /* get jth entry                    */
  entry = RESULT

  type = LEFT( entry, 1 )       /* parse filetype (f, d, F, D)      */
  name = SUBSTR( entry, 2 )     /* parse filename                   */

  SELECT                        /* it's either a file OR a directory*/

    /* If entry is a selected FILE we add it to playlist            */

    WHEN type = 'f' THEN DO

      IF CheckFileNames = 1 THEN DO     /* if checking not disabled     */
        CALL FileCheck                  /* check if it's a module       */
      END

      IF crap = 0 THEN DO               /* if it is, then lets add...   */

        IF checkflag ~= 'TRUE' THEN DO  /* if it's the first file to    */
          ADDRESS 'HIPPOPLAYER'         /* add we clear the playlist    */
          'CLEAR'
          checkflag = 'TRUE'
        END

        ADDRESS 'FilerRexx'
                                        /* just finetuning the message..*/
        Message = 'HiP: Adding module "'||name||'" into playlist...'
        IF LENGTH( Message ) < 67 THEN DO
          Message = OVERLAY( 'Please wait!', Message, 68)
        END

        'STATUS '||Message              /* tell user what's happening   */
        ADDRESS 'HIPPOPLAYER'
        'ADD '||srcdir||name            /* add the file into playlist   */

      END /* IF - FileCheck   */

      ADDRESS 'FilerRexx'
      TOGGLEENTRY j                     /* de-select                    */

    END /* WHEN */

    /* If entry is a DIRECTORY we scan it through and see what's in     */

    WHEN type = 'd' THEN DO

      Dirname = srcdir||name
      /* get a string containing the filenames separated with a '0a'x   */
      Filelist = SHOWDIR( Dirname, 'FILE', '0a'x )
      /* if string not empty we append a '0a'x (to make things work...) */
      IF Filelist ~= '' THEN Filelist = Filelist || '0a'x

      CALL FileNameParser   /* add all the files in the dir to playlist */

      /* See if there are any SUBDIRECTORIES and scan them for files    */

      i = 1                                         /* recursion level  */
      CALL DirRecurser      /* let's delve through the subdirectories   */
      ADDRESS 'FilerRexx'
      TOGGLEENTRY j

    END /* WHEN - DIRECTORY */

    OTHERWISE                   /* ignore entries not selected          */

  END /* SELECT */

END /* DO j */

/* -------------------------------------------------------------------- */
/* Ok, we've scanned all selected files/dirs and added the files to     */
/* playlist, now it's time to do some bonus stuff...                    */
/* -------------------------------------------------------------------- */

/* If no file (or module! FileNameCheck...) was selected then:          */

IF checkflag ~= "TRUE" THEN DO

    ADDRESS 'HIPPOPLAYER'
    'GET NFIL'                    /* get number of files in playlist    */
    numberoffiles = RESULT

    /* if only non-module files were selected then this helps us complain */
    IF NameCheckFlag = 1 THEN numberoffiles = 0

    IF numberoffiles = 1 THEN DO  /* if it's one we eject the mod       */
        'CLEAR'
        'EJECT'
        ADDRESS 'FilerRexx'
        'STATUS HiP: Ejected the only module in the playlist.'
        EXIT
    END

    IF numberoffiles = 0 THEN DO  /* Nothing playing? Let's complain    */
        ADDRESS 'FilerRexx'
        'STATUS HiP: It might help if you selected a module to play! :)'
        EXIT
    END

    IF RandPlay = 0 THEN
    CALL DisplayStuff   /* Show info if multiple entries in playlist*/

END

ADDRESS 'FilerRexx'
'STATUS HiP: Loading module, please wait...'

ADDRESS 'HIPPOPLAYER'

'GET NFIL'                          /* get number of files in playlist  */
                                    /* because RANDPLAY doesn't work    */
IF RESULT = 1 THEN DO               /* if there's only one file...      */
    'CHOOSE 1'                      /* ...at least not with HiP207.     */
    'PLAY'
END                                 /* single file: let's play it.      */
ELSE 'RANDPLAY'                     /* multiple files: Random Play.     */

'GET PLAY'                          /* check if anything is playing     */
playornot = RESULT
IF playornot = 0 THEN DO            /* if not -> we're very sorry...    */
    ADDRESS 'FilerRexx'             /* ...probably out of memory        */
    "STATUS HiP: Sorry, can't play this one!"
    EXIT
END

DisplayStuff:
/* Now a mod is playing, so we just display some info on FilerScreen    */

'GET NAME'                          /* get mod name so that we can show */
modname = RESULT                    /* it on Filer's statusbar          */

IF modname = '' THEN DO             /* if modname doesn't exist         */
    'GET CNAM'                      /* we simply use filename           */
    modname = RESULT
                                    /* strip off any prefix (like mod.) */
    /* a little fix for a bug in HiP207: CNAM gives path too! K-P? :)   */
    DivPos = max(lastpos(':', modname),lastpos('/', modname)) +1
    modname = substr(modname, DivPos)
    modname = substr(modname, lastpos('.', modname, 6) +1)

END /* IF */

modname = SPACE( modname, 1)        /* remove extra spaces from name    */

IF Verbose = 0 THEN DO              /* if Verbose is switched off we    */
    ADDRESS 'FilerRexx'             /* only tell the module's name      */
    'STATUS HiP: Playing "'||modname'"'
    EXIT                            /* and exit.*/
END

'GET COMM'                          /* get filenote/comment because     */
comment = RESULT                    /* I have the composer's name in it */

IF comment = '' THEN DO             /* no comment? Then give type&size  */
    'GET TYPE'                      /* instead to have some chrome :)   */
    modtype = RESULT
    'GET SIZE'
    modsize = RESULT

    comment = 'HiP: Playing '||modtype||' module "'||modname'"'

                            /* check that announcement fits on screen   */
    IF LENGTH( comment ) < 61 THEN DO
        comment = comment || ', size '||modsize||' bytes'
    END
                                    /* announce what HiP is playing     */
    ADDRESS 'FilerRexx'             /* with modtype and modsize         */
    'STATUS ' || comment

END /* IF */

ELSE DO
    comment = 'by ' || comment      /* announce with composer's name    */
    ADDRESS 'FilerRexx'
    'STATUS HiP: Playing "'||modname||'" '||comment
END /* ELSE */

EXIT                                /* voilá! */


/* -------------------------------------------------------------------- */
/*************** END OF MAIN PROGRAM, SUBROUTINES FOLLOW ****************/
/* -------------------------------------------------------------------- */


FileNameParser:
/* Parses filenames from the string 'Filelist' and adds them to playlist*/
/* Gets the complete path from the variable 'Dirname'.                  */
/* Filelist looks like "file1'0a'xfile2'0a'xfile3'0a'xfile4'0a'x".      */

 DO WHILE POS( '0a'x, Filelist ) > 0    /* while we still have files    */

    Slashpos = POS( '0a'x, Filelist )   /* find the next separator      */
    name = LEFT( Filelist, Slashpos -1) /* extract filename             */

    IF CheckFileNames = 1 THEN DO
      CALL FileCheck                    /* see if it is a module        */
    END

    IF crap = 0 THEN DO                 /* if yes, add it to playlist:  */

      IF checkflag ~= 'TRUE' THEN DO    /* if this is the first file    */
          ADDRESS 'HIPPOPLAYER'         /* to add to playlist then      */
          'CLEAR'                       /* clear the list first         */
          checkflag = 'TRUE'
      END

      ADDRESS 'FilerRexx'
                                        /* just finetuning the message..*/
      Message = 'HiP: Adding module "'||name||'" into playlist...'
      IF LENGTH( Message ) < 67 THEN DO
          Message = OVERLAY( 'Please wait!', Message, 68)
      END

      'STATUS '||Message
      ADDRESS 'HIPPOPLAYER'
      'ADD '||Dirname||'/'||name        /* add the mod to playlist      */

    END /* IF - FileCheck */
                                /* Strip out added filename from string */
    Filelist = SUBSTR( Filelist, Slashpos +1)

 END /* WHILE */

RETURN /* END OF SUBROUTINE ----------------------------------------*/


DirRecurser:
/* Recurses through all the subdirectories of a directory, then     */
/* calls FileNameParser to add the files in them into playlist.     */

/* Get list of subdirectories                                       */
Dirlist.i = SHOWDIR( Dirname, 'DIR', '0a'x)
IF Dirlist.i ~= '' THEN Dirlist.i = Dirlist.i || '0a'x

/* Go through the subdirs one by one, adding any files to playlist  */
DO WHILE POS( '0a'x, Dirlist.i ) > 0

    Slashpos = POS( '0a'x, Dirlist.i )          /* find the divider */
    dname = LEFT( Dirlist.i, Slashpos -1)       /* get subdirname   */
    Dirlist.i = SUBSTR( Dirlist.i, Slashpos +1) /* strip it off     */

    Dirnamebak.i = Dirname                /* take backup of Dirname */
    Dirname = Dirname || '/' ||dname      /* make subdirectorypath  */

    Filelist = SHOWDIR( Dirname, 'FILE', '0a'x)    /* make filelist */
    IF Filelist ~= '' THEN Filelist = Filelist || '0a'x

    CALL FileNameParser     /* add any files in subdir to playlist  */

    i = i + 1                           /* increase recursion level */

    CALL DirRecurser        /* call subroutine itself recursively   */

    i = i - 1                           /* decrease recursion level */

    Dirname = Dirnamebak.i              /* get back saved Dirname   */
END

RETURN  /* END OF SUBROUTINE -----------------------------------*/


FileCheck:
/* Checks if file clearly is not a module (.info .readme...)    */
/* Gets the filename from a global variable called "name"       */
/* If file is not a mod, returns crap = 1, else returns crap=0. */
/* Bad suf(/pre)fixes are stored in crapsuf(/pre)fix variable.  */

a = 1

DO WHILE a < (crapsufnumber+1)
    /* Check suffix */
    IF RIGHT( name, LENGTH( crapsuffix.a ) ) = crapsuffix.a THEN DO
        crap = 1            /* file is not a module!        */
        NameCheckFlag = 1   /* a non-module file was found  */
        RETURN
    END
    a = a + 1
END

a = 1

DO WHILE a < (crapprefnumber+1)
    /* Check prefix */
    IF LEFT( name, LENGTH( crapprefix.a ) ) = crapprefix.a THEN DO
        crap = 1            /* file is not a module!    */
        NameCheckFlag = 1   /* a non-mod was selected   */
        RETURN
    END
    a = a + 1
END

crap = 0    /* file passed the check - it's no crap! :) */

RETURN      /* END OF SUBROUTINE -------------------------------*/


IOERR:      /* I/O-Error trap, not tested, might even work...   */

ADDRESS 'FilerRexx'
'STATUS HiP: Sorry, an I/O-error has occurred on line '||SIGL||'!'
'ALERTBOX I/O error - something is wrong!|File "'||name||'" was being processed.'
EXIT


BREAK_C:    /* Break trap, never had this work...   */

ADDRESS 'FilerRexx'
"STATUS HiP: Break request detected - I won't play anything!"
'NONE'
EXIT
