; Copyright 1996 Acorn Computers Ltd
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
;     http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; s.Save
; Save and Desktop save handling.
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


Save_KeyPressed ROUT
        Push    "LR"

        LDR     r0,[r1,#24]
        CMP     r0,#13
        BEQ     %FT00
        SWI     XWimp_ProcessKey
        Pull    "PC"
00
        MOV     r0, #4                  ; fake a select click

IntSave_KeyPressed

; Scan for a '.' in the filename

        Push    "r0"
        LDR     r0,save_filename_address
01
        LDRB    r14,[r0],#1
        CMP     r14,#"."
        BEQ     %FT02
        CMP     r14,#32
        BGE     %BT01

        ADD     sp,sp,#4
        ADR     r0,ErrorBlock_PinboardNoDot
        BL      msgtrans_errorlookup
        Pull    "PC"

02
        Debug   sa,"Dot is at ",r14
        LDR     r1,save_filename_address

        BL      DoSave
        ADDVS   sp,sp,#4
        Pull    "PC",VS

        Pull    "r0"
        TEQ     r0, #1                  ; was it an adjust click?
        MOVNE   r1,#-1
        SWINE   XWimp_CreateMenu
        Pull    "PC"


ErrorBlock_PinboardNoDot
        DCD     0
        DCB     "NoDot",0
        ALIGN



save_click      ROUT

        Debug   sa,"Save click ",r2
        CMP     r0,#&40
        BEQ     save_drag

        CMP     r2,#0                   ; icon of the OK button
        ANDEQS  r14,r0,#2               ; ignore menu button
        BEQ     IntSave_KeyPressed
        Pull    "PC"

save_drag       ROUT

        Debug   sa,"Save drag"

        ADR     r1,dataarea
        LDR     r2,saveas_handle
        STR     r2,[r1]
        MOV     r0,#3
        STR     r0,[r1,#4]
        SWI     XWimp_GetIconState
        Pull    "PC",VS

        ADD     R14,R1,#8
        LDMIA   R14,{R6-R9}             ; x0 - y1 of icon

        ADRL    R1,(dataarea+40)
        STR     R2,[R1]                 ; R2 = window handle (store it baby!)

        SWI     XWimp_GetWindowState
        Pull    "PC",VS

        ADD     r14,r1,#4
        LDMIA   r14,{r0-r3}
        ADD     r6,r6,r0              ; Scrren coords.
        ADD     r8,r8,r0
        ADD     r7,r7,r3
        ADD     r9,r9,r3

        Push    "R0-R2"
        MOV     R0,#ReadCMOS
        MOV     R1,#FileSwitchCMOS
        SWI     XOS_Byte                ; R2 = CMOS byte allocated to FileSwitch
        MOVVS   R2,#0
        TST     R2,#1:SHL:1             ; Is 'drag a sprite' enabled?
        Pull    "R0-R2"
        BEQ     %FT10                   ; obviously not!

        Push    "R6-R9"                 ; R6-R9 contain icon position
        MOV     R3,SP                   ; R3 -> pushed coordinates
        ADRL    R2,(dataarea+28)        ; R2 -> sprite name to use (from icon data)
        MOV     R1,#1                   ; R1 =1 => sprite in Wimp sprite pool

        MOV     R0,#DS_HJustify_Centre :OR: DS_VJustify_Centre :OR: DS_BoundTo_Screen :OR: DS_Bound_Pointer :OR: DS_DropShadow_Present
        SWI     XDragASprite_Start
        ADD     SP,SP,#4*4              ; balance out the stack
        B       %FT20                   ; then exit 'cos finished the drag start

10      LDR     r0,saveas_handle
        ADR     r1,dataarea
        MOV     r2,#5
        STMIA   r1,{r0,r2,r6-r9}

        SUB     r3,r8,r6
        SUB     r4,r9,r7
        ADR     r0, bounding_box
        LDMIA   r0, {r6-r9}
        SUB     r6, r6, r3 ,LSR #1
        SUB     r7, r7, r4 ,LSR #1
        ADD     r8, r8, r3, LSR #1  ; half x size.
        ADD     r9, r9, r4, LSR #1  ; half y size.
        ADR     r1,dataarea
        ADD     r14,r1,#6*4
        STMIA   r14,{r6-r9}

        Debug   sa,"Calling wimp_dragbox ",r1

        SWI     XWimp_DragBox

        Pull    "PC",VS

        Debug   sa,"Wimp_DragBox returned"
20
        MOV     r0,#DragType_Save
        STR     r0,DragType

        BL      Claim_Focus

        Debug   sa,"Save drag exits"

      [ debugsa
        Pull    "LR"
        Debug   sa,"LR is ",r14
        MOV     PC,LR
      ]

        Pull    "PC"

Save_DragEnd    ROUT

        SWI     XDragASprite_Stop

        ADR     r1,dataarea
        SWI     XWimp_GetPointerInfo
        Pull    "PC",VS

        LDMIA   r1,{r4,r5}
        ADD     r14,r1,#12
        LDMIA   r14,{r2,r3}

        MOV     r0,#Message_DataSave
        STR     r0,[r1,#ms_action]
        MOV     r0,#252
        STR     r0,[r1,#ms_size]
        MOV     r6,#0
        STR     r6,[r1,#ms_yourref]
        LDR     r7,=FileType_Obey
        ADD     r14,r1,#ms_data
        STMIA   r14!,{r2,r3,r4,r5,r6,r7}       ; Window, icon , x , y

        LDR     r0,save_filename_address
        MOV     r4,r0
01
        LDRB    r5,[r0],#1
        CMP     r5,#"."
        MOVEQ   r4,r0
        CMP     r5,#32
        BGE     %BT01

; r4 -> Leafname

        MOV     r0,r4
        MOV     r1,r14
        BL      Copy_r0r1


        ADR     r1,dataarea
        ADD     r14,r1,#44
        DebugS  sa,"Leafname is ",r14
        MOV     r0,#18                       ; r2,r3 are icon / window handles
        Debug   sa,"Icon,Window ",r2,r3
        SWI     XWimp_SendMessage

        Pull    "PC"

Save_DataSaveAck        ROUT

        DebugS  sa,"Filename is ",r14

        ;MOV     r0,#&8F
        ADD     r1,r1,#44
        ;DebugS  sa,"Filename is ",r1
        ;SWI     XOS_Find
        ;Pull    "PC",VS

        ;Push    "r0"                            ; SMC: save file handle for CloseFile
        BL      DoSave
        ;BL      CloseFile
        ;ADD     sp, sp, #4                      ; SMC: don't need file handle now
        ;Pull    "PC",VS                         ; SMC: return error from DoSave or CloseFile

        ADR     r1,dataarea
        LDR     r0,[r1,#8]
        STR     r0,[r1,#12]
        MOV     r0,#Message_DataLoad
        STR     r0,[r1,#ms_action]
        MOV     r0,#18
        LDR     r2,[r1,#4]
        SWI     XWimp_SendMessage
        Pull    "PC",VS

        ADR     r1,dataarea
        ADD     r2,r1,#44                       ; SMC: point to file name
        LDR     r3,[r1,#36]
        CMP     r3,#-1                          ; Check for unsafe file eg. <Wimp$Scrap>
        MOVNE   r0,r2                           ; SMC: only copy if not unsafe
        LDRNE   r1,save_filename_address
        BLNE    Copy_r0r1

        MOVVC   r1,#-1
        SWIVC   XWimp_CreateMenu

        Pull    "PC"

DesktopSave
        ;LDR     r0, [r1, #msSaveDesktop_handle]
        ;BL      DoSave
        Pull    "PC"


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; DoSave
;
; Save a Pinboard Obey file
;
; In: r1 -> filename
; Out: r0 corrupt

DoSave  ROUT
        Entry   "r1-r9"

        MOV     r8, r1                          ; r8 -> filename

        ; Open file to write
        MOV     r0, #open_write :OR: open_pathbits :OR: open_mustopen :OR: open_nodir
        MOV     r1, r8
        SWI     XOS_Find
        EXIT    VS
        MOV     r9, r0                          ; r9 = file handle

        ; Write a 'Pinboard' command
        MOV     r0, r9
        ADR     r1, PinboardCommand
        BL      PutString
        ADR     r1, NL
        BL      PutString

        ; Write *Pin commands for each icon
        BL      write_pin_commands

        ; Close the file, set it's type and exit
        MOV     r0, #0
        MOV     r1, r9
        SWI     XOS_Find

        MOV     r0, #OSFile_SetType
        MOV     r1, r8
        LDR     r2,=FileType_Obey
        SWI     XOS_File
        EXIT


PinboardCommand DCB "Pinboard",0
TinyDirsCommand DCB "X AddTinyDir ", 0          ; ignore errors so that entering the desktop
PinCommand      DCB "X Pin ", 0                 ; doesn't result in scores of error boxes
Space           DCB " ", 0
NL              DCB 10, 0


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; write_pin_commands
;
; Output Pin commands to a file for each icon on the backdrop
;
; In: r0 = filehandle of output
;
; Out: all regs preserved

write_pin_commands Entry "r1-r3"
        ; Loop through all the icons and write Pin commands for each one.
        ADR     r2,Icon_list
02
        LDR     r2,[r2]
        CMP     r2,#0
        EXIT    EQ
        LDR     r3,[r2,#ic_window]
        CMP     r3,#-2
        ADREQ   r1,TinyDirsCommand
        ADRNE   r1,PinCommand
        BL      PutString
        EXIT    VS

        ADD     r1,r2,#ic_path
        BL      PutString
        EXIT    VS

        ADREQ   r1,NL
        BLEQ    PutString
        EXIT    VS
        BEQ     %BT02
        ADR     r1,Space
        BL      PutString
        EXIT    VS

        Push    "r0-r2"
        ADR     r1,ConversionSpace
        LDR     r0,[r2,#ic_x]
        CMP     r0,#0
        MOVLT   r2,#"0"
        STRLTB  r2,[r1],#1
        MOV     r2,#256
        SWI     XOS_ConvertInteger4
        STRVS   r0,[sp]
        Pull    "r0-r2"
        EXIT    VS
        ADR     r1,ConversionSpace
        BL      PutString
        EXIT    VS
        ADRL    r1,Space
        BL      PutString
        EXIT    VS

        Push    "r0-r2"
        ADR     r1,ConversionSpace
        LDR     r0,[r2,#ic_y]
        MOV     r2,#256
        SWI     XOS_ConvertInteger4
        STRVS   r0,[sp]
        Pull    "r0-r2"
        EXIT    VS
        ADR     r1,ConversionSpace
        BL      PutString
        EXIT    VS
        ADRL    r1,NL
        BL      PutString
        EXIT    VS

        B       %BT02


; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; PutString
;
; Write a NULL terminated string to a file
;
; In: r0 = file handle
;     r1 -> string to write
;
; Out: All registers preserved

PutString       ROUT
        EntryS  "r0-r2"

        MOV     r2,r1
        MOV     r1,r0
01
        LDRB    r0,[r2],#1
        CMP     r0,#0
        EXITS   EQ
        SWI     XOS_BPut
        STRVS   r0,[sp]
        EXIT    VS
        B       %BT01

        LNK     Backdrop.s