;---------------------------------------------------------------------
; Converts some filename's path (full or relative) in relative
; form, related to current directory.
; Arg:
;   hFileName - handle/ptr of the filename.
; Returns:
;   eax - Handle to new string containing the relative path/filename
;---------------------------------------------------------------------

proc GetRelativePath, .hFileName
.hRoot dd ?
.hName dd ?
.res   rb 512
begin
        push    esi edi ebx

        stdcall GetCurrentDir
        mov     [.hRoot], eax

        stdcall StrPtr, eax
        mov     esi, eax

        mov     ecx, [esi+string.len]

        cmp     byte [esi+ecx-1], '\'
        je      @f

        stdcall StrCharCat, [.hRoot], '\'
        stdcall StrPtr, [.hRoot]
        mov     esi, eax

@@:

        stdcall GetFullPathNameUtf8, [.hFileName]
        mov     [.hName], eax

        stdcall StrPtr, eax
        mov     edi, eax

        cmp     [edi+string.len], 0
        je      .returnempty    ; there is invalid or missing filename.

        lea     edx, [.res]

; find first subdir
        mov     cl, ':'
        call    _CmpSubFolder
        jc      .copy                   ; Copy full path, because they are in different drives.

        mov     cl, '\'

        inc     esi
        inc     edi

.subloop:
        call    _CmpSubFolder
        jnc     .subloop

        dec     esi

; count of remaining subfolders.
.count:
        inc     esi
        mov     al, [esi]
        test    al,al
        je      .copy
        cmp     al,cl
        jne     .count
.found:
        mov     dword [edx], '..\'
        add     edx, 3
        test    al,al
        jnz     .count

.copy:
        mov     al, [edi]
        inc     edi
        mov     [edx], al
        inc     edx
        test    al,al
        jnz     .copy

        lea     edx, [.res]
        stdcall StrDupMem, edx

.finish:
        stdcall StrDel, [.hRoot]
        stdcall StrDel, [.hName]

        pop     ebx edi esi
        return

.returnempty:
        stdcall StrNew
        jmp     .finish
endp




proc _CmpSubFolder       ; esi - first, edi - second, cl - end char
begin
        xor     ebx, ebx

.scanloop:
        mov     al, [esi+ebx]
        test    al,al
        jz      .endofpath

        mov     ch, al
        mov     ah, [edi+ebx]
        or      ax, $2020
        cmp     al, ah
        jne     .notequal

        cmp     ch,cl
        je      .eosubdir

        inc     ebx
        jmp     .scanloop

.endofpath:
        cmp     byte [edi+ebx], cl
        jne     .notequal
        inc     edi
        add     edi, ebx
        add     esi, ebx
        xor     ebx, ebx
        stc
        return

.eosubdir:
        add     esi, ebx
        add     edi, ebx
        inc     esi
        inc     edi
        xor     ebx, ebx
        clc
        return

.notequal:
        stc
        return
endp

;----------------------------------------
; Returns an index to the filename
; separated from full path name.
; The original string remains unchanged
;----------------------------------------
proc ExtractFileName, .hPath
begin
        push    ebx ecx edx
        stdcall StrPtr, [.hPath]
        mov     ebx, eax
        mov     edx, eax
        xor     ecx, ecx
.loop:
        mov     cl, [edx]
        inc     edx
        jecxz   .end

        cmp     cl, '\'
        je      .dir
        cmp     cl, '/'
        jne     .loop
.dir:
        mov     eax, edx
        jmp     .loop

.end:
        sub     eax, ebx
        pop     edx ecx ebx
        return
endp





;----------------------------------------------------------
; Create an unique for the project filename of shape:
; <hPrefix>NNN<hSuffix> - where NNN is the mimimal number
; that makes the filename unique.
; Returns:
;   eax - handle to the new created filename.
;   edx - the NNN number.
;----------------------------------------------------------

proc CreateUniqueName, .hPrefix, .hSuffix
begin
        push    esi edi ebx

        xor     edx, edx
        inc     edx

        stdcall StrNew
        mov     esi, eax

; Create name
.findloop:
        stdcall StrCopy, esi, [.hPrefix]

        stdcall NumToStr, edx, ntsUnsigned or ntsDec
        stdcall StrCat, esi, eax
        stdcall StrDel, eax
        stdcall StrCat, esi, [.hSuffix]

        stdcall GetFullPathNameUtf8, esi
        mov     ebx, eax

        stdcall IsFileOpen, ebx
        test    eax, eax
        jz      .found

.nextloop:
        stdcall StrDel, ebx
        inc     edx
        jmp     .findloop

.found:
        stdcall StrDel, esi

        mov     eax, ebx

        pop     ebx edi esi
        return
endp



proc HashFilename, .hFileName
.str rb 1024
.ptr dd ?
begin
        stdcall GetFullPathNameUtf8, [.hFileName]
        push    eax

        stdcall StrLCase, eax
        stdcall StrHash, eax
        stdcall StrDel ; from the stack.
        return
endp




proc ChangeDir, .hFileName
begin
        stdcall GetFullPathNameUtf8, [.hFileName]
        mov     ecx, eax
        stdcall StrSplitFilename, ecx
        stdcall StrDel, eax

        stdcall SetCurrentDir, ecx
        stdcall StrDel, ecx

        return
endp