iglobal
  include 'actions.inc'   ; menus, action, etc

  cAddFileTitle du 'Add file to the project', 0
  cSetMainTitle du 'Select main file', 0
endg


ActionEvents:

;----------------------------------------------------------------
; This is OnIdle handler of the application.
; When message queue is empty, this subroutine is called once.
; The idea is to provide updating of the status of the controls
; without performance decreasing.
;----------------------------------------------------------------

proc OnIdle

.changed dd ?
.buffer  rb 256

begin
        push    esi edi ebx

        mov     [.changed], 0

        invoke  SendMessageW, [hMainToolbar], TB_ISBUTTONENABLED, actCut, 0
        test    eax,eax
        setnz   bh

        stdcall CanAction, [ptrCurrentFile], WM_CUT
        test    eax, eax
        setnz   bl

        cmp     bh, bl
        je      .cut_action_ok

        movzx   eax, bl
        movzx   ebx, bh         ; MF_BYCOMMAND + ( MF_GRAYED | MF_ENABLED )
        inc     [.changed]

        invoke  SendMessageW, [hMainToolbar], TB_ENABLEBUTTON, actCut, eax
        invoke  EnableMenuItem, [hMainMenu], actCut, ebx
        invoke  EnableMenuItem, [hEditorMenu], actCut, ebx

.cut_action_ok:

        invoke  SendMessageW, [hMainToolbar], TB_ISBUTTONENABLED, actCopy, 0
        test    eax,eax
        setnz   bh

        stdcall CanAction, [ptrCurrentFile], WM_COPY
        test    eax, eax
        setnz   bl

        cmp     bh, bl
        je      .copy_action_ok

        movzx   eax, bl
        movzx   ebx, bh         ; MF_BYCOMMAND + ( MF_GRAYED | MF_ENABLED )
        inc     [.changed]

        invoke  SendMessageW, [hMainToolbar], TB_ENABLEBUTTON, actCopy, eax
        invoke  EnableMenuItem, [hMainMenu], actCopy, ebx
        invoke  EnableMenuItem, [hEditorMenu], actCopy, ebx

.copy_action_ok:


;----------------------------------------------------------------------
; Set actPaste state enable/disable. Only for text data in clipboard.
;----------------------------------------------------------------------
        invoke  SendMessageW, [hMainToolbar], TB_ISBUTTONENABLED, actPaste, 0
        test    eax,eax
        setnz   bh

        stdcall CanAction, [ptrCurrentFile], WM_PASTE
        test    eax, eax
        setnz   bl

        cmp     bh, bl
        je      .paste_action_ok

        movzx   eax, bl
        movzx   ebx, bh         ; MF_BYCOMMAND + ( MF_GRAYED | MF_ENABLED )
        inc     [.changed]

        invoke  SendMessageW, [hMainToolbar], TB_ENABLEBUTTON, actPaste, eax
        invoke  EnableMenuItem, [hMainMenu], actPaste, ebx
        invoke  EnableMenuItem, [hEditorMenu], actPaste, ebx

.paste_action_ok:


;----------------------------------------------------------------------
; Set history back button and menu item.
;----------------------------------------------------------------------
        invoke  SendMessageW, [hMainToolbar], TB_ISBUTTONENABLED, actHistoryBack, 0
        test    eax,eax
        setnz   bh

        xor     bl, bl

        cmp     [ptrBackHistory], 0
        je      .set_back

        mov     eax, [ptrBackHistory]
        cmp     [eax+TArray.count], 0
        je      .set_back

        inc     bl

.set_back:
        cmp     bl, bh
        je      .back_ok

        movzx   eax, bl
        movzx   ebx, bh         ; MF_BYCOMMAND + ( MF_GRAYED | MF_ENABLED )
        inc     [.changed]

        invoke  SendMessageW, [hMainToolbar], TB_ENABLEBUTTON, actHistoryBack, eax
        invoke  EnableMenuItem, [hMainMenu], actHistoryBack, ebx

.back_ok:

;----------------------------------------------------------------------
; Set history forward button and menu item.
;----------------------------------------------------------------------
        invoke  SendMessageW, [hMainToolbar], TB_ISBUTTONENABLED, actHistoryForward, 0
        test    eax,eax
        setnz   bh

        xor     bl, bl

        cmp     [ptrForwardHistory], 0
        je      .set_forw

        mov     eax, [ptrForwardHistory]
        cmp     [eax+TArray.count], 0
        je      .set_forw

        inc     bl

.set_forw:
        cmp     bl, bh
        je      .forward_ok

        movzx   eax, bl
        movzx   ebx, bh         ; MF_BYCOMMAND + ( MF_GRAYED | MF_ENABLED )
        inc     [.changed]

        invoke  SendMessageW, [hMainToolbar], TB_ENABLEBUTTON, actHistoryForward, eax
        invoke  EnableMenuItem, [hMainMenu], actHistoryForward, ebx

.forward_ok:

;----------------------------------------------------------------------
; Set actUndo state enable/disable.
;----------------------------------------------------------------------
        invoke  SendMessageW, [hMainToolbar], TB_ISBUTTONENABLED, actUndo, 0
        xor     esi, esi
        test    eax, eax
        setnz   bh

        stdcall CanAction, [ptrCurrentFile], WM_UNDO
        test    eax, eax
        setnz   bl

        cmp     bh, bl
        je      .undo_action_ok

        movzx   eax, bl
        movzx   ebx, bh
        inc     [.changed]

        invoke  SendMessageW, [hMainToolbar], TB_ENABLEBUTTON, actUndo, eax
        invoke  EnableMenuItem, [hMainMenu], actUndo, ebx
        invoke  EnableMenuItem, [hEditorMenu], actUndo, ebx

.undo_action_ok:

;----------------------------------------------------------------------
; Set actSave state enable/disable.
;----------------------------------------------------------------------
        invoke  SendMessageW, [hMainToolbar], TB_ISBUTTONENABLED, actSave, 0
        test    eax, eax
        setnz   bh

        stdcall GetModified, [ptrCurrentFile]
        test    eax,eax
        setnz   bl

        cmp     bh,bl
        jz      .save_action_ok

        movzx   eax, bl
        movzx   ebx, bh
        inc     [.changed]

        invoke  SendMessageW, [hMainToolbar], TB_ENABLEBUTTON, actSave, eax
        invoke  EnableMenuItem,[hMainMenu], actSave, ebx
        invoke  EnableMenuItem,[hTabMenu], actSave, ebx

.save_action_ok:

;----------------------------------------------------------------------
; Set actSaveAll state enable/disable.
;----------------------------------------------------------------------

        invoke  SendMessageW, [hMainToolbar], TB_ISBUTTONENABLED, actSaveAll, 0
        test    eax, eax
        setnz   bh

        stdcall EnumOpenFiles, _checkfirstforsave, NULL
        test    eax, eax
        setnz   bl

        cmp     bh, bl
        je      .saveall_action_ok

        movzx   eax, bl
        movzx   ebx, bh
        inc     [.changed]

        invoke  SendMessageW, [hMainToolbar], TB_ENABLEBUTTON, actSaveAll, eax
        invoke  EnableMenuItem, [hMainMenu], actSaveAll, ebx

.saveall_action_ok:

;----------------------------------------------------------------------
; Set actCompile state enable/disable.
;----------------------------------------------------------------------

        invoke  SendMessageW, [hMainToolbar], TB_ISBUTTONENABLED, actCompile, 0
        test    eax, eax
        setnz   bh

        invoke  SendMessageW, [hProjManager], PMM_GETMAINFILE, 0, 0
        test    eax, eax
        setnz   bl

        mov     eax, [ptrCurrentFile]
        test    eax, eax
        jz      .checkcomp

        cmp     [eax+TOpenFile.ptrType], ftCommonSource
        sete    al
        or      bl, al

.checkcomp:
        cmp     bh, bl
        je      .compile_action_ok

        movzx   edi, bl
        movzx   ebx, bh
        inc     [.changed]

        invoke  SendMessageW, [hMainToolbar], TB_ENABLEBUTTON, actCompile, edi
        invoke  SendMessageW, [hMainToolbar], TB_ENABLEBUTTON, actRun, edi
        invoke  SendMessageW, [hMainToolbar], TB_ENABLEBUTTON, actDebug, edi

        invoke  EnableMenuItem,[hMainMenu], actCompile, ebx
        invoke  EnableMenuItem,[hMainMenu], actRun, ebx
        invoke  EnableMenuItem,[hMainMenu], actDebug, ebx
        invoke  EnableMenuItem,[hMainMenu], actRunDirect, ebx

.compile_action_ok:

        cmp     [.changed], 0
        je      .quit
        invoke  InvalidateRect, [hMainToolbar], NULL, FALSE
.quit:
        pop     ebx edi esi
        return
endp


proc _checkfirstforsave, .ptrFile, .dummy
begin
        stdcall GetModified, [.ptrFile]
        bt      eax, 0
        return
endp















;---------------------------------------------------
; Opens file(s) in the Fresh
;
;---------------------------------------------------
proc OnOpen, .wparam, .lparam
begin
        stdcall OpenFilesDialog, [hMainForm], cOpenFileTitle, TRUE, AllFilter, OpenFileByNameEdit, 0, 0
        return
endp




proc OnOpenFileAtCursor, .wparam, .lparam
.line      rw aeLineCharLen
.pos       AEPOS
.directory rb 1024
.name      dd ?
begin
        mov     esi, [ptrCurrentFile]
        mov     eax, [esi+TOpenFile.ptrType]
        cmp     [eax+TFileType.CreateProc], CreateSourceEditor
        jne     .finish

        mov     ebx, [esi+TOpenFile.hEditor]
        test    ebx, ebx
        je      .finish

        lea     eax, [.pos]
        invoke  SendMessageW, ebx, AEM_GETPOS, eax, 0

        lea     esi, [.line]
        invoke  SendMessageW, ebx, AEM_GETLINEDATA, 0, esi

        mov     ebx, [.pos.caretPosition]
        dec     ebx
        mov     ax, '"'
        mov     cx, "'"

; Search to left
.toleft:
        dec     ebx
        js      .finish

        cmp     [esi + aeCharSize * ebx], ax
        je      .found
        cmp     [esi + aeCharSize * ebx], cx
        jne     .toleft

        mov     ax, cx

.found:
        lea     edi, [esi + aeCharSize * ebx + aeCharSize]

; search to right
.toright:
        inc     ebx
        cmp     ebx, aeLineCharLen
        jae     .finish

        cmp     [esi + aeCharSize * ebx], ax
        jne     .toright

.foundName:

        mov     word [esi + aeCharSize * ebx], 0

        mov     eax, [ptrCurrentFile]

        stdcall GetFullPathNameUtf8, [eax+TOpenFile.hFileName]
        mov     ebx, eax

        stdcall StrSplitFilename, ebx
        stdcall StrDel, eax

        stdcall SetCurrentDir, ebx
        stdcall StrDel, ebx

        stdcall WideCharToUtf8, edi
        push    eax

        stdcall ConvertAliasString, eax
        push    eax

        stdcall OpenFileByName, eax, NULL, TRUE

        stdcall StrDel ; from the stack
        stdcall StrDel ; from the stack

.finish:
        return
endp





;----------------------------------------------------
; Save the current project and all open files to disk.
;----------------------------------------------------
proc OnSaveAll, .wparam, .lparam
begin
        stdcall EnumOpenFiles, _dosaveonefile, 0
        stdcall EnumOpenFiles, _dosaveonefile, 0
        return
endp


proc  _dosaveonefile, .ptrFile, .dummy
begin
        stdcall SaveFile, [.ptrFile]
        clc
        return
endp



;----------------------------------------------------
; Save the current editor file to the disk.
;----------------------------------------------------
proc OnSave, .wparam, .lparam
begin
        stdcall SaveFile, [ptrCurrentFile]
        return
endp


;----------------------------------------------------------
; Save the current editor file to the disk with new name.
;----------------------------------------------------------
proc OnSaveAs, .wparam, .lparam
begin
        mov     esi, [ptrCurrentFile]
        test    esi, esi
        jz      .finish
        xor     ebx, ebx
        inc     ebx
        xchg    [esi+TOpenFile.fNeverSaved], ebx

        stdcall SaveFile, esi
        test    eax, eax
        jnz     .finish

        xchg    [esi+TOpenFile.fNeverSaved], ebx

.finish:
        return
endp



;------------------------------------------
; actExit action handler
;------------------------------------------
proc OnExit, .wparam, .lparam
begin
        invoke  PostMessageW, [hMainForm], WM_CLOSE, 0, 0
        return
endp




;------------------------------------------
; actClose action handler.
; Closes the current file.
;------------------------------------------
proc OnFileClose, .wparam, .lparam
begin
        xor     eax, eax
        xchg    eax, [ptrCurrentFile]
        stdcall CloseFile, eax
        return
endp


;------------------------------------------
; actCloseAll action handler.
;------------------------------------------
proc OnCloseAll, .wparam, .lparam
begin
        stdcall EnumOpenFiles, _docloseone, NULL
        mov     [ptrCurrentFile], 0
        return
endp



proc _docloseone, .ptrFile, .dummy
begin
        stdcall CloseFile, [.ptrFile]
        cmp     eax, cfrCanceled
        je      .stop
        clc
        return

.stop:
        stc
        return
endp



proc OnCleanupMRU, .wparam, .lparam
begin
        stdcall  ValidateMRUList, [ptrMRUFiles], _MRUCheckCallback
        stdcall  ValidateMRUList, [ptrMRUProj], _MRUCheckCallback
        return
endp


proc _MRUCheckCallback, .hMRUItem
begin
        stdcall StrPtr, [.hMRUItem]
        stdcall FileExists, eax
        return
endp



;------------------------------------------
; aux procedure. make simultaneous switch
; of menu item and toolbutton with the same
; action.
;------------------------------------------
proc ActionSetCheck, .ID, .check
begin
        push    esi ebx
        movzx   ebx, word [.ID]
        mov     eax, MF_UNCHECKED
        xor     esi,esi
        cmp     [.check], FALSE
        je      @f
        mov     eax, MF_CHECKED
        inc     esi
@@:
        or      eax, MF_BYCOMMAND
        invoke  CheckMenuItem, [hMainMenu], ebx, eax
        invoke  SendMessageW, [hMainToolbar], TB_CHECKBUTTON, ebx, esi
        pop     ebx esi
        return
endp

;------------------------------------------
; actGridView action handler
;------------------------------------------
proc OnGridView, .wparam, .lparam
begin
        xor     [fGridVisible],1
        stdcall ActionSetCheck, [.wparam], [fGridVisible]
;        invoke  SendMessageA, [hProjManager], PMM_REFRESHFORMS, 0, 0

        stdcall EnumOpenFiles, DoRefreshForms, 0
        return
endp


proc DoRefreshForms, .ptrFile, .dummy
begin
        mov     eax, [.ptrFile]
        cmp     [eax+TOpenFile.ptrType], ftFormSource
        jne     .finish

        cmp     [eax+TOpenFile.hEditor], 0
        je      .finish

        invoke  GetPropW, [eax+TOpenFile.hEditor], [propWinTemplate]
        test    eax, eax
        jz      .finish

        invoke  InvalidateRect, [eax+TWinTemplateDT.hwnd], NULL, TRUE

.finish:
        clc
        return
endp


;------------------------------------------
; actSnap action handler
;------------------------------------------
proc OnSnap, .wparam, .lparam
begin
        xor     [fSnapToGrid],1
        stdcall ActionSetCheck, [.wparam], [fSnapToGrid]
        return
endp

;------------------------------------------
; actSnap action handler
;------------------------------------------
proc OnPartialSelect, .wparam, .lparam
begin
        xor     [fPartialSelect],1
        stdcall ActionSetCheck, [.wparam], [fPartialSelect]
        return
endp


proc OnViewProjMan, .wparam, .lparam
begin

        invoke  IsWindowVisible, [hProjManager]
        mov     ebx, SW_SHOWNORMAL
        xor     eax, TRUE
        jnz     @f
        mov     ebx, SW_HIDE
@@:
        stdcall ActionSetCheck, [.wparam], eax
        invoke  ShowWindow, [hProjManager], ebx

        stdcall __RefreshLeftPane

        return
endp


proc OnViewPropEditor, .wparam, .lparam
begin

        invoke  IsWindowVisible, [hPropEditor]
        mov     ebx, SW_SHOWNORMAL
        xor     eax, TRUE
        jnz     @f
        mov     ebx, SW_HIDE
@@:
        stdcall ActionSetCheck, [.wparam], eax
        invoke  ShowWindow, [hPropEditor], ebx

        stdcall __RefreshLeftPane

        return
endp



proc __RefreshLeftPane
begin
        pushad

        mov     ebx, [hProjManager]
        test    ebx, ebx
        jz      .projok

        invoke  IsWindowVisible, [hProjManager]
        mov     ebx, eax

.projok:

        invoke  IsWindowVisible, [hPropEditor]
        mov     ecx, eax

        test    ebx, ebx
        setnz   bl
        movzx   ebx, bl

        test    ecx, ecx
        setnz   cl
        movzx   ecx, cl

        test    ecx, ecx
        jz      @f

        invoke  SendMessageW, [hPropEditor], PEM_GETCONTROL, 0, 0

        test    eax, eax
        setnz   cl
        movzx   ecx, cl

@@:
        stdcall SetCellHidden, [hMainForm], MainLayout.cellPropEditor, ecx
        stdcall SetCellHidden, [hMainForm], MainLayout.cellProjectManager, ebx

        mov     eax, ebx
        or      eax, ecx

        stdcall SetCellHidden, [hMainForm], 5, eax

        popad
        return
endp


;proc OnViewSourceEditor, .wparam, .lparam
;begin
;        invoke  IsWindowVisible, [hEditorsHost]
;        test    eax, eax
;        jnz     .setfocus
;
;        mov     ebx, SW_SHOWNORMAL
;        mov     eax, TRUE
;        stdcall ActionSetCheck, [.wparam], eax
;        invoke  ShowWindow, [hEditorsHost], ebx
;        return
;
;.setfocus:
;        stdcall ProcessMessages
;        invoke  SetActiveWindow, [hEditorsHost]
;        return
;endp


proc OnViewPalette, .wparam, .lparam
begin
        invoke  IsWindowVisible, [hToolPalette]
        test    eax, eax
        setnz   bl
        movzx   ebx, bl         ; SW_SHOWNORMAL = 1 and SW_HIDE = 0 !!!

        xor     ebx, SW_SHOWNORMAL

        stdcall ActionSetCheck, [.wparam], ebx
        invoke  ShowWindow, [hToolPalette], ebx
        stdcall SetCellHidden, [hMainForm], MainLayout.cellPalette, ebx

        return
endp



proc OnViewLister, .wparam, .lparam
begin
        invoke  IsWindowVisible, [hLister]
        mov     ebx, eax
        test    ebx, ebx
        jz      @f

        invoke  GetFocus
        cmp     eax, [hLister]
        je      @f              ; it is focused

        mov     eax, [hLister]
        jmp     .focus

@@:
        xor     ebx, TRUE
        invoke  SendMessageW, [hLister], LM_SHOW, ebx, 0

        mov     eax, [hLister]
        test    ebx, ebx
        jnz     .focus

        invoke  SendMessageW, [hEditorsHost], EHM_GETCURRENTASMEDIT, 0, 0

.focus:
        invoke  SetFocus, eax
        return
endp


proc OnShowForm, .wparam, .lparam
begin
        mov     eax, [ptrCurrentFile]
        test    eax, eax
        jz      .exit

        cmp     [eax+TOpenFile.ptrType], ftFormSource
        jne      .exit

        invoke  SendMessageW, [eax+TOpenFile.hEditor], FEM_SWITCHMODE, 2, 0     ; 2 == switch the opposite.

.exit:
        return
endp



proc OnUndo, .wparam, .lparam
begin
        stdcall CommonAction2, WM_UNDO
        return
endp


proc OnPaste, .wparam, .lparam
begin
        stdcall CommonAction2, WM_PASTE
        return
endp

proc OnDelete, .wparam, .lparam
begin
        stdcall CommonAction2, WM_CLEAR
        return
endp


proc OnCut, .wparam, .lparam
begin
        stdcall CommonAction2, WM_CUT
        return
endp


proc OnCopy, .wparam, .lparam
begin
        stdcall CommonAction2, WM_COPY
        return
endp


proc CommonAction2, .cmd
begin
        invoke  GetFocus
        mov     esi, eax

        invoke  GetPropW, esi, [propOpenFileStructure]
        test    eax, eax
        jnz     .toeditor

        mov     eax, esi

.loop:
        mov     ebx, eax
        invoke  GetPropW, ebx, [propTemplateDT]
        test    eax, eax
        jnz     .toformeditor

        invoke  GetParent, ebx
        test    eax, eax
        jnz     .loop

.control:
        invoke  SendMessageW, esi, [.cmd], 0, 0
        return

.toeditor:
        stdcall CommonAction, eax, [.cmd]
        return

.toformeditor:
        cmp     [eax+TWinTemplateDT.ptrFile], 0
        je      .next

        mov     eax, [eax+TWinTemplateDT.ptrFile]
        jmp     .toeditor

.next:
        mov     eax, [eax+TWinTemplateDT.parent]
        test    eax, eax
        jnz     .toformeditor
        return
endp

;------------------------------------------------
; Temporary action handler for functions
; not implemented on this stage.
;------------------------------------------------
proc OnNotImplemented, .wparam, .lparam
begin
        stdcall ErrorMessage, errNotImplemented
        return
endp




;------------------------------------------
; actAbout action handler
; using of message box is only temporary.
; this must be more fancy :)
;------------------------------------------
proc OnAbout, .wparam, .lparam
begin
        stdcall CreateForm, AboutForm, [hMainForm]

        stdcall ShowModal, ebx, MSF_CENTER

        invoke  DestroyWindow, ebx

        return
endp



iglobal
  property propBackground, "Background"
  property propEditBrush, "EditBrush"
endg

cAboutBackground = $20d0a0

proc AboutWinProc, .hwnd, .wmsg, .wparam, .lparam
begin
        dispatch [.wmsg]
        stc
        return

oncase SGM_REALIGN

        stdcall OnRealignWithPadding, [.hwnd], 16, 16, 16, 16

        clc
        return


oncase WM_CTLCOLORSTATIC

        invoke  SetTextColor, [.wparam], $ffffff

        invoke  SetBkMode, [.wparam], TRANSPARENT
        invoke  GetPropW, [.hwnd], [propEditBrush]
        clc
        return


oncase FM_AFTERCREATE

        stdcall ImageList_LoadGif, [hInstance], resBmpAbout, 170, FALSE
        invoke  SetPropW, [.hwnd], [propBackground], eax
        invoke  SetPropW, [.hwnd], [propColor], cAboutBackground

        invoke  CreateSolidBrush, cAboutBackground
        invoke  SetPropW, [.hwnd], [propEditBrush], eax

        invoke  SendDlgItemMessageW, [.hwnd], 101, STM_SETIMAGE, IMAGE_BITMAP, eax

        stdcall SetDlgItemTextUtf8, [.hwnd], 102, cAboutText

        stdcall SetSplitGrid, [.hwnd], AboutLayout
        stdcall AttachToCellDlgItem, [.hwnd], MR_OK, AboutLayout.cellBtnClose
        stdcall AttachToCellDlgItem, [.hwnd], 102, AboutLayout.cellText

        invoke  CreateFontW, -16, 0, 0, 0, FW_BOLD, 0, 0, 0, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FF_DECORATIVE, 0
        invoke  SendDlgItemMessageW, [.hwnd], 102, WM_SETFONT, eax, FALSE

        clc
        return


oncase WM_DESTROY

        invoke  SendDlgItemMessageW, [.hwnd], 102, WM_GETFONT, 0, 0
        invoke  DeleteObject, eax

        invoke  GetPropW, [.hwnd], [propBackground]
        invoke  ImageList_Destroy, eax

        invoke  GetPropW, [.hwnd], [propEditBrush]
        invoke  DeleteObject, eax

        stc
        return

oncase WM_PAINT
locals
  .ps PAINTSTRUCT
  .cx dd ?
  .cy dd ?
  .rect RECT
  .rtxt RECT
endl

        lea     eax, [.ps]
        invoke  BeginPaint, [.hwnd], eax

        invoke  GetPropW, [.hwnd], [propBackground]
        mov     ebx, eax

        lea     eax, [.cx]
        lea     ecx, [.cy]
        invoke  ImageList_GetIconSize, ebx, eax, ecx

        stdcall GetCellRect, [.hwnd], AboutLayout.cellPicture
        jc      .draw_end

        mov     esi, eax

        mov     eax, [esi+RECT.bottom]
        sub     eax, [esi+RECT.top]
        sub     eax, [.cy]
        sar     eax, 1
        add     eax, [esi+RECT.top]

        mov     ecx, [esi+RECT.right]
        sub     ecx, [esi+RECT.left]
        sub     ecx, [.cx]
        sar     ecx, 1
        add     ecx, [esi+RECT.left]

        invoke  ImageList_Draw, ebx, 0, [.ps.hdc], ecx, eax, ILD_TRANSPARENT

.draw_end:
        lea     eax, [.ps]
        invoke  EndPaint, [.hwnd], eax

        xor     eax, eax
        clc
        return


        enddispatch

endp




iglobal
  ; About box form definition.
  Window AboutForm, wtParent or wtEnd, waNone, 'TForm', 'About "Fresh"...', WS_POPUPWINDOW or WS_CLIPCHILDREN, WS_EX_CONTROLPARENT, NULL, 0, 0, 640, 360, AboutWinProc
  Window NONE, wtChild, waBottom, 'Button', 'Close', WS_VISIBLE or WS_CHILD or WS_BORDER or WS_TABSTOP or BS_DEFPUSHBUTTON or WS_CLIPSIBLINGS, 0, MR_OK, 10, 50, 64, 25, 0
  Window NONE, wtChild or wtEnd, waClient, 'Edit', '', WS_VISIBLE or WS_CHILD or ES_LEFT or ES_MULTILINE or ES_READONLY or WS_CLIPSIBLINGS , 0, 102, 0, 10, 180, 19, 0

  SplitStart AboutLayout
    Split stVert or stJustGap or stOriginBR, 8, 25, 0, 100
      Split stHoriz or stJustGap or stOriginBR, 8, 320, 0, 1000
        Cell cellPicture
        Cell cellText
      Split stHoriz or stOriginBR or stJustGap, 0, 64, 0, 100
        Cell cellEmpty1
        Cell cellBtnClose
  SplitEnd




  cAboutText db ' Fresh IDE', $0d, $0a, $0d, $0a
             db ' IDE: ', FRESH_VERSION, $0d, $0a
             db ' build: '
             create_build_time DAY, MONTH, YEAR
             db $0d, $0a
             db ' checkin: '
             file "../manifest.uuid": 0, 16
             db $0d, $0a, $0d, $0a
             db '    © John Found', $0d, $0a
             db '    © Fredrik Klasson (aka scientica)', $0d, $0a
             db '    © Tommy Lillehagen',$0d, $0a
             db '    © Mateusz Tymek (aka decard)', $0d, $0a
             db '    © Victor Loh (aka roticv)', $0d, $0a
             db '    © Yunus Sina Gulsen (aka VeSCeRa)', $0d, $0a
             db '    © Pelaillo', $0d, $0a, $0d, $0a
             db '  Compiler: FASM ',VERSION_STRING, $0d, $0a
             db '    © Tomasz Grysztar (aka Privalov)', 0

endg




;*****************************************************************************
; Bookmarks actions and some edit actions by Tommy Lillehagen.
;*****************************************************************************

proc OnToggleBM, .wparam, .lparam
begin
        stdcall GetCurrentAsmEdit
        jc      .finish
        invoke  SendMessageW, eax, AEM_TOGGLEBOOKMARK, 0, 0
.finish:
        return
endp



proc OnNextBM, .wparam, .lparam
.pos AEPOS
begin
        stdcall GetCurrentAsmEdit
        jc      .finish
        mov     ebx,eax
        invoke  SendMessageW,ebx, AEM_GOTOBOOKMARK, 0, AEBM_NEXT

        mov     [.pos.caretLine],eax
        mov     [.pos.selectionLine],eax
        mov     [.pos.caretPosition],1
        mov     [.pos.selectionPosition],1
        lea     eax, [.pos]
        invoke  SendMessageW, ebx, AEM_SETPOS, eax, 0
.finish:
        return
endp



proc OnPrevBM, .wparam, .lparam
.pos AEPOS
begin
        stdcall GetCurrentAsmEdit
        jc      .finish

        mov     ebx,eax
        invoke  SendMessageW, ebx, AEM_GOTOBOOKMARK, 0, AEBM_PREV
        mov     [.pos.caretLine], eax
        mov     [.pos.selectionLine], eax
        mov     [.pos.caretPosition],1
        mov     [.pos.selectionPosition],1
        lea     eax, [.pos]
        invoke  SendMessageW, ebx, AEM_SETPOS, eax, 0
.finish:
        return
endp


proc OnClearBM, .wparam, .lparam
begin
        stdcall GetCurrentAsmEdit
        jc      .finish
        invoke  SendMessageW, eax, AEM_CLEARBOOKMARKS, 0, 0
.finish:
        return
endp


proc OnComment, .wparam, .lparam
begin
        stdcall GetCurrentAsmEdit
        jc      .finish
        invoke  SendMessageW, eax, AEM_COMMENT, 0, 1
.finish:
        return
endp



proc OnUncomment, .wparam, .lparam
begin
        stdcall GetCurrentAsmEdit
        jc      .finish
        invoke  SendMessageW, eax, AEM_COMMENT, 0, 0
.finish:
        return
endp



proc OnIndent, .wparam, .lparam
begin
        stdcall GetCurrentAsmEdit
        jc      .finish
        invoke  SendMessageW, eax, AEM_INDENT, 0, 1
.finish:
        return
endp


proc OnOutdent, .wparam, .lparam
begin
        stdcall GetCurrentAsmEdit
        jc      .finish
        invoke  SendMessageW, eax, AEM_INDENT, 0, 0
.finish:
        return
endp



;************************************************************************
; Returns modal result from progress window.
;************************************************************************
proc OnCompile, .wparam, .lparam
.exit dd ?
.compiled_file dd ?
begin
        stdcall WaitForCompiler
        jc      .error_hanging

        invoke  SendMessageW, [frmMsg], MWM_CLEARMESSAGES, 0, 0

; Set output filename...

        xor     eax, eax
        cmp     [poBinNameAuto], FALSE
        jne     .setoutputname

        stdcall StrLen, [poBinName]
        test    eax, eax
        jz      .setoutputname

uglobal
  out_filename_buffer rb 1024
endg
        lea     ecx, [eax+1]
        cmp     ecx, 256
        jbe     .copy_output_name

        xor     eax, eax
        jz      .setoutputname

.copy_output_name:
        stdcall StrPtr, [poBinName]
        mov     esi, eax
        mov     edi, out_filename_buffer
        rep movsb

        mov     eax, out_filename_buffer

.setoutputname:
        mov     [output_file], eax
        mov     [symbols_file], cDumpFilename

        stdcall ProgressWndCreate, 4, 1, cProgressCaption, 0

        invoke  SendMessageW, [hProjManager], PMM_GETMAINFILE, 0, 0
        test    eax, eax
        jnz     .docompile

        mov     eax, [ptrCurrentFile]
        test    eax, eax
        jz      .finish

        cmp     [eax+TOpenFile.ptrType], ftCommonSource
        jne     .finish

.docompile:
        mov     [.compiled_file], eax

        stdcall PrepareForCompilation, [eax+TOpenFile.hFileName]
        test    eax, eax
        jz      .outofmemory

        mov     [flagFakeCompile], 0
        mov     [initial_definitions], 0

        stdcall ThreadCreate, flat_assembler, NULL
        mov     [comp_handle], eax

        stdcall ShowModal, [hProgressWnd], MSF_CENTER
        mov     [.exit], eax

        cmp     [.exit], MR_CANCEL
        jne     .compended

;user canceled the compilation
        invoke  TerminateThread, [comp_handle], -1
        invoke  CloseHandle, [comp_handle]
        mov     [comp_handle], 0

        mov     [fmsg.link.hFileName], 0
        mov     [fmsg.type], mtError
        mov     [fmsg.hMessage], cCanceled
        invoke  SendMessageW, [frmMsg], MWM_ADDMESSAGE, fmsg, TVI_ROOT
        mov     ebx, eax

        jmp     .cleanup

.compended:
        cmp     [.exit], MR_OK
        je      .compile_ok

        stdcall WaitForCompiler
        jc      .compile_ok

; try to compile with flagFakeCompile = 1 -> this should remove errors.
        stdcall CleanupAfterCompilation
        mov     eax, [.compiled_file]
        stdcall PrepareForCompilation, [eax+TOpenFile.hFileName]

        mov     [flagFakeCompile], 1
        mov     [initial_definitions], cFakeCompileSymbol

        mov     [output_file], cFakeBinFilename
        mov     [symbols_file], cDumpFilename

        stdcall ThreadCreate, flat_assembler, 0
        mov     [comp_handle], eax

        stdcall ShowModal, [hProgressWnd], MSF_CENTER

        cmp     [output_file], 0
        je      .compile_ok

        stdcall FileDelete, [output_file]

.compile_ok:
        cmp     [.exit], MR_OK
        jne     .error_pos

        cmp     [output_format], 5      ; ELF
        jne     .finalize

; set the executable permission for the ELF file

        stdcall SetElfPermissions, [CompiledFileName], 755o
        jmp     .finalize


; find the error message.
.error_pos:
        invoke  SendMessageW, [frmMsg], MWM_FIRSTERROR, 0, 0

.finalize:
        stdcall AddCompilationStatistics

.cleanup:
        stdcall CleanupAfterCompilation

        mov     [flagFakeCompile], 0
        mov     [initial_definitions], 0

        push    [.exit]
        jmp     .return

.error_hanging:
        stdcall ErrorMessage, errCompilerHang
        jmp     .finish

.outofmemory:
        stdcall ErrorMessage, errCompilerMemory

.finish:
        push    MR_ABORT

.return:
        stdcall ProgressWndDestroy

        pop     eax
        return
endp

uglobal
  comp_handle dd ?
endg

cDumpFilename text 'dump.fas'
cProgressCaption text 'Compiling...'
cFakeBinFilename text 'dump.bin'


proc OnDebug, .wparam, .lparam
.sinfo  STARTUPINFO
.pinfo  PROCESSINFO
begin
        stdcall OnCompile, 0, 0
        cmp     eax, MR_OK
        jne     .finish         ; There are errors during compilation.

        cmp     [output_format], 5
        jne     .windebuger

        stdcall RunInLinux, TRUE
        jmp     .finish

.windebuger:
        mov     ecx, sizeof.STARTUPINFO / 4
        lea     edi,[.sinfo]
        xor     eax, eax
        rep stosd
        mov     [.sinfo.cb], sizeof.STARTUPINFO
        mov     [.sinfo.dwFlags],0

        stdcall GetParamFromINI, cDebugerKey
        jnc     .debuggerok

        stdcall StrNew
        push    eax
        jmp     .nodebugger

.debuggerok:
        push    eax
        stdcall StrCharCat, eax, ' '

.nodebugger:
        stdcall StrCharCat, eax, '"'
        stdcall StrCat, eax, [CompiledFileName]
        stdcall StrCharCat, eax, '"'

        stdcall utf8ToWideChar, eax
        stdcall StrDel ; from the stack
        push    eax

        lea     edx,[.sinfo]
        lea     ecx,[.pinfo]
        invoke  CreateProcessW, NULL, eax, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE, NULL, NULL, edx, ecx
        stdcall FreeMem ; from the stack

        test    eax,eax
        jnz     .ok

        stdcall LastError
.ok:
        invoke  CloseHandle, [.pinfo.hThread]
        invoke  CloseHandle, [.pinfo.hProcess]
.finish:
        return
endp



proc OnShowMessages, .wparam, .lparam
begin

        invoke  IsWindowVisible, [frmMsg]
        xor     eax, 1
        invoke  SendMessageW, [frmMsg], MWM_SHOWMESSAGES, eax, 0
        return
endp



iglobal
  Window  dlgCategorySelect,  wtParent or wtEnd, waNone, 'TForm', 'Add category:', $00080000, WS_EX_DLGMODALFRAME, 0, 0, 0, 252, 208, CategorySelectProc
  Window  NONE,  wtChild, waNone, 'Static', 'Category &Name:', ComCtrlStyle, 0, 0, 4, 4, 200, 16, NULL
  Window  NONE,  wtChild, waNone, 'Edit', '', ComCtrlStyle or WS_TABSTOP or ES_AUTOHSCROLL,  WS_EX_CLIENTEDGE, 101, 4, 20, 236, 19, NULL
  Window  NONE,  wtChild, waNone, 'Static', 'Category &Icon:', ComCtrlStyle, 0, 0, 4, 42, 200, 16, NULL
  Window  NONE,  wtChild, waNone, LISTVIEW_CLASS, '', ComCtrlStyle or WS_TABSTOP or LVS_ICON or LVS_SINGLESEL or LVS_SHAREIMAGELISTS or LVS_NOLABELWRAP or LVS_AUTOARRANGE or LVS_NOSCROLL or LVS_SHOWSELALWAYS, WS_EX_CLIENTEDGE, 102, 4, 58, 236, 92, NULL
  Window  NONE,  wtChild, waNone, 'Button', 'OK', ComCtrlStyle or WS_TABSTOP or BS_DEFPUSHBUTTON, 0, MR_OK, 48, 156, 64, 24, NULL
  Window  NONE,  wtChild or wtEnd, waNone, 'Button', 'Cancel', ComCtrlStyle or WS_TABSTOP, 0, MR_CANCEL, 128, 156, 64, 24, NULL
endg


proc CategorySelectProc, .hwnd, .wmsg, .wparam, .lparam
.lvi LVITEM
.tvi TVITEM
.str rb 256
begin
        cmp     [.wmsg], FM_AFTERCREATE
        je      .aftercreate

        stc
        return

.aftercreate:
        invoke  SendDlgItemMessageW, [.hwnd], 102, LVM_SETIMAGELIST, LVSIL_NORMAL, [imlCategories]
        invoke  SendDlgItemMessageW, [.hwnd], 102, LVM_SETICONSPACING, 0, $00240018
        invoke  SendDlgItemMessageW, [.hwnd], 102, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_BORDERSELECT

        invoke  ImageList_GetImageCount, [imlCategories]
        mov     ebx, eax
        xor     esi, esi

.imageadd:
        lea     ecx, [esi+1]
        stdcall NumToStr, ecx, ntsUnsigned or ntsDec
        push    eax

        stdcall utf8ToWideChar, eax
        stdcall StrDel ; from the stack

        mov     [.lvi.pszText], eax
        mov     [.lvi.mask], LVIF_IMAGE or LVIF_TEXT
        mov     [.lvi.iItem], esi
        mov     [.lvi.iSubItem], 0
        mov     [.lvi.iImage], esi
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageW, [.hwnd], 102, LVM_INSERTITEMW, 0, eax
        stdcall FreeMem, [.lvi.pszText] ; from the stack

        inc     esi
        dec     ebx
        jnz     .imageadd

        mov     [.lvi.stateMask], LVIS_FOCUSED or LVIS_SELECTED
        mov     [.lvi.state], LVIS_FOCUSED or LVIS_SELECTED
        lea     eax, [.lvi]
        invoke  SendDlgItemMessageW, [.hwnd], 102, LVM_SETITEMSTATE, 0, eax

        invoke  GetDlgItem, [hProjManager], ProjTreeCtrlID
        mov     ebx, eax

        invoke  SendMessageW, ebx, TVM_GETNEXTITEM, TVGN_CARET, 0


        stdcall GetFullItemName, ebx, eax
        push    ecx
        push    eax

        stdcall SetDlgItemTextUtf8, [.hwnd], 101, eax
        invoke  SendDlgItemMessageW, [.hwnd], 101, EM_SETSEL, 0, -1
        stdcall StrDel ; from the stack.

        pop     ecx
        lea     eax, [.lvi]
        mov     [eax+LVITEM.stateMask], LVIS_FOCUSED or LVIS_SELECTED
        mov     [eax+LVITEM.state], LVIS_FOCUSED or LVIS_SELECTED

        invoke  SendDlgItemMessageW, [.hwnd], 102, LVM_SETITEMSTATE, ecx, eax

        invoke  SendMessageW, [hProjManager], _CEM_SETMODIFIED, TRUE, 0

        clc
        return
endp


proc OnAddCategory, .wparam, .lparam
.res  dd ?
begin
        mov     [.res], FALSE

        stdcall CreateForm, dlgCategorySelect, [hMainForm]

        stdcall ShowModal, ebx, MSF_CENTER
        cmp     eax, MR_OK
        jne     .finishadd

        invoke  SendDlgItemMessageW, ebx, 102, LVM_GETNEXTITEM, -1, LVNI_FOCUSED
        cmp     eax, -1
        jne     @f

        mov     eax, 4
@@:
        mov     edi, eax

        stdcall  GetDlgItemTextUtf8, ebx, 101
        push     eax ; for delete

        stdcall StrCharCat, eax, '\'
        stdcall GetCategoryTree, eax, TVI_ROOT, edi

        invoke  SendDlgItemMessageW, [hProjManager], ProjTreeCtrlID, TVM_SELECTITEM, TVGN_CARET, eax

        stdcall StrDel ; From the stack.
        mov     [.res], TRUE

        invoke  SendMessageW, [hProjManager], _CEM_SETMODIFIED, TRUE, 0

.finishadd:
        invoke  DestroyWindow, ebx
        mov     eax, [.res]
        return
endp



proc OnEditCategory, .wparam, .lparam
.tvi TVITEM
begin
        stdcall CreateForm, dlgCategorySelect, [hMainForm]
        invoke  SendDlgItemMessageW, ebx, 101, EM_SETREADONLY, TRUE, 0

        stdcall ShowModal, ebx, MSF_CENTER
        cmp     eax, MR_OK
        jne     .finish

        invoke  SendDlgItemMessageW, ebx, 102, LVM_GETNEXTITEM, -1, LVNI_FOCUSED
        cmp     eax, -1
        jne     @f

        mov     eax, 4
@@:
        mov     edi, eax

        stdcall  GetDlgItemTextUtf8, ebx, 101
        push     eax ; for delete

        stdcall GetCategoryTree, eax, TVI_ROOT, edi

        lea     ecx, [.tvi]
        mov     [ecx+TVITEM.hItem], eax
        mov     [ecx+TVITEM.mask], TVIF_IMAGE or TVIF_SELECTEDIMAGE
        mov     [ecx+TVITEM.iImage], edi
        mov     [ecx+TVITEM.iSelectedImage], edi

        invoke  SendDlgItemMessageW, [hProjManager], ProjTreeCtrlID, TVM_SETITEMW, 0, ecx
        invoke  SendDlgItemMessageW, [hProjManager], ProjTreeCtrlID, TVM_SELECTITEM, TVGN_CARET, eax

        stdcall StrDel ; From the stack.

.finish:
        invoke  DestroyWindow, ebx
        return
endp


proc OnDelCategory, .wparam, .lparam
begin
        push    ebx esi

        invoke  GetDlgItem, [hProjManager], ProjTreeCtrlID
        mov     ebx, eax

        invoke  SendMessageW, ebx, TVM_GETNEXTITEM, TVGN_CARET, 0
        test    eax, eax
        jz      .finish

        mov     esi, eax

        stdcall AskQuestion, cDelProjQuery, [hMainForm], answerYesNo
        cmp     eax, IDYES
        jne     .finish

        invoke  SendMessageW, ebx, TVM_DELETEITEM, 0, esi

.finish:
        pop     esi ebx
        return
endp

cDelProjQuery text 'Do you really want to remove this category and all category files from the project?'



proc OnAddFile, .wparam, .lparam
begin
        stdcall OpenFilesDialog, [hMainForm], cAddFileTitle, TRUE, AllFilter, _AddFileCallback, FALSE, NULL
        return
endp


proc _AddFileCallback, .hFileName, .lParam
begin
        stdcall OpenFileByName, [.hFileName], NULL, FALSE
        test    eax, eax
        jz      .finish
        invoke  SendMessageW, [hProjManager], PMM_ADDFILE, eax, -1
.finish:
        return
endp


proc OnDelFile, .wparam, .lparam
.lvi LVITEM
begin
        push    ebx esi

        xor     ebx, ebx
        push    ebx             ; marker for the end of the list
        dec     ebx

        invoke  GetFocus
        mov     esi, eax
        invoke  GetWindowLongW, esi, GWL_ID
        cmp     eax, ProjListCtrlID
        je      .delloop

        cmp     eax, ProjMainCtrlID
        je      .delloop

        invoke  GetDlgItem, [hProjManager], ProjListCtrlID
        mov     esi, eax

.delloop:
        invoke  SendMessageW, esi, LVM_GETNEXTITEM, ebx, LVNI_SELECTED
        cmp     eax, -1
        je      .delit

        mov     ebx, eax

        mov     [.lvi.mask], LVIF_PARAM
        mov     [.lvi.iItem], eax
        lea     eax, [.lvi]
        invoke  SendMessageW, esi, LVM_GETITEMW, 0, eax
        push    [.lvi.lParam]
        jmp     .delloop

.delit:
        cmp     dword [esp], 0
        je      .delitloop

        stdcall AskQuestion, cDelFileQuery, [hMainForm], answerYesNo
        cmp     eax, IDYES
        je      .delitloop

.clearstack:
        pop     ecx
        jecxz   .endfiledel
        jmp     .clearstack

.delitloop:
        pop     ecx
        jecxz   .endfiledel
        invoke  SendMessageW, [hProjManager], PMM_REMOVEFILE, ecx, 0
        jmp     .delitloop

.endfiledel:
        pop     esi ebx
        return

endp

cDelFileQuery text 'Do you really want to remove selected file(s) from the project?'



proc OnSetMainFile, .wparam, .lparam
begin
        stdcall OpenFilesDialog, [hMainForm], cSetMainTitle, FALSE, FileFilter, _SetMainCallback, NULL, 0
        return
endp


proc _SetMainCallback, .hFileName, .dummy
begin
        stdcall OpenFileByName, [.hFileName], NULL, FALSE
        test    eax, eax
        jz      .finish
        invoke  SendMessageW, [hProjManager], PMM_ADDFILE, eax, 0
.finish:
        return
endp




proc OnShowNotUsed, .wparam, .lparam
begin
        invoke  SendMessageW, [frmMsg], MWM_CLEARMESSAGES, 0, 0
        stdcall ShowNotUsed
        return
endp


proc OnAutoArrange, .wparam, .lparam
begin
;        stdcall AutoArrangeWindows, FALSE
        return
endp

proc OnNextWindow, .wparam, .lparam
begin
        invoke  SendMessageW, [hEditorsHost], _EHM_SETACTIVETAB, 1, TRUE
        return
endp



proc OnPrevWindow, .wparam, .lparam
begin
        invoke  SendMessageW, [hEditorsHost], _EHM_SETACTIVETAB, -1, TRUE
        return
endp


iglobal
  cIncludeFilesTitle du 'Filenames as "include" statement', 0
  cIncludeRoot       dd 0
endg

proc OnIncludeFile, .wparam, .lparam
.aepos AEPOS
.hwnd  dd ?
.IncludeGroup dd ?
begin
        stdcall GetCurrentAsmEdit
        jc      .finish

        mov     [.hwnd], eax

        stdcall StrNew
        mov     [.IncludeGroup], eax

        stdcall ConvertAliasString, cIncludeRoot
        push    eax
        stdcall OpenFilesDialog, [hMainForm], cIncludeFilesTitle, TRUE, AllFilter, _DoInsertOneFile, eax, [.IncludeGroup]
        stdcall StrDel ; from the stack

        lea     esi, [.aepos]
        invoke  SendMessageW, [.hwnd], AEM_GETPOS, esi, 0
        mov     [esi+AEPOS.caretPosition], 1
        mov     [esi+AEPOS.selectionPosition], 1
        mov     eax, [esi+AEPOS.caretLine]
        mov     [esi+AEPOS.selectionLine], eax
        invoke  SendMessageW, [.hwnd], AEM_SETPOS, esi, 0

        invoke  SendMessageW, [.hwnd], AEM_GETMODE, 0, 0
        push    eax
        invoke  SendMessageW, [.hwnd], AEM_SETMODE, 0, 0

;        stdcall StrCat, [.IncludeGroup], cIncludeEnd2

        stdcall utf8ToWideChar, [.IncludeGroup]
        push    eax

        invoke  SendMessageW, [.hwnd], EM_REPLACESEL, TRUE, eax
        stdcall FreeMem ; from the stack

        stdcall StrDel, [.IncludeGroup]

        pop     eax
        invoke  SendMessageW, [.hwnd], AEM_SETMODE, eax, 0

        lea     esi, [.aepos]
        invoke  SendMessageW, [.hwnd], AEM_GETPOS, esi, 0
        mov     eax, [esi+AEPOS.selectionPosition]
        mov     ecx, [esi+AEPOS.selectionLine]
        mov     [esi+AEPOS.caretPosition], eax
        mov     [esi+AEPOS.caretLine], ecx
        invoke  SendMessageW, [.hwnd], AEM_SETPOS, esi, 0

.finish:
        return
endp


proc _DoInsertOneFile, .hFileName, .hGroup
begin
        stdcall _RelativeToFinc, [.hFileName]
        stdcall StrCat, [.hGroup], cIncludeCommand

        stdcall StrCat, [.hGroup], eax
        stdcall StrDel, eax

        stdcall StrCat, [.hGroup], cIncludeEnd
        return
endp


proc _RelativeToFinc, .hFileName
.olddir dd ?
begin
        stdcall GetCurrentDir
        mov     [.olddir], eax

        stdcall ConvertAliasString, cIncludeRoot
        push    eax

        stdcall SetCurrentDir, eax
        stdcall StrDel ; from the stack

        stdcall GetRelativePath, [.hFileName]
        stdcall StrInsert, eax, cIncludeRoot, 0
        push    eax

        stdcall SetCurrentDir, [.olddir]
        stdcall StrDel, [.olddir]

        pop     eax
        return
endp

;************************************************************************
; ReplaceVarString - replaces some variable (actually string) in hEdit with
; the value of hString.
; hEdit - handle of AsmEdit control
; ptrVar - pointer to varname string.
; hString - handle of the string that will replace the var name.
;************************************************************************
proc ReplaceVarString, .hEdit, .ptrVar, .hString

.oldpos AEPOS
.aepos  AEPOS

begin
        push    ebx esi

        lea     eax, [.oldpos]
        invoke  SendMessageA, [.hEdit], AEM_GETPOS, eax, 0

        stdcall StrPtr, [.hString]
        mov     esi, eax
        test    esi, esi
        jz      .endofsearch

        mov     ebx, [.hEdit]

        mov     [.aepos.selectionPosition], 1
        mov     [.aepos.selectionLine], 1
        mov     [.aepos.caretPosition], 1
        mov     [.aepos.caretLine], 1
        lea     eax, [.aepos]
        invoke  SendMessageA, ebx, AEM_SETPOS, eax, 0
        invoke  SendMessageA, ebx, AEM_FINDFIRST, AEFIND_CASESENSITIVE, [.ptrVar]
        test    eax, eax
        jz      .endofsearch

        invoke  SendMessageA, ebx, EM_REPLACESEL, FALSE, esi

.loop:
        invoke  SendMessageA, ebx, AEM_FINDNEXT, 0, 0
        test    eax, eax
        jz      .endofsearch

        invoke  SendMessageA, ebx, EM_REPLACESEL, FALSE, esi
        jmp     .loop

.endofsearch:
        lea     eax, [.oldpos]
        invoke  SendMessageA, [.hEdit], AEM_SETPOS, eax, 0

        pop     esi ebx
        return
endp


iglobal
  cErrorAndLinux du "andLinux not supported in this version. Sorry."
endg

proc OnOpenTerminal, .wparam, .lparam
.term dd ?
.sinfo STARTUPINFO
.pinfo  PROCESSINFO
begin
        cmp     [procLinuxPath], 0
        jne     .linux

; here, must be the code for starting terminal in andLinux. But I can't test it, so better to not write buggy source.

        invoke  MessageBoxW, [hMainForm], cErrorAndLinux, NULL, MB_OK or MB_ICONERROR
        jmp     .error


.linux:
        stdcall CfgGetStr, [hCfgFileName], cParamSection, cLinuxTerminalKey
        jc      .error

        stdcall StrCat, eax, txt ' bash'

.pathok:
        mov     [.term], eax

        mov     ecx, sizeof.STARTUPINFO/4
        lea     edi, [.sinfo]
        xor     eax, eax
        rep stosd

        mov     [.sinfo.cb], sizeof.STARTUPINFO
        mov     [.sinfo.dwFlags],0

        stdcall utf8ToWideChar, [.term]
        push    eax

        lea     ecx,[.pinfo]
        lea     edx,[.sinfo]
        invoke  CreateProcessW, NULL, eax, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, edx, ecx  ; remaining from the stack
        stdcall FreeMem ; from the stack

        test    eax,eax
        jnz     .ok

        stdcall LastError

.ok:
        invoke  CloseHandle,[.pinfo.hThread]
        invoke  CloseHandle,[.pinfo.hProcess]
        stdcall StrDel, [.term]

.error:
        return
endp








        DispSize  'action events', ($ - ActionEvents)
