

struct THistoryItem
  .hFileName  dd ?
  .LineNumber dd ?
ends



uglobal
  ptrBackHistory    dd ?
  ptrForwardHistory dd ?
  fLogFileLock      dd ?
endg



proc InitBrowseHistory, .ptrHistoryVar
begin
        push    eax ecx esi

        mov     esi, [.ptrHistoryVar]

        stdcall FreeBrowseHistory, [esi]
        mov     dword [esi], 0

        stdcall CreateArray, sizeof.THistoryItem
        jc      .finish

        mov     [esi], eax

.finish:
        pop     esi ecx eax
        return
endp




proc FreeBrowseHistory, .ptrHistory
begin
        push    eax ecx esi
        cmp     [.ptrHistory], 0
        je      .finish

        mov     esi, [.ptrHistory]
        mov     ecx, [esi+TArray.count]

.free_loop:
        dec     ecx
        js      .free_array

        stdcall StrDel, [esi+TArray.array+8*ecx+THistoryItem.hFileName]
        jmp     .free_loop

.free_array:
        stdcall FreeMem, esi

.finish:
        pop     esi ecx eax
        return
endp



proc LogInHistory, .ptrHistoryVar
.filename dd ?
.line     dd ?
begin
        pushad

        stdcall GetCurrentPlace
        jc      .finish

        mov     [.filename], eax
        mov     [.line], edx

        mov     edi, [.ptrHistoryVar]

        mov     esi, [edi]
        test    esi, esi
        jnz     .history_ok

        stdcall InitBrowseHistory, edi
        mov     esi, [edi]

.history_ok:

        stdcall AddArrayItems, esi, 1
        mov     [edi], edx
        mov     esi, eax

.element_ok:
        mov     eax, [.filename]
        mov     [esi+THistoryItem.hFileName], eax

        mov     eax, [.line]
        mov     [esi+THistoryItem.LineNumber], eax

.finish:
        popad
        return
endp




proc OnHistoryBack, .wparam, .lparam
begin
        push    eax esi

        mov     esi, [ptrBackHistory]
        test    esi, esi
        jz      .finish

        mov     eax, [esi+TArray.count]
        dec     eax
        js      .finish

        mov     [esi+TArray.count], eax

        stdcall LogInHistory, ptrForwardHistory

        mov     [fLogFileLock], 1
        stdcall PosEditor, [esi+TArray.array+8*eax+THistoryItem.hFileName], [esi+TArray.array+8*eax+THistoryItem.LineNumber]
        mov     [fLogFileLock], 0

        stdcall StrDel, [esi+TArray.array+8*eax+THistoryItem.hFileName]
        mov     [esi+TArray.array+8*eax+THistoryItem.hFileName], 0
        mov     [esi+TArray.array+8*eax+THistoryItem.LineNumber], 0

.finish:
        pop     esi eax
        return

endp




proc OnHistoryForward, .wparam, .lparam
begin
        push    eax esi

        mov     esi, [ptrForwardHistory]
        test    esi, esi
        jz      .finish

        mov     eax, [esi+TArray.count]
        dec     eax
        js      .finish

        mov     [esi+TArray.count], eax

        stdcall LogInHistory, ptrBackHistory

        mov     [fLogFileLock], 1
        stdcall PosEditor, [esi+TArray.array+8*eax+THistoryItem.hFileName], [esi+TArray.array+8*eax+THistoryItem.LineNumber]
        mov     [fLogFileLock], 0

        stdcall StrDel, [esi+TArray.array+8*eax+THistoryItem.hFileName]
        mov     [esi+TArray.array+8*eax+THistoryItem.hFileName], 0
        mov     [esi+TArray.array+8*eax+THistoryItem.LineNumber], 0

.finish:
        pop     esi eax
        return

endp





; returns:
;  eax - current place filename.
;  edx - current place line number.

proc GetCurrentPlace
.aepos AEPOS
begin
        push    ebx esi

        stdcall GetCurrentAsmEdit
        jc      .error

        mov     ebx, eax

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

        invoke  SendMessageW, ebx, _CEM_GETFILE, 0, 0
        test    eax, eax
        jz      .error

        mov     esi, eax

        stdcall StrDup, [esi+TOpenFile.hFileName]
        push    eax
        push    [.aepos.caretLine]

        pop     edx
        pop     eax
        pop     esi ebx
        clc
        return

.error:
        pop     esi ebx
        stc
        return
endp

