(*
 * Library:  OWork:mod/cddb.library
 * Version   44.21
 *)

MODULE cddb;
(* $StackChk- $RangeChk- $CaseChk- $OvflChk- $ReturnChk- $TypeChk- $NilChk- *)
IMPORT
  y: SYSTEM, e := Exec, I: Intuition, u: Utility;

CONST
   name *= "cddb.library"; version *= 44;

TYPE
   cddbBasePtr* = UNTRACED POINTER TO cddbBase;
   cddbBase   * = STRUCT (libNode-: e.Library);
   END;

CONST
   (* the max. size (incl ending 0 byte!) of various used strings *)
   maxLenCateg  *=  30;
   maxLenArtist *= 100;
   maxLenDTitle *= 100;
   maxLenTTitle *= 100;
   maxTracks    *=  99;

(* Error codes *)
   errNoError		*= 0; (* entry found *)
   errNoTCPStack	*= 1; (* No TCP/IP stack is running, go online first! *)
   errResolve		*= 2; (* failed to resolve the host *)
   errSocket		*= 3; (* s.Socket() failed *)
   errConnect		*= 4; (* s.Connect() failed *)
   errServerError	*= 5; (* Server comes up with an error after connect *)
   errHello             *= 6; (* Hello cmd failed *)
   errQuery             *= 7; (* Query cmd failed *)
   errQNoMatch          *= 8; (* No matching discID found in query *)
   errQInexactMatch     *= 9; (* Inexact matches found in query *)
   errNoTags            *=10; (* You must specify the minimal tags aDiscID, aCateg, aArtist, aDTitle, aTTitles! *)
   errNoCDInfo          *=11; (* No CDInfo structure or discID was 0! *)
   errCOUNT             *=12; (* internal: number of errMsgs *)

(* attributes for GetCDDDB *)
   aDiscID 		*= u.user+1; (* LONGPTR: place here a variable for the discID *)
   aCateg               *= u.user+2; (* STRPTR: place here a variable for the category *)
   aArtist              *= u.user+3; (* STRPTR: place here a variable for the artist *)
   aDTitle              *= u.user+4; (* STRPTR: place here a variable for the disc title *)
   aTTitles             *= u.user+5; (* PTR TO ARRAY MAX(INTEGER) OF STRPTR: place here a variable for the track titles,
   				      *					     an array of allocated (not NIL!) STRPTR's *)
   aStatusHook          *= u.user+6; (* HookPtr: gets called with the current status while getting an entry *)
   aMultiGetHook	*= u.user+7; (* HookPtr: gets called after an entry is successfully received, so another CD can be scanned *)
   aForceOnline		*= u.user+8; (* BOOLEAN: Force to go online, if MultiHook = NIL and the disc is already known. *)

TYPE
   TTitlesType * = UNTRACED POINTER TO ARRAY MAX(INTEGER) OF e.STRPTR;

   (* next 2 are from BurnIts CDDB_cdinfo *)
   MSFtimePtr * = UNTRACED POINTER TO MSFtime;
   MSFtime * = STRUCT 
     min   *: SHORTINT; (* C: UByte *)
     sec   *: SHORTINT; (* C: UByte *)
     frame *: SHORTINT; (* C: UByte *)
   END;

   CDInfoPtr * = UNTRACED POINTER TO CDInfo;
   CDInfo * = STRUCT  (* orig: CDDB_cdinfo *)
     msf    *: ARRAY 100 OF MSFtime; 
     tracks *: LONGINT; 
     time   *: LONGINT; 
     discID *: LONGINT; 
   END;

(* structs *)
   pStatusHookPtr *= UNTRACED POINTER TO pStatusHook;
   pStatusHook	  *= STRUCT (msg *: I.Msg)
     str*: e.LSTRPTR;
   END;

   pMultiGetHookPtr *= UNTRACED POINTER TO pMultiGetHook;
   pMultiGetHook    *= STRUCT (msg *: I.Msg)
     err    *: INTEGER; (* see above 'Error codes' *)
     discID *: LONGINT;
     categ  *: ARRAY maxLenCateg  OF CHAR; (* I don't know exactly the length *)
     artist *: ARRAY maxLenArtist OF CHAR; (* I don't know exactly the length *)
     dTitle *: ARRAY maxLenDTitle OF CHAR; (* I don't know exactly the length *)
     tTitles*: ARRAY maxTracks OF UNTRACED POINTER TO ARRAY maxLenTTitle OF CHAR;
     data   *: e.APTR; (* for you! *)
   END;

   TrackPtr   *= UNTRACED POINTER TO Track;
   Track      *= STRUCT
     title *: ARRAY maxLenTTitle OF CHAR;
     length*: INTEGER; (* in seconds *)
   END;

   KnownCDPtr *= UNTRACED POINTER TO KnownCD;
   KnownCD    *= STRUCT
     discID    *: LONGINT;
     length    *: INTEGER; (* in seconds *)
     numTracks *: INTEGER; (* number of tracks *)
     categ     *: ARRAY maxLenCateg  OF CHAR;
     artist    *: ARRAY maxLenArtist OF CHAR;
     title     *: ARRAY maxLenDTitle OF CHAR;
     track     *: ARRAY maxTracks    OF TrackPtr;
   END;

VAR
  base*: cddbBasePtr;

PROCEDURE GetA * {base,- 30} (cdinfo{8}: CDInfoPtr; tagList{8+1}  : u.TagListPtr): LONGINT; (* -> error code, see above for values, 0 -> no error *)
PROCEDURE Get  * {base,- 30} (cdinfo{8}: CDInfoPtr; tag1   {8+1}..: u.Tag)       : LONGINT; (* -> error code, see above for values, 0 -> no error *)
PROCEDURE get  * {base,- 30} (cdinfo{8}: CDInfoPtr; tag1   {8+1}..: u.Tag); (* no error code, for using with MultiGetHook! *)

PROCEDURE LoadKnownCD * {base,- 36} (discID{0}: LONGINT; VAR cd{8}: KnownCD): BOOLEAN;

PROCEDURE CalcDiscID *  {base,- 42} (VAR cdi{8}: CDInfo); (* the discID is written to 'cdi.discID' *)

PROCEDURE ErrorStr   *  {base,- 48} (error{0}: LONGINT): e.APTR;

BEGIN
    base := e.OpenLibrary (name, version);
CLOSE
    IF base # NIL THEN e.CloseLibrary (base) END;
END cddb.
