REM Title:      FrontBack
REM Purpose:    Alter a window's position in the window stack
REM Version:    1.00, Wednesday the 27th of February, 2002
REM Copyright:  Bernhard Ege
REM Updated by: Philip Ludlam

REM Syntax:     FrontBack [-top] [-bottom] [-up] [-down]
REM             The system variable Director$Window must hold a valid
REM             window handle. It is that window which will change position
REM             in the stack.

REM By default this program moves the window pointed to by
REM Director$Window to the top of the window stack, if its partly
REM covered by another window. If its uncovered, then its moved
REM to the back.
REM If -top -bottom -up or -down is supplied as an arguement to the program,
REM then the window is moved to the top, bottom, moved up or down respectively.

REM Its main use was meant for DirectorFilter:
REM DirectorFilter "Front Back" * "Dynamic:/Director:Menus.System.FrontBack" -select -alt
REM , which intercepts all alt+select clicks and calls FrontBack
REM
REM  Bernhard Ege
REM   bmeg93@kom.auc.dk
REM   http://www-i8.auc.dk/~bmeg93/

ON ERROR REPORT:PRINT ERL:END

buffer_size%=512
DIM buffer% buffer_size%
DIM buf% 36

SYS "OS_GetEnv" TO comm$

top%=(INSTR(comm$,"-top")<>0)
bottom%=(INSTR(comm$,"-bottom")<>0)
up%=(INSTR(comm$,"-up")<>0)
down%=(INSTR(comm$,"-down")<>0)
window%=EVAL(FNread("Director$Window"))


SYS"Wimp_Initialise",310,&4b534154,"FrontBack" TO taskhandle%
buf%!0=window%
SYS "XWimp_GetWindowState",,buf% TO ;flags%
IF (flags% AND NOT 1) AND window%>=0 THEN

PROCdo

REM Change the settings of 'our' window.
buf%!0=window%
SYS "XWimp_GetWindowState",,buf% TO ;flags%
IF (flags% AND 1) END
buf%!28=win_behind%

REM Send open window request to source task
SYS "Wimp_SendMessage",2,buf%,window%

ENDIF
SYS"Wimp_CloseDown",taskhandle%,&4b534154
END

:

DEF PROCdo
REM Move to top
IF top% THEN win_behind%=-1:ENDPROC

REM Move to bottom
IF bottom% THEN win_behind%=-2:ENDPROC

REM Move up
IF up% THEN
  IF buf%!28=-1 END
    REM Move up the chain
  buf%!0=buf%!28
  SYS "XWimp_GetWindowState",,buf% TO ;flags%
  IF (flags% AND 1) END
    REM If this window is a pane, find the next one up which isn't
  WHILE buf%!28<>-1 AND (buf%!32 AND 1<<5)<>0
    buf%!0=buf%!28
    SYS "XWimp_GetWindowState",,buf% TO ;flags%
    IF (flags% AND 1) END
  ENDWHILE
  win_behind%=buf%!28
  IF buf%!28=-1 ENDPROC
    REM Window handle buf%!0 isn't a pane.
    REM We want to be above this window (and any of it's panes)
  buf%!0=buf%!28
  SYS "XWimp_GetWindowState",,buf% TO ;flags%
  IF (flags% AND 1) END
    REM If this window is a pane, find the next one up which isn't
  WHILE buf%!28<>-1 AND (buf%!32 AND 1<<5)<>0
    buf%!0=buf%!28
    SYS "XWimp_GetWindowState",,buf% TO ;flags%
    IF (flags% AND 1) END
  ENDWHILE
  IF buf%!28=-1 AND (buf%!32 AND 1<<5)<>0 win_behind%=-1:ENDPROC
  win_behind%=buf%!0
  ENDPROC
ENDIF

REM Move down
IF down% THEN
  win_behind%=-2
  win%=FNcreate_back_window
  REM Get first Window in front of Iconbar/Director: Keys
  buf%!0=win%
  SYS "XWimp_GetWindowState",,buf% TO ;flags%
  IF (flags% AND 1) END
  win%=buf%!28
  WHILE win%<>-1 AND win%<>window%
    SYS "XWimp_GetWindowState",,buf% TO ;flags%
    IF (flags% AND 1) END
    win%=buf%!28
    IF (buf%!32 AND 1<<1) AND ( (buf%!32 AND 1<<5) =0) THEN
      win_behind%=buf%!0
    ENDIF
    buf%!0=win%
    ENDWHILE
  ENDPROC
ENDIF

REM Otherwise
IF (buf%!32 AND 2^17)=&20000 THEN
  REM at top, move to back
  win_behind%=-2
ELSE
  REM covered, move to top
  win_behind%=-1
ENDIF

ENDPROC

:

DEF FNread(a$)
  ?buffer%=13
  SYS "XOS_ReadVarVal",a$,buffer%,buffer_size%,0,3 TO ,,read%
  buffer%?read%=13
=$buffer%

:

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

DEF FNcreate_back_window
  LOCAL handle%
  DIM block% 256

  RESTORE +0
  DATA &00000190, &000002E0, &0000022C, &000002E4
  DATA &00000000, &00000000, &FFFFFFFE, &84001852
  DATA &01070207, &000C0103, &00000000, &FFFFFC00
  DATA &00000500, &00000000, &2700003D, &00003000
  DATA &00000001, &00000001, &6B636142, &0000000D
  DATA &00000000, &00000000

  FOR i%=block%+4 TO block%+4+22*4-1 STEP 4
    READ !i%
  NEXT i%
  SYS "Wimp_CreateWindow",,block%+4 TO handle%
  !block%=handle%
  SYS "Wimp_OpenWindow",,block%
=handle%
