(********************************************************************

:Program.     SimplePlay.mod
:Contents.    SPObject operations:
:Contents.      - Play Samples/Modules (all SPObjects)
:Contents.    Use it as an example for programming superview.library!
:Copyright.   (c) 1994 by Andreas Ralph Kleinert.
:Copyright.   Freeware. All rights reserved.
:Language.    Oberon-2
:Translator.  A+L Amiga Oberon Compiler V3.11d
:History.     V1.5 indy 27-Dec-95 first Oberon-2 version
:Imports.     SuperPlay.mod
*********************************************************************)

MODULE SimplePlay;

IMPORT
  Break,

   asl:= ASL,
     d:= Dos,
     e:= Exec,
    es:= ExecSupport,
     g:= Graphics,
     i:= Intuition,
     u:= Utility,

  args:= Arguments,
    io,
    ol:= OberonLib,
   str:= Strings,
     s:= SYSTEM,

    sp:= SuperPlay;


CONST

  (*** Help- and Info- Texts ****)
  VerText       = "$VER: SimplePlay(Oberon-2) 1.5 (27.12.95)";

  FileReqText   = "Select Picture File :";

  EntryText1 = "\[1;32;40mSimplePlay(Oberon-2) V1.5 \[0;32;40m\[3;32;40m(FREEWARE)\[0;32;40m\n"
               "(c) 1994 by Andreas Ralph Kleinert.\n"
               "Andreas R. Kleinert, Grube Hohe Grethe 23, D-57074 Siegen, Germany.\n";
  EntryText2 = "Plays Sound Samples and Modules via superplay.library.\n";
  EntryText3 = "USAGE : \[0;33;40mSimplePlay\[0;31;40m [? | -STOP | -REMOVE | <Sample/ModuleFileName>]\n";


  (*** Error-Messages for Leave() and KF_Message()     ***)

  IntuitionLibText = 'You need "intuition.library" V37+ !';
  ASLLibText       = 'You need "asl.library" V37+ !';
  SPLibText        = 'You need "superplay.library" V1+ !';



(* *************************************************** *)
(* *                                                 * *)
(* * Variables for Port Usage                        * *)
(* *                                                 * *)
(* *************************************************** *)


CONST
  PortName  = "SimplePlay.port";
  PortName2 = "SimplePlay_2.port";


VAR
  port1, port2: e.MsgPortPtr;


(* *************************************************** *)
(* *                                                 * *)
(* * Structure-Definitions and Flags                 * *)
(* *                                                 * *)
(* *************************************************** *)

TYPE
  SPMessagePtr = UNTRACED POINTER TO SPMessage;

  SPMessage = STRUCT(msg: e.Message)  (* The Message itself           *)
    flag: LONGSET;     (* (See flag-definitions below) *)
    ext : e.APTR;      (* Future expansions            *)
  END;


CONST
  spfRemove = LONGSET{1};
  spfStop   = LONGSET{2};
  (* #define SPF_CONT   ((ULONG) 3) *)


(* *************************************************** *)
(* *                                                 * *)
(* * Globally Accessed Data                          * *)
(* *                                                 * *)
(* *************************************************** *)

CONST
  TopazAttr = g.TextAttr (s.ADR("topaz.font"), i.topazEighty, g.normal,
                           SHORTSET{g.romFont});
VAR
  verText    : e.STRING;

  argv       : ARRAY 3 OF e.STRING;
  wbLoadname : e.STRING;
  wb         : BOOLEAN;

  request    : asl.FileRequesterPtr;
  tags       : ARRAY 4 OF u.TagItem;
  nameBuffer : e.STRING;

  ourMsg     : SPMessage;
  msgPtr     : e.MessagePtr;
(*-------------------------------------------------------------------*)

PROCEDURE Leave(endText: ARRAY OF CHAR; result1, result2: LONGINT);

VAR
  procPtr: d.ProcessPtr;
  dummy  : LONGINT;

BEGIN
  procPtr:=s.VAL(d.ProcessPtr, ol.Me);

  IF (endText#"") AND (ol.wbStarted=FALSE) THEN
    io.WriteString(endText); io.WriteLn;
  END;

  IF d.base.lib.version>=36 THEN dummy:= d.SetIoErr(result2);
                            ELSE procPtr.result2:=result2;
  END;

  IF result1= d.ok THEN HALT(d.ok);
  ELSIF result1= d.warn  THEN HALT(d.warn);
  ELSIF result1= d.error THEN HALT(d.error);
  ELSIF result1= d.fail  THEN HALT(d.fail);
  ELSE HALT(d.fail);
  END;
END Leave;

(* *************************************************** *
 * *                                                 * *
 * * Remove-Function                                 * *
 * *                                                 * *
 * *************************************************** *)

PROCEDURE Remove();

VAR
  port   : e.MsgPortPtr;
  gotMsg : SPMessagePtr;


BEGIN
  port1:= e.FindPort(PortName); (* still there ? *)
  IF port1#NIL THEN (* remove previous song and task, if existant *)

    port:= es.CreatePort(PortName2, 0);
    IF port#NIL THEN
      ourMsg.msg.replyPort:= port;
      ourMsg.msg.length   := SIZE(SPMessage);
      ourMsg.flag         := spfRemove;
      ourMsg.ext          := NIL;

      port1:= e.FindPort(PortName); (* still there ? *)
      IF port1#NIL THEN
        e.PutMsg(port1, s.ADR(ourMsg));
        e.WaitPort(port);
      END;

      gotMsg:= e.GetMsg(port);
      WHILE gotMsg#NIL DO gotMsg:= e.GetMsg(port); END;
      e.RemPort(port);
    END;
  END;
END Remove;
(*-------------------------------------------------------------------*)

(* *************************************************** *
 * *                                                 * *
 * * Play-Function                                   * *
 * *                                                 * *
 * *************************************************** *)

PROCEDURE Play(filename: ARRAY OF CHAR);

VAR
  handle     : e.APTR;
  retVal     : LONGINT;
  ourWaitport: e.MsgPortPtr;
  gotMsg     : e.MessagePtr;
  run        : BOOLEAN;
  flag       : LONGSET;

BEGIN
  retVal:= sp.errNoError;
  run:= TRUE;

  Remove();

  ourWaitport:= es.CreatePort(PortName, 0);
  IF ourWaitport#NIL THEN

    handle:= sp.AllocHandle(NIL);
    IF handle#NIL THEN
      retVal:= sp.InitHandleAsDOS(handle, NIL);

      IF retVal=0 THEN
        retVal:= sp.SuperPlay(handle, filename);

        IF retVal=0 THEN
          WHILE run=TRUE DO
            e.WaitPort(ourWaitport);
            gotMsg:= e.GetMsg(ourWaitport);
            flag:= gotMsg(SPMessagePtr).flag;

            IF flag=spfRemove THEN sp.FreeHandle(handle); run:= FALSE; END;
            IF flag=spfStop   THEN sp.StopReplay(handle);              END;

            e.ReplyMsg(gotMsg);
          END;
        END;
      END;
    ELSE retVal:= sp.errNoHandle; END;

    gotMsg:= e.GetMsg(ourWaitport);
    WHILE gotMsg#NIL DO
      e.ReplyMsg(gotMsg);
      gotMsg:= e.GetMsg(ourWaitport);
    END;
    e.RemPort(ourWaitport);
  END;

  IF retVal#0 THEN Leave(sp.GetErrorString(retVal)^, 0, 0); END;
END Play;
(*---------------------------------------------------------*)

BEGIN
  verText:= VerText;
  ourMsg.msg.node.type:= e.message;
  port1:= e.FindPort(PortName);

  IF args.NumArgs()>=1 THEN args.GetArg(1, argv[1]); END;
  IF args.NumArgs()>=2 THEN args.GetArg(2, argv[2]); END;

  IF ol.wbStarted=TRUE THEN
    wb:= TRUE; wbLoadname:= argv[1];

  ELSIF (args.NumArgs()>2) OR (argv[1, 0] ="?") OR (argv[2, 0] = "?") THEN
    io.WriteString(EntryText1);
    io.WriteString(EntryText2);
    io.WriteString(EntryText3);
    Leave("", 0, 0);
  END;

  IF sp.LibVer(i.base)  <37 THEN Leave(IntuitionLibText,   d.fail, 103); END;
  IF sp.LibVer(asl.base)<37 THEN Leave(ASLLibText,   d.fail, 103); END;
  IF sp.LibVer(sp.base) <1  THEN Leave(SPLibText,    d.fail, 103); END;


 (* Play *)

  IF (args.NumArgs()<1) AND (wbLoadname="") THEN
    tags[0].tag  := asl.hail;
    tags[0].data := s.ADR("Select Sample/Module to play :");

    tags[1].tag  := asl.okText;
    tags[1].data := s.ADR(" Play ");

    tags[2].tag  := asl.cancelText;
    tags[2].data := s.ADR(" Quit ");

    tags[3].tag  := u.done;
    tags[3].data := NIL;

    request:= asl.AllocAslRequest(asl.fileRequest, NIL);
    IF request#NIL THEN
      IF asl.AslRequest(request, tags)=TRUE THEN

        COPY(request.dir^, nameBuffer);
        IF (nameBuffer[0]# "\o") AND
           (nameBuffer[str.Length(nameBuffer)-1]# ":") AND
           (nameBuffer[str.Length(nameBuffer)-1]# "/") THEN str.Append(nameBuffer, "/");
        END;

        str.Append(nameBuffer, request.file^);
        IF nameBuffer#"" THEN Play(nameBuffer); END;
      END;
      asl.FreeAslRequest(request);
    END;
  ELSE
   IF wbLoadname#"" THEN Play(wbLoadname)
     ELSIF argv[1,0]#"-" THEN Play(argv[1]);
     ELSIF argv[1]="-STOP" THEN
       IF port1#NIL THEN
         port2:= es.CreatePort(PortName2, 0);
         ourMsg.msg.replyPort:= port2;
         ourMsg.msg.length   := SIZE(SPMessage);
         ourMsg.flag         := spfStop;
         ourMsg.ext          := NIL;

         e.PutMsg(port1, s.ADR(ourMsg));
         e.WaitPort(port2);
         msgPtr:= e.GetMsg(port2);
         e.RemPort(port2);
       END;
     ELSIF argv[1]="-REMOVE" THEN Remove(); END;
  END;
  Leave("", 0, 0);

END SimplePlay.
