REM Title:      Director:Menus.System.FindDrives.FindDrive
REM Purpose:    FindDrives
REM Version:    0.10 ,
REM Copyright:  (C) Philip Ludlam 2002

REM This program is free software; you can redistribute it and/or modify it
REM under the terms of the GNU General Public License as published by the Free
REM Software Foundation; either version 2 of the License, or (at your option)
REM any later version.

ON ERROR PROCerror
SYS "XHourglass_On"

Menu%=FNswi_number("Director_Menu")
EndMenu%=FNswi_number("Director_EndMenu")
Option%=FNswi_number("Director_Option")
Command%=FNswi_number("Director_Command")
Dash%=FNswi_number("Director_Dash")
XOS_ReadVarVal%=FNswi_number("XOS_ReadVarVal")
XOS_SetVarVal%=FNswi_number("XOS_SetVarVal")
XOS_GBPB%=FNswi_number("XOS_GBPB")
XOS_FSControl%=FNswi_number("XOS_FSControl")
XOS_CLI%=FNswi_number("XOS_CLI")
XOS_File%=FNswi_number("XOS_File")

file%=0
DIM status$(7):status$()=" (audio playing)"," (audio paused)"," (reserved)"," (audio stopped)"," (audio error)"," (audio stopped)"," (empty)"," (error)"
DIM block% 1023

SYS "XOS_GetEnv" TO comm%;F%
REM IF (f% AND 1) PROCerror("Unable to read commandline options")
comm$=FNstring(comm%)
REM PRINT "A";comm$;"b"

SYS "XOS_ReadArgs","name,quit,default/K,fs/K",comm%,block%,1023 TO ;F%

default%=block%!8
IF default%=0 default%=16 ELSE default%=EVAL(FNstring(block%!8))

*Menu FindDrives
PROCsdfs("")
PROCadfs("")
PROCscsi("")
PROCidefs("")
PROCmassfs("")
PROChostfs("")
PROCram("")
PROCcdfs("")
PROClanman98("")
PROCsharefs("")
PROCsunfish("")
PROCrafs("")
PROClayerfs("")
PROCresources("")
PROCpipe("")
*EndMenu

*Set Director$Menu FindDrives
SYS "XHourglass_Off"
END

DEF PROCadfs(opt$)
XADFS_Drives%=FNxswi_number("XADFS_Drives")
IF XADFS_Drives%=-1 ENDPROC
SYS XADFS_Drives% TO , flops%, hards% ;F%
IF (F% AND 1)=0 PROCfilecoredrives("ADFS",flops%,hards%,opt$,"")
ENDPROC

DEF PROCsdfs(opt$)
XSDFS_Drives%=FNxswi_number("XSDFS_Drives")
IF XSDFS_Drives%=-1 ENDPROC
SYS XSDFS_Drives% TO , flops%, hards% ;F%
IF (F% AND 1)=0 PROCfilecoredrives("SDFS",flops%,hards%,opt$,"")
ENDPROC

DEF PROCscsi(opt$)
XSCSI_Drives$=FNswi_name(&40982)
IF XSCSI_Drives$="User" ENDPROC
SYS &40982 TO ,flops%,hards%;flags%
IF hards%=0 AND flops%=0 ENDPROC
REM Is it SCSI::x.$ or SCSIFS::x.$ ?
IF hards% <> 0 THEN
  SYS XOS_FSControl%,37,"SCSI::4.$",block%,,,1024 TO ;F%
ELSE
  IF flops% <> 0 THEN
    SYS XOS_FSControl%,37,"SCSI::0.$",block%,,,1024 TO ;F%
  ENDIF
ENDIF
IF (F% AND 1)=1 THEN
    PROCfilecoredrives("SCSI", flops%, hards%, opt$, "SCSI")
ELSE
    PROCfilecoredrives("SCSIFS", flops%, hards%, opt$, "SCSIFS")
ENDIF
ENDPROC

DEF PROCram(opt$)
XRamFS_Drives%=FNxswi_number("XRamFS_Drives")
IF XRamFS_Drives%=-1 ENDPROC
SYS XRamFS_Drives% TO , flops%, hards% ;F%
IF (F% AND 1)=0 PROCfilecoredrives("RAM", flops%, hards%, opt$,"")
ENDPROC

DEF PROCidefs(opt$)
XIDEFS_Drives%=FNxswi_number("XIDEFS_Drives")
IF XIDEFS_Drives%=-1 ENDPROC
SYS XIDEFS_Drives% TO ,flops%, hards% ;F%
IF (F% AND 1)=0 PROCfilecoredrives("IDEFS",flops%,hards%,opt$,"")
ENDPROC

DEF PROCfilecoredrives(fileSystem$,flops%,hards%,opt$,suf$)
IF flops% > 0 THEN
  FOR i%=1 TO flops%
    PROCfilecoredrive(fileSystem$,i%,opt$,suf$)
  NEXT
ENDIF
IF hards% > 0 THEN
  FOR i%=1 TO hards%
    PROCfilecoredrive(fileSystem$,i%+4,opt$,suf$)
  NEXT
ENDIF
ENDPROC

REM PROCfilecoredrive
REM Purpose:            Find out details about filecore drives before calling
REM                       PROCmakeOption
REM Input: fileSystem$: File system to examine
REM        drvnum%:     Drive number to examine
REM        opt$:        Option settings
REM        suf$:        Any special suffix for PROCmakeOption
DEF PROCfilecoredrive(fileSystem$,drvnum%,opt$,suf$)
LOCAL path$,drvstat$,opt%,o$
o$=MID$(opt$,drvnum%,1):IF o$="" OR o$="*" THEN opt%=default% ELSE opt%=EVAL("&"+o$)
drvnum%-=1
path$ = fileSystem$+"::"+STR$(drvnum%)
drvnam$=FNfilecorereadMediaName(path$,drvstat%)
PROCmakeOption("small_dir",fileSystem$,drvnum%,drvnam$,drvstat%,opt%,suf$,"")
ENDPROC

REM FNfilecorereadMediaName
REM Purpose:      To read the name of the media
REM Input: path$: The full path name of the drive to examine
REM Output: str$: The name of the drive
DEF FNfilecorereadMediaName(path$, RETURN drvstat%)
LOCAL spare%,tmp%,tmp2%
SYS XOS_FSControl%, 37, path$, block%, 0, 0, 1023 TO ,,,,,spare%;flags%
IF spare%<0 ERROR 0, "Drive name too long for buffer"
IF (flags% AND 1)=1 THEN
  path$="":drvstat%=6
ELSE
  drvstat%=0
  IF (opt% AND 2)=0 THEN
    path$ = FNstring(block%)
    tmp%=INSTR(path$,"::"):tmp2%=INSTR(path$,".")
    path$=MID$(path$,tmp%+2,tmp2%-tmp%-2)
  ELSE
    path$=""
  ENDIF
ENDIF
=path$

DEF PROChostfs(opt$)
  IF FNrmensure("RPCEmuHostFS") ENDPROC
  o$=LEFT$(opt$,1):IF o$="" OR o$="*" THEN opt%=default% ELSE opt%=EVAL("&"+o$)
opt%=opt% OR 8
  PROCmakeOption("small_dir","HostFS",-1,"",0,opt%,"","-sub ""Path:HostFS:$""")
ENDPROC

DEF PROCpipe(opt$)
o$=LEFT$(opt$,1):IF o$="" OR o$="*" THEN opt%=default% ELSE opt%=EVAL("&"+o$)
opt%=opt% OR 8
PROCmakeOption("small_dir","Pipe",-1,"",0,opt%,"","-sub ""Path:Pipe:$""")
ENDPROC

DEF PROCresources(opt$)
LOCAL o$,opt%
IF FNlcase(MID$(opt$,2,1))="d" THEN opt%=4 ELSE opt%=0
o$=FNlcase(LEFT$(opt$,1))
CASE o$ OF
  WHEN "$":
    PROCmakeOption("small_dir","Resources",-1,"",0,opt%,"","-path Resources:$")
  WHEN "a":
    PROCmakeOption("small_dir","Resources",-1,"",0,opt%,"","-path Resources:$.Apps")
  WHEN "d":
    PROCmakeOption("small_dir","Resources",-1,"",0,opt%,"","-path Resources:$.Discs")
  WHEN "f":
    PROCmakeOption("small_dir","Resources",-1,"",0,opt%,"","-path Resources:$.Fonts")
  WHEN "r":
    PROCmakeOption("small_dir","Resources",-1,"",0,opt%,"","-path Resources:$.Resources")
  WHEN "t":
    PROCmakeOption("small_dir","Resources",-1,"",0,opt%,"","-path Resources:$.ThirdParty")
  OTHERWISE
    PROCmakeOption("small_dir","Resources",-1,"",0,opt%,"","")
ENDCASE
ENDPROC

DEF PROClanman98(opt$)
IF FNrmensure("LanMan98") ENDPROC
LOCAL name$,o$,opt%
o$=LEFT$(opt$,1):IF o$="" OR o$="*" THEN opt%=default% ELSE opt%=EVAL("&"+o$)
SYS XOS_GBPB%,10,"LM98:Discs",block%,1,0,1024 TO ,,,r3%,r4%
WHILE r4%<>-1
  IF r3%<>0 THEN
    name$=FNstring(block%+20)
    SYS XOS_File%,23,"LanMan98::"+name$+".$" TO ;flags%
    IF (flags% AND 1)=0 THEN
      PROCmakeOption("sm!lanman98","LanMan98",-1,name$,0,opt%,"","")
    ENDIF
  ENDIF
  SYS XOS_GBPB%,10,"LM98:Discs",block%,1,r4%,1024 TO ,,,r3%,r4%
ENDWHILE
ENDPROC

DEF PROCmassfs(opt$)
IF FNrmensure("MassFS") ENDPROC
LOCAL drvnam$,o$,opt%,drives%,f%
o$=LEFT$(opt$,1):IF o$="" OR o$="*" THEN opt%=default% ELSE opt%=EVAL("&"+o$)
SYS "XMassFS_GetDriveCount" TO drives% ;F%
IF (F% AND 1)=1 THEN ENDPROC
IF drives%>0 THEN
  FOR i%=0 TO drives%-1
    SYS "XMassFS_GetDriveInfo",i% TO ,drvnam$
    PROCmakeOption("sm!usb","MassFS",-1,drvnam$,0,opt%,"","")
  NEXT i%
ENDIF
ENDPROC


DEF PROCrafs(opt$)
IF FNrmensure("raFS") ENDPROC
LOCAL line$,file$,leaf$,drvnam$,pos%,o$,opt%
o$=LEFT$(opt$,1):IF o$="" OR o$="*" THEN opt%=default% ELSE opt%=EVAL("&"+o$)
SYS XOS_CLI%,"raFS_Discs { > <Wimp$ScrapDir>.Director.raFS }"

file%=OPENIN("<Wimp$ScrapDir>.Director.raFS")
WHILE NOT EOF#file%
  line$=FNreadfile
  WHILE line$<>""
    pos%=INSTR(line$," "):drvnam$=LEFT$(line$,pos%-1)
    file$=MID$(line$,pos%+1):leaf$=FNfile_leaf(file$)
    PROCmakeOption("sm!raFS","raFS",-1,drvnam$,0,opt%,"","")
    line$=GET$#file%
  ENDWHILE
ENDWHILE
CLOSE #file%:file%=0
ENDPROC

DEF FNreadfile:LOCAL text$:text$=""
WHILE text$="" AND NOT EOF#file%
  chr%=BGET#file%
  WHILE chr%>=32 AND NOT EOF#file%
    IF CHR$(chr%)="<" text$+="|"
    text$+=CHR$(chr%)
    chr%=BGET#file%
  ENDWHILE
ENDWHILE
=text$

DEF PROClayerfs(opt$)
IF FNrmensure("LayerFS") ENDPROC
LOCAL line$,file$,drvnam$,o$,opt%
o$=LEFT$(opt$,1):IF o$="" OR o$="*" THEN opt%=default% ELSE opt%=EVAL("&"+o$)

SYS XOS_CLI%,"LayerFS_stats { > <Wimp$ScrapDir>.Director.LayerFS }"
file%=OPENIN("<Wimp$ScrapDir>.Director.LayerFS")
IF EXT#file%=0 CLOSE#file%:file%=0:ENDPROC

line$=GET$#file%
IF line$="No images opened" CLOSE#file%:file%=0:ENDPROC

WHILE line$<>""
  file$=MID$(line$,5):drvnam$=FNfile_leaf(file$)
  PROCmakeOption("small_ad5","LayerFS",-1,drvnam$,0,opt%,file$,"")
  line$=GET$#file%:line$=GET$#file%
ENDWHILE
CLOSE#file%:file%=0:ENDPROC

DEF PROCcdfs(opt$)
IF FNrmensure("CDFS") ENDPROC
XCDFS_GetNumberOfDrives%=FNxswi_number("XCDFS_GetNumberOfDrives")
IF XCDFS_GetNumberOfDrives%=-1 ENDPROC

DIM cdBlock% 20,cdFive% 5
LOCAL abc%,dataOnly%,start%,end%,drive%,nDrives%,pdn%,o$,opt%
XCDFS_ConvertDriveToDevice%=FNswi_number("XCDFS_ConvertDriveToDevice")
XCD_EnquireTrack%=FNswi_number("XCD_EnquireTrack")
XCD_AudioStatus%=FNswi_number("XCD_AudioStatus")

SYS XCDFS_GetNumberOfDrives% TO nDrives%
drive%=0
WHILE drive%<nDrives%
o$=MID$(opt$,drive%,1):IF o$="" OR o$="*" THEN opt%=default% ELSE opt%=EVAL("&"+o$)
  drvnam$="":submnu$="":status%=0
  SYS XCDFS_ConvertDriveToDevice%,drive% TO ,pdn%;flags%
  cdBlock%!0  =  (pdn% AND &0007)
  cdBlock%!4  = ((pdn% >> 3)  AND &0003)
  cdBlock%!8  = ((pdn% >> 5)  AND &0007)
  cdBlock%!12 = ((pdn% >> 8)  AND &00FF)
  cdBlock%!16 = ((pdn% >> 16) AND &FFFF)

  SYS XCD_EnquireTrack%,0,cdFive%,,,,,,cdBlock% TO error;flags%
  IF flags% AND 1 THEN
    status%=6
  ELSE
    start%=cdFive%?0
    end%=cdFive%?1
    dataOnly%=TRUE
    FOR track%=start% TO end%
      SYS XCD_EnquireTrack%,track%,cdFive%,,,,,,cdBlock%
      abc%=cdFive%?4
      IF (abc% AND 1)=0 THEN dataOnly%=FALSE
      track%=end%
    NEXT
    IF dataOnly% THEN
      drvnam$=FNfilecorereadMediaName("CDFS::"+STR$(drive%),drvstat%)
    ELSE
      SYS XCD_AudioStatus%,,,,,,,,cdBlock% TO status%;flags%
      IF flags% AND 1 THEN
        status%=6
      ELSE
        submnu$="-sub ""Dynamic:/Director:Menus.Files.CDFS -drive "+STR$(drive%)+""""
      ENDIF
    ENDIF
  ENDIF
  PROCmakeOption("smcd","CDFS",drive%,drvnam$,status%,opt%,"",submnu$)
  drive%+=1
ENDWHILE
ENDPROC

DEF PROCsharefs(opt$)
REM Need to find a way to enumerate /mounted/ Shares

REM  XShareFS_EnumerateShares%=FNxswi_number("XShareFS_EnumerateShares")
REM  IF XShareFS_EnumerateShares%=0 THEN ENDPROC
REM  lookingfor%=0: REM Let's try just enumerating standard shares
REM  unique%=0: REM For the very first lookup
REM  SYS XShareFS_EnumerateShares%,lookingfor% TO ,name%,path%,flags%,unique%;f%
REM  IF (flags% AND 1)=0 THEN
REM    name$=FNstring(name%)
REM    PROCmakeOption("small_f9f","ShareFS",-1,name$,0,0,"","")
REM  ENDIF
ENDPROC

DEF PROCsunfish(opt$)
  XSunfish_ListMounts%=FNxswi_number("XSunfish_ListMounts")
  IF XSunfish_ListMounts%=-1 THEN ENDPROC
  pos%=0
  REM XSunfish_ListMounts will return r0==0 if there are no more mounts
  REM However we first need to see if there is just 1 mount
  REPEAT
    SYS XSunfish_ListMounts%,pos% TO pos%,name%,field%;f%
    IF name%<>0 THEN
      name$=FNstring(name%)
      PROCmakeOption("small_1b6","Sunfish",-1,name$,0,0,"","")
    ENDIF
  UNTIL pos%=0
ENDPROC


REM PROCmakeOption
REM Purpose:         Create an Option for the specified drive.
REM Input: sprite$:  Sprite to use for menu option (*)
REM        fsnam$:   File system name to use (*)
REM        drvnum%:  Drive number (*). -1 if unavailable
REM        drvnam$:  Drive name (*). Null if unknown/unavailable
REM        drvstat%: Status of the drive. Used as an index to status$().
REM        opt%:     Option setting. See Documentation for details
REM        suf$:     A special suffix to be passed to the external FindDrives
REM                    menu files. Used for SCSI. Null if not required.
REM        submnu$:  A different submenu is to be used rather than the default.
REM                    Used for Resources and CDFS. Null if not required.
REM                  (*) whether this is used in the option command is down
REM                      to what the options settings are.
DEF PROCmakeOption(sprite$,fsnam$,drvnum%,drvnam$,drvstat%,opt%,suf$,submnu$)
LOCAL name$
REM IF (opt% AND 2)<>0 drvnam$=STR$(drvnum%)
IF submnu$="" THEN
  IF (opt% AND 8)=0 THEN
    IF drvnam$<>"" THEN
      submnu$="-sub ""Dynamic:/Director:Menus.System.FindDrives."+fsnam$+" "+drvnam$+" "+suf$+""""
    ELSE
      submnu$="-sub ""Dynamic:/Director:Menus.System.FindDrives."+fsnam$+" "+STR$(drvnum%)+" "+suf$+""""
    ENDIF
  ELSE
    IF drvnam$<>"" THEN
      submnu$="-path "+fsnam$+"::"+drvnam$
    ELSE
      IF drvnum%<>-1 THEN
        submnu$="-path "+fsnam$+"::"+STR$(drvnum%)
      ELSE
        submnu$="-path "+fsnam$+":$"
      ENDIF
    ENDIF
  ENDIF
ENDIF
IF drvnam$<>"" THEN
  IF (opt% AND 1)<>0 fsnam$="" ELSE fsnam$+="::"
  name$=fsnam$+drvnam$
ELSE
  IF drvnum%<>-1 THEN
    IF (opt% AND 1)<>0 fsnam$="" ELSE fsnam$+="::"
    name$=fsnam$+STR$(drvnum%)
  ELSE
    name$=fsnam$
  ENDIF
ENDIF
IF (opt% AND 4)=0 THEN
  spr$=" -sprite "+sprite$
ELSE
  spr$=""
ENDIF
IF drvstat%>5 THEN
  REM Empty drive/error occured - don't display it
  REM SYS Option%,""""+name$+status$(drvstat%)+""""+spr$+" -grey"
ELSE
  SYS Option%,name$+spr$+" "+submnu$
ENDIF
ENDPROC

DEF FNswi_number(name$)
  SYS &39,,name$ TO A%
=A%

DEF FNxswi_number(name$)
  SYS &20039,,name$ TO A%;F%
  IF (F% AND 1)=1 A%=-1
=A%

DEF FNswi_name(num%)
  LOCAL r2%
  SYS &20038,num%,block%,1023 TO ,,r2%
  ?(block%+r2%-1)=13
=$block%

DEF FNread(var$):LOCAL size%
SYS XOS_ReadVarVal%,var$,block%,1023 TO ,,size%
=FNstring_s(block%,size%)

DEF PROCset(var$,value$)
SYS XOS_SetVarVal%,var$,value$,LEN(value$)
ENDPROC

DEF FNstring(ptr%):LOCAL a$:a$=""
WHILE ?ptr%>31
  a$+=CHR$(?ptr%):ptr%+=1
  ENDWHILE:=a$

DEF FNstring_s(ptr%,size%)
?(ptr%+size%)=13
=$ptr%

DEF FNlcase(text$)
LOCAL Loop%,text2$
FOR Loop%=1 TO LEN(text$)
  chr%=ASC(MID$(text$,Loop%,1))
  IF chr%>64 AND chr%<91 chr%=chr%+32
  text2$+=CHR$(chr%)
NEXT
=text2$

REM Returns TRUE if the supplied module title doesn't exist
DEF FNrmensure(m$)
LOCAL c%
SYS "XOS_Module",18,m$ TO ,,,c%
=(c%=0)

DEF FNfile_leaf(file$)
LOCAL pos%,temp%
temp%=0
REPEAT
pos%=temp%+1
temp%=INSTR(file$,".",pos%)
UNTIL temp%=0
=MID$(file$,pos%)

DEF PROCerror
ON ERROR OFF
SYS "XHourglass_Smash"
VDU 4
PRINT "Error in: !Director.Menus.System.FindDrives.FindDrives"
PRINT "Report:   ";REPORT$
PRINT "Line:     ";ERL
IF file%<>0 CLOSE#file%
END
