;08.05.2009 - bugfix 
;14.04.2009 - a macros for code load library the box_lib.obj from '/sys/lib/' or current dirrectory.
; The macros for load any library/libraries:
; Copyright (c) 2009, <Lrz>
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
;       * Redistributions of source code must retain the above copyright
;       notice, this list of conditions and the following disclaimer.
;       * Redistributions in binary form must reproduce the above copyright
;       notice, this list of conditions and the following disclaimer in the
;       documentation and/or other materials provided with the distribution.
;       * Neither the name of the <organization> nor the
;       names of its contributors may be used to endorse or promote products
;       derived from this software without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY Alexey Teplov aka <Lrz> ''AS IS'' AND ANY
; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;*****************************************************************************
; This macros based on source code:
; <Lrz> - Alexey Teplov / Алексей Теплов
; Mario79, Mario - Marat Zakiyanov / Марат Закиянов
; Diamondz - Evgeny Grechnikov / Евгений Гречников
;------------------------
; DESCRIPTION
; Macro load_library
; Logick of work.
; A first time we must to check system path, where I belive find a system library. System path is "/sys/lib/".
; If I cannot found my library, i must to check second way. Second way is current dirrectory.
; If we cannot load library, we must show the error message:
; "I'm sorry,the programm cannot found system library box_lib.obj."
; "The find was make on 2 ways: /sys/lib/ and current dirrectory."
;
; 
;---------------------------------------------------------------------
; Macro sys_load_library
; A first time we must to check own path in current dirrectory the program, where I belive find a system library.
; If I cannot found my library, i must to check second way. Second way is system path a "/sys/lib/".
; If we cannot load library, we must show the error message:
; "I'm sorry,the programm cannot found system library box_lib.obj."
; "The find was make on 2 ways: /sys/lib/ and current dirrectory."
;
;---------------------------------------------------------------------
; How can I use it?
;---------------------------------------------------------------------
;-Example using single load library
;-universal load library/librarys
;load_library  library_name__, cur_dir_path__, library_path__, system_path__, \
;err_message_found_lib__, head_f_l__, myimport, err_message_import__, head_f_i__
;-if return code =-1 then exit, else normally work
;        cmp     eax,-1
;        jz      exit
;- Well, if you get 
;
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;DATA данные
;Всегда соблюдать последовательность в имени.
;system_path__      db '/sys/lib/'
;library_name__     db 'box_lib.obj',0
; Если есть желание разъединить, то нужно использовать следующию конструкцию
;system_path__      db '/sys/lib/box_lib.obj',0
;... любая последовательность других команд и определений.
;library_name__     db 'box_lib.obj',0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;err_message_found_lib__   db 'Sorry I cannot found library box_lib.obj',0
;head_f_i__:
;head_f_l__        db 'System error',0
;err_message_import__      db 'Error on load import library box_lib.obj',0

;myimport:   
;
;edit_box_draw   dd      aEdit_box_draw
;edit_box_key    dd      aEdit_box_key
;edit_box_mouse  dd      aEdit_box_mouse
;version_ed      dd      aVersion_ed
;
;check_box_draw  dd      aCheck_box_draw
;check_box_mouse dd      aCheck_box_mouse
;version_ch      dd      aVersion_ch
;
;option_box_draw  dd      aOption_box_draw
;option_box_mouse dd      aOption_box_mouse
;version_op       dd      aVersion_op

;                dd      0
;                dd      0
;
;aEdit_box_draw  db 'edit_box',0
;aEdit_box_key   db 'edit_box_key',0
;aEdit_box_mouse db 'edit_box_mouse',0
;aVersion_ed     db 'version_ed',0

;aCheck_box_draw  db 'check_box_draw',0
;aCheck_box_mouse db 'check_box_mouse',0
;aVersion_ch      db 'version_ch',0

;aOption_box_draw  db 'option_box_draw',0
;aOption_box_mouse db 'option_box_mouse',0
;aVersion_op       db 'version_op',0

;---------------------------------------------------------------------
macro @use_library
{

local __sc
local lp
local lp1
local correction
local exit_
;/equ
err_message1     equ    dword [esp+8]
head1            equ    dword [esp+4]


__sc.frame                equ  dword [__sc+0]
__sc.grab                 equ  dword [__sc+4]
__sc.grab_button          equ  dword [__sc+8]
__sc.grab_button_text     equ  dword [__sc+12] 
__sc.grab_text            equ  dword [__sc+16]
__sc.work                 equ  dword [__sc+20]
__sc.work_button          equ  dword [__sc+24]
__sc.work_button_text     equ  dword [__sc+28]
__sc.work_text            equ  dword [__sc+32]
__sc.work_graph           equ  dword [__sc+36]

;;;;;;;;;;;CALC WIDTH & HIGHT WINDOW & CENTER MONITOR POSITION;;;;;;;;;;
show_err_:
;check memory
        push    dword [arrea_xx]
        pop     eax
        test    eax,eax
        jnz     @f

        mcall   68,11
        mcall   68,12,4096
        push    eax
        pop     dword [arrea_xx]

        push    head1
        pop     dword[eax]

        push    0x0
        pop     dword[eax+4]

@@:
        mov     eax,48             ;get system color
        mov     ebx,3
        mov     ecx,__sc
        mov     edx,sizeof.system_colors
        mcall
;-----------------------------------
        xor     eax,eax
        mov     esi,err_message1
        mov     ecx,30
align 4
lp:     add     ecx,7
        lodsb
        test    eax,eax
        jnz     lp

        push    dword [arrea_xx]
        pop     ebp

align 4
@@:     add     ebp,4
        mov     eax,dword [ebp]

        test    eax,eax
        jnz     @b 

        push    err_message1
        pop     dword[ebp]

        mov     dword [ebp+4],eax

        mcall   48,5    ;get system window
        cmp     word[on_x],cx
        jae     @f; не нужно обновлять

        sub     eax,ecx
        shl     eax,15
        mov     ax,cx
        mov     dword [on_x],eax

@@:
        add     word [on_y],12
        sub     bx,word [on_y]
        shl     ebx,15
        mov     bx,word [on_y]
        mov     dword [on_y],ebx

        ret


;;;;;;;;;;;DRAW WINDOW;;;;;;;;;;;;;;
align 4
start__:
        mcall   40,0x5         ;set mask on events rewraw window and get id button.
.red_win:
;draw_window:
        mcall 12,1

        xor     eax,eax
        mov     ebp,dword [arrea_xx]      ; set point
        mov     ebx,dword [on_x]
        mov     ecx,dword [on_y]
        mov     edx,__sc.work
        or      edx,0x33000000
        mov     esi,__sc.grab_text
        xor     edi,edi
        mov     edi,dword [ebp]         ;head1
        mcall

        mov     ebx,(10*65536+25-12)
        add     ebp,4   ;inc index

@@:
        mov     eax,4
        add     bx,12
        mov     ecx,__sc.grab_text
        or      ecx,0x90000000
        mov     edx,dword [ebp]       ;err_message1
        mcall

        add     ebp,4   ;inc index

        mov     eax,dword [ebp]
        test    eax,eax
        jnz     @b

        mcall 12,2
align 4

.still:                          ;main loop
        mcall   10              ;wait event
        dec  eax
        jz   .red_win
        sub  eax,2
        jnz  .still   ;go to main loop
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.button:
        mcall   17      ;get id button
        test    ah,ah      ;if in ah 0, then go to still
        jz      .still
        mcall   -1
        ret

align 4
__sc     system_colors
on_x     dd     0x0
on_y     dd     0x0000004E
arrea_xx dd     0x0
rb      0x50
end_tr:

;---------------------------------------------------------------------

@library_name     equ    dword [esp+16]
@cur_dir_path     equ    dword [esp+12]
@library_path     equ    dword [esp+8]
@point_dir_name   equ    dword [esp+4]

align 4
@copy_path:
;        mov     ebx,@library_name
        mov     esi,@cur_dir_path
        mov     edi,@library_path

        xor     eax,eax
        cld
align 4
.lp1:
        lodsb
        stosb
        test    eax,eax
        jnz     .lp1
        mov     esi,edi

        std
align 4
.lp2:
        lodsb
        cmp     al,'/'
        jnz     .lp2
        mov     edi,esi

        add     edi,2
        cld
;	mov     esi,@library_name

	mov	esi,@point_dir_name
	test	esi,esi
	jz      .str_lp4

align 4
.lp3:
        lodsb
        stosb
        test    eax,eax
        jnz     .lp3


	dec 	edi
.str_lp4:
	mov     esi,@library_name
align 4
.lp4:
        lodsb
        stosb
        test    eax,eax
        jnz     .lp4
;--------------------------------------------------------------------- 
        ret
}



macro sys_load_library library_name__, cur_dir_path__, library_path__, system_path__, err_message_found_lib__, head_f_l__, myimport, err_message_import__, head_f_i__,point_dir_name__
{
local end_steep
local exit
;---------------------------------------------------------------------  
; loading Box_Lib library 

        mcall   68,19,system_path__   ; load of sys directory
        test    eax,eax
        jnz     end_steep 

if point_dir_name__ eq
  copy_path   library_name__, cur_dir_path__, library_path__,0x0
else
  copy_path   library_name__, cur_dir_path__, library_path__,point_dir_name__    ;the macros making way /current pach a program/+ name system library
end if 
        
        mcall   68,19,library_path__ ; load of alternative
        test    eax,eax
        jnz     end_steep
        show_error_window  err_message_found_lib__, head_f_l__    ;show error message /create window
        jmp     exit


align 4
end_steep:

        import_boxlib myimport, err_message_import__, head_f_i__  ;import
exit:
        test    eax,eax
        jz      @f

        mcall   51,1,start__,end_tr            ; создаем новый поток по шаблону
        or      eax,-1
@@:     

;---------------------------------------------------------------------
}


macro load_library library_name__, cur_dir_path__, library_path__, system_path__, err_message_found_lib__, head_f_l__, myimport, err_message_import__, head_f_i__,point_dir_name__
{
local end_steep
local exit
;---------------------------------------------------------------------  
; loading Box_Lib library 

if point_dir_name__ eq
  copy_path   library_name__, cur_dir_path__, library_path__,0x0
else
  copy_path   library_name__, cur_dir_path__, library_path__,point_dir_name__    ;the macros making way /current pach a program/+ name system library
end if 

        mcall   68,19,library_path__ ; load of alternative
        test    eax,eax
        jnz     end_steep 
        
        mcall   68,19,system_path__ ; load of sys directory
        test    eax,eax
        jnz     end_steep

        show_error_window  err_message_found_lib__, head_f_l__    ;show error message /create window
        jmp     exit

align 4
end_steep:

        import_boxlib myimport, err_message_import__, head_f_i__  ;import
exit:
        test    eax,eax
        jz      @f

        mcall   51,1,start__,end_tr            ; создаем новый поток по шаблону
        or      eax,-1
@@:     
        
;---------------------------------------------------------------------
}
macro sys_load_libraries _start,_end
{
local exit_lp2
local lp2
local lp
local end_steep
local next
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
library_name__            equ [ebp]
cur_dir_path__            equ [ebp+4]
library_path__            equ [ebp+8]
system_path__             equ [ebp+12]
err_message_found_lib__   equ [ebp+16]   
head_f_l__                equ [ebp+20]
my_import                 equ [ebp+24] 
err_message_import__      equ [ebp+28]
head_f_i__                equ [ebp+32]
point_dir_name__          equ [ebp+36]
adr_load_lib              equ dword [ebp+40]
status_lib                equ dword [ebp+44]

        mov     ebp,_start
        mov     ecx,((_end-_start)/ll_struc_size)

align 4
lp:     push    ecx
        mcall   68,19,system_path__   ; load of sys directory
        test    eax,eax
        jnz     end_steep 

        copy_path  library_name__, cur_dir_path__, library_path__,point_dir_name__     ;the macros making way /current pach a program/+ name system library
        
        mcall   68,19,library_path__ ; load of alternative
        test    eax,eax
        jnz     end_steep

        or      status_lib,0x1          ; status of code - enable error - not found library

        show_error_window  err_message_found_lib__, head_f_l__,    ;show error message /create window
        jmp      next

align 4
end_steep:
        mov     adr_load_lib,eax        ;save adr lib in memory
        import_boxlib my_import, err_message_import__, head_f_i__  ;import

        test    eax,eax
        jz      next

        or      status_lib,0x2          ; status of code - enable error - import error

next:
        pop     ecx
        add     ebp,ll_struc_size
        dec     ecx
        jnz     lp

;----------------------------------
        mov     ebp,_start
        mov     ecx,((_end-_start)/ll_struc_size)

align 4
lp2:
        mov     eax,status_lib
        test    eax,eax
        jz      @f

        mcall   51,1,start__,end_tr            ; создаем новый поток по шаблону
        or      eax,-1
        jmp     exit_lp2

@@:
        add     ebp,ll_struc_size
        dec     ecx
        jnz     lp2
exit_lp2:
}

macro load_libraries _start,_end
{
local lp2
local exit_lp2
local lp
local end_steep
local next
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
library_name__            equ [ebp]
cur_dir_path__            equ [ebp+4]
library_path__            equ [ebp+8]
system_path__             equ [ebp+12]
err_message_found_lib__   equ [ebp+16]   
head_f_l__                equ [ebp+20]
my_import                 equ [ebp+24] 
err_message_import__      equ [ebp+28]
head_f_i__                equ [ebp+32]
point_dir_name__          equ [ebp+36]
adr_load_lib              equ dword [ebp+40]
status_lib                equ dword [ebp+44]

        mov     ebp,_start
        mov     ecx,((_end-_start)/ll_struc_size)

align 4
lp:     push    ecx

        copy_path    library_name__, cur_dir_path__, library_path__,point_dir_name__   ;the macros making way /current pach a program/+ name system library

        mcall   68,19,library_path__  ; load of alternative
        test    eax,eax
        jnz     end_steep 
        
        mcall   68,19,system_path__   ; load of sys directory
        test    eax,eax
        jnz     end_steep

        or      status_lib,0x1          ; status of code - enable error - not found library

        show_error_window  err_message_found_lib__, head_f_l__    ;show error message /create window
        jmp      next

align 4
end_steep:
        mov     adr_load_lib,eax        ;save adr lib in memory

        import_boxlib my_import, err_message_import__, head_f_i__  ;import

        test    eax,eax
        jz      next

        or      status_lib,0x2          ; status of code - enable error - import error

next:
        pop     ecx
        add     ebp,ll_struc_size
        dec     ecx
        jnz     lp

;-----------------------------------------------
        mov     ebp,_start
        mov     ecx,((_end-_start)/ll_struc_size)

align 4
lp2:
        mov     eax,status_lib
        test    eax,eax
        jz      @f

        mcall   51,1,start__,end_tr            ; создаем новый поток по шаблону
        or      eax,-1
        jmp     exit_lp2

@@:
        add     ebp,ll_struc_size
        dec     ecx
        jnz     lp2
exit_lp2:

}


macro copy_path lib_name,dir_path,lib_path,point_dir_name
{
        pushad  ;save all registers
        push    dword lib_name
        push    dword dir_path
        push    dword lib_path
        push	dword point_dir_name
        call    @copy_path

        add     esp,16
        popad   ;restore all registers
}

macro show_error_window  err_message, head
{       pushad  ;save all registers
        push    dword err_message
        push    dword head

        call    show_err_

        add     esp,8
        popad   ;restore all registers
        or      eax,-1  ;увы
}


macro import_boxlib myimport, err_message_import__, head_f_i__
{
local import_loop
local import_find
local lp
local import_find_next
local import_found
local import_done
local exit
local e.exit
local import_not_found
; initialize import
        
        mov     edx, eax
        mov     esi,myimport
import_loop:
        lodsd
        test    eax, eax
        jz      import_done
        push    edx
import_find:
        mov     ebx, [ds:edx]
        test    ebx, ebx
        jz      import_not_found
        push    eax
lp:
        mov     cl, [ds:eax]
        cmp     cl, [ds:ebx]
        jnz     import_find_next
        test    cl, cl
        jz      import_found
        inc     eax
        inc     ebx
        jmp     lp
import_find_next:
        pop     eax
        add     edx, 8
        jmp     import_find
import_found:
        pop     eax
        mov     eax, [ds:edx+4]
        mov     [esi-4], eax
        pop     edx
        jmp     import_loop
import_not_found:
        add     esp,4
        show_error_window  err_message_import__, head_f_i__    ;show error message /create window
        jmp     e.exit
import_done:
        xor     eax,eax
e.exit: 
;---------------------------------------------------------------------
}
ll_struc_size = 48;($-library_name__)    ; constant   size of struct
struc l_libs library_name__, cur_dir_path__, library_path__, system_path__, err_message_found_lib__, head_f_l__, my_import, err_message_import__, head_f_i__,point_dir_name; struct for loading libraries
{        
.library_name__           dd library_name__        ; имя загружаемой библиотеки
.cur_dir_path__           dd cur_dir_path__        ; указатель на буфер в котором содержиться путь от куда была запущена программа
                        
.library_path__           dd library_path__        ; указатель на буфер в котором будет софоримирован путь к библиотеки, если нужно вычислить путь до либы с места запуска программы, обычно нужно, в случаях, если либа расположена в той же папке
.complete_path            dd system_path__         ; путь который четко содержит путь

.err_message_found_lib__  dd err_message_found_lib__
.head_f_l__               dd head_f_l__
.my_import                dd my_import
.err_message_import__     dd err_message_import__
.head_f_i__               dd head_f_i__
if point_dir_name eq
.point_dir_name__	dd 0x0
else
.point_dir_name__	dd point_dir_name	   ; имя вложенной дирректории в кторой храняться подгружаемые модули.
end if 
.adr_load_lib           dd 0x0
.status_lib             dd 0x0          ;status of load library
;
}
