;Макрос для вывода основных функций которые испльзуются боксом
macro use_general_func
{
;debug_func
;----------------------------------------------------------
;--- процедура прорисовки выделеной части -----------------
;----------------------------------------------------------
.draw_shift:
        test    word ed_flags,ed_shift_bac ;установка флага, выделенной области
        jz      @f
        mov     ebp,shift_color
        mov     ebx,dword       ed_shift_pos
        call    .sh_cl_
@@:     ret
;----------------------------------------------------------
;--- процедура прорисовки текста --------------------------
;----------------------------------------------------------
.draw_text:
;--- вычисляем, сколько помещается символов ---
;--- чтобы мусор не рисовать ---
        call    .get_n
        mov     esi,ed_size
        mov     ebx,ed_offset
        sub     esi,ebx
        cmp     eax,esi
        jae     @F
        mov     esi,eax         ;чтобы не выходить за пределы экрана
;--- рисуем текст ---                                            
@@:     mov     eax,4
        mov     ebx,ed_left
        mov     edx,ed_offset
        add     ebx,2
        shl     ebx,16
        add     ebx,ed_top
        mov     ecx,ed_text_color
        add     ebx,4
        add     edx,ed_text
        mcall
ret
;----------------------------------------------------------
;--- процедура прорисовки фона ----------------------------
;входные данные
;eax
;edx - color
;----------------------------------------------------------
;вход только цвет edx
.draw_bg:
        mov     ebx,ed_left
        add     ebx,1
        mov     edx,ed_color
        shl     ebx,16
        add     ebx,ed_width
        sub     ebx,1
.draw_bg_eax:
        mov     ecx,ed_top
        mov     eax,13
        add     ecx,1
        shl     ecx,16
        add     ecx,ed_height
        dec     ecx
        mcall   
ret
;----------------------------------------------------------
;--- процедура получения количества символов в текущей щирине компонента
;----------------------------------------------------------
.get_n:
        mov     eax,ed_width    ;получем ширину компонента
        xor     edx,edx   ;результат распологается в паре edx:eax в eax - остаток
        sub     eax,4           ;вычтим 4
        mov     ebx,6           ;загрузми делитель
        div     ebx             ;размделим на 6
ret
;----------------------------------------------------------
;--- процедура рисования курсора --------------------------
;----------------------------------------------------------
;входные ebp- цвет
.clear_cursor:
        mov     edx,ebp
        mov     ebx,cl_curs_x
        mov     ecx,cl_curs_y
        jmp     .draw_curs
.draw_cursor:
        mov     edx,ed_text_color
        mov     ebx,ed_pos
        mov     ecx,ed_offset
        sub     ebx,ecx

        lea     ebx,[ebx*2+ebx]
        shl     ebx,1
        ;imul   ebx,6
        add     ebx,ed_left
        mov     ecx,ed_top
        inc     ebx
        add     ecx,2
        mov     ebp,ebx
        shl     ebx,16
        mov     bx,bp
        mov     ebp,ecx
        
        shl     ecx,16
        mov     cx,bp
        add     ecx,ed_height-4
        
        mov     cl_curs_x,ebx
        mov     cl_curs_y,ecx
.draw_curs:              
        mcall   38
ret
;----------------------------------------------------------
;--- процедура рисования рамки ----------------------------
;----------------------------------------------------------
.draw_border:
;--- цвет рамки ---
        test    word ed_flags,ed_focus
        mov     edx,ed_focus_border_color
        jne     @f
        mov     edx,ed_blur_border_color
@@:
;--- сверху ---
        mov     eax,38
        mov     ebx,ed_left
        mov     ecx,ebx
        shl     ebx,16
        mov     bx,cx
        add     ebx,ed_width
        mov     ecx,ed_top
        mov     esi,ecx
        shl     ecx,16
        mov     cx,si
        mcall
;--- снизу ---
        mov     esi,ecx
        add     ecx,ed_height
        mov     ebp,ecx
        shl     ecx,16
        mov     cx,bp
        mcall
;--- слева ---
        mov     cx,si
        mov     ebp,ebx
        sub     ebx,ed_width
        mcall
;--- справа ---
        mov     ebx,ebp
        shl     ebx,16
        mov     bx,bp
        mcall
ret
;----------------------------------------------------------
;--- проверка, зашел ли курсор за границы и, если надо, ---
;--- изменяем смещение ------------------------------------
;--- если смещение было установка флага ed_offset_cl иначе
; если ничего не изменилось то выставление ed_offset_fl
; в общей битовой маррице состояния компонентов word ed_flags
;----------------------------------------------------------
.check_offset:
pusha
        mov     ecx,ed_pos
        mov     ebx,ed_offset
        cmp     ebx,ecx
        ja      .sub_8

        push    ebx
        call    .get_n                  ;получим кол-во символов в паре регистров edx:eax 
        pop     ebx
        mov     edx,ebx
        add     edx,eax         ;ed_offset+width editbox
        inc     edx             ;необходимо для номального положения курсора в крайней левой позиции
        cmp     edx,ecx
        ja      @f

        mov     edx,ed_size
        cmp     edx,ecx
        je      .add_end

        sub     edx,ecx
        cmp     edx,8
        jbe     .add_8
        add     ebx,8
        jmp     .chk_d

.sub_8: cmp     ecx,0
        je      .sub_min
        cmp     ebx,8
        jbe     .sub_min
        sub     ebx,8   ;ebx=ed_offset
        jmp     .chk_d
.sub_min:
        xor     ebx,ebx
        jmp     .chk_d

.add_end:sub    edx,eax
        mov     ebx,edx
        jmp     .chk_d
.add_8: add     ebx,edx
.chk_d: mov     ed_offset,ebx
        call    .draw_bg
        and     word ed_flags,ed_offset_cl
edit_ex
@@:
        or      word ed_flags,ed_offset_fl
edit_ex
}

macro use_key_func
{
;Обработка Shift для снятия выделения неизвестной области
.shift: ;;;;;;;SHIFT
        test    word ed_flags,ed_shift
        je      .f_exit

@@:     mov     ebp,shift_color
        or      word ed_flags,ed_shift_bac ;установка флага, выделенной области
        mov     ebx,dword       ed_shift_pos
        call    .sh_cl_
        jmp     .draw_cursor_text
;;;;;;;;;;;;;;;;;;;;;
.f_exit:call    .check_offset
        and     word ed_flags,ed_shift_cl
        call    .enable_null
        jmp     .draw_cursor_text
.sh_cl_:
;;;;;;SHIFT end
;обработка очистки, при левом - правом движении выделения
;для обработки снятия выделения
;входные параметры ebp=color ebx=ed_shift_pos
        mov     eax,dword       ed_pos
        cmp     eax,ebx

        jae     .sh_n
        push    eax  ;меньшее в eax
        push    ebx  ;большее
        jmp     .sh_n1
                     ;если иначе
.sh_n:  push    ebx  
        push    eax
.sh_n1: 
        call    .check_offset
        call    .get_n
        mov     edx,eax ;size of ed_box
        mov     ecx,ed_offset
        add     eax,ecx ;eax = w_off= ed_offset+width
        mov     edx,eax ;save
        pop     ebx     ;большее
        pop     eax     ;меньшее

        cmp     eax,ecx         ;сравнение с меньшего с offset.
        jae     .f_f            ;если больше
        xor     eax,eax
        cmp     edx,ebx         ;cравним размер w_off с большим
        jb      @f
        sub     ebx,ecx
        jmp     .nxt_f
@@:     mov     ebx,edx
        sub     ebx,ecx 
        jmp     .nxt_f
.f_f:   
        sub     eax,ecx
        cmp     edx,ebx         ;cравним размер w_off с большим
        jle     @f
        sub     ebx,ecx
        sub     ebx,eax
        jmp     .nxt_f
@@:
        mov     ebx,edx 
        sub     ebx,ecx
        sub     ebx,eax
.nxt_f:
        mov     edx,ebx
        lea     ebx,[eax*2+eax]
        shl     ebx,1
        add     ebx,ed_left
        inc     ebx
        shl     ebx,16
        lea     ecx,[edx*2+edx]
        shl     ecx,1   
        mov     bx,cx
        inc     ebx
        mov     edx,ebp;shift_color

        call    .draw_bg_eax
@@:     call    .enable_null
        ret
;;;;;;;;;;;;;;;;;;;;;
;Установка- снятие выделения в один символ
;;;;;;;;;;;;;;;;;;;;;
.drw_sim:
        mov     eax,dword       ed_pos
        call    .draw_rectangle   ;нарисовать прямоугольник с заданным цветом
        jmp     @b
;;;;;;;;;;;;;;;;;;;;;
;Фукция установки выделения при движения влево и вправо и нажатии shift
;Логика: 
;;;;;;;;;;
.draw_wigwag:
;функция установки переменных
        mov     ebp,shift_color
        call    .clear_cursor

        or      word ed_flags,ed_shift_bac ;установка флага, выделенной области
        mov     ebp,shift_color
        mov     eax,dword       ed_pos
        test    word ed_flags,ed_left_fl
        jz      .low
        jmp     @f
;;;;;;;;;;
;Фукция удаления выделения при движения влево и вправо и нажатии shift
;Логика: 
;;;;;;;;;;
.draw_wigwag_cl:
;функция установки переменных
        mov     ebp,ed_color
        call    .clear_cursor

        mov     ebp,ed_color
        mov     eax,dword       ed_pos
        test    word ed_flags,ed_left_fl
        jz      .low
@@:     call    .draw_rectangle  ;нарисовать прямоугольник закрашиваемой области
        ret
.low:   dec     eax
        jmp     @b
;входной параметр ebx - ed_pos
.sh_first_sh:
        test    word ed_flags,ed_shift
        je      @f
        mov     dword ed_shift_pos_old,ebx
        test    word ed_flags,ed_shift_on
        jne     @f
        mov     dword ed_shift_pos,ebx
        or      word ed_flags,ed_shift_on
@@:     ret
;Обработка крайних положений в editbox при нажатом shift
;производит снятие выделение, если нет shift
;иначе вообще выходит
.sh_st_of:
        test    word ed_flags,ed_shift
        jne     @f
        test    word ed_flags,ed_shift_bac
        je      @f
        mov     ebp,ed_color
        mov     ebx,dword       ed_shift_pos
        call    .sh_cl_  ;очистка выделеного фрагмента
        and     word ed_flags,ed_shift_cl ; очистка от того что убрали выделение 
        jmp     .draw_cursor_text
@@:
        and     word ed_flags,ed_shift_off
edit_ex
;проверка состояния shift был ли он нажат раньше?
.sh_enable:
        test    word ed_flags,ed_shift
        jne     .sh_ext_en ;нарисовать закрашеный прямоугольник

        test    word ed_flags,ed_shift_bac
        je      @f
        call    .check_offset

        mov     ebp,ed_color
        mov     ebx,dword       ed_shift_pos
        call    .sh_cl_  ;очистка выделеного фрагмента
        call    .draw_wigwag_cl 
        and     word ed_flags,ed_shift_cl ; 1вар не нужно 
        ret

@@:     mov     ebp,ed_color
        call    .clear_cursor
        call    .check_offset
        ret
.sh_ext_en:     
        call    .check_offset
        test    word ed_flags,ed_offset_fl
        je      @f
;Рисование закрашеных прямоугольников и очистка их
        mov     eax,dword       ed_shift_pos
        mov     ebx,dword       ed_pos
        mov     ecx,dword       ed_shift_pos_old
;проверка и рисование закрашеных областей
        cmp     eax,ecx
        je      .1_shem
        jb      .smaller
        cmp     ecx,ebx
        ja      .1_shem
        call    .draw_wigwag_cl ;clear
        jmp     .sh_e_end
.smaller:
        cmp     ecx,ebx
        jb      .1_shem
        call    .draw_wigwag_cl ;clear
        jmp     .sh_e_end
;alike  =
.1_shem: call   .draw_wigwag
.sh_e_end:      and     word ed_flags,ed_shift_off
        ret
@@:     mov     ebp,shift_color
        mov     ebx,dword       ed_shift_pos
        call    .sh_cl_
        jmp     .sh_e_end
;функция для обработки shift при нажатии home and end
.sh_home_end:
        mov     ebp,ed_color
        call    .clear_cursor
        test    word ed_flags,ed_shift_bac
        je      @f
        mov     ebp,ed_color
        mov     ebx,dword       ed_shift_pos_old
        call    .sh_cl_

@@:     test    word ed_flags,ed_shift
        je      .sh_exit_ ;выйти
        mov     ebp,shift_color
        mov     ebx,dword       ed_shift_pos
        call    .sh_cl_
        or      word ed_flags,ed_shift_bac ;установка флага, выделенной области
        jmp     .sh_e_end
.sh_exit_:      call    .check_offset
        ret
;функция внесения 0 по адресу ed_size+1
.enable_null:
        pusha
        mov     eax,ed_size
        mov     ebx,ed_text
        test    eax,eax
        add     eax,ebx
        jne     @f
        inc     eax
@@:     xor     ebx,ebx
        mov     [eax],bl
edit_ex
;- удаление символа
;Входные данные edx=ed_size;ecx=ed_pos
.del_char:
        mov     esi,ed_text
        test    word ed_flags,ed_shift_on
        je      @f
        mov     eax,dword ed_shift_pos
        mov     ebx,esi
        cmp     eax,ecx
        jae     .dh_n

        mov     ed_pos,eax      ;что бы не было убегания курсора
        mov     ebp,ecx
        sub     ebp,eax
        add     ebx,eax  ;eax меньше 
        sub     edx,ecx
        add     esi,ecx

        mov     dword ed_shift_pos,ebp
        jmp     .del_ch_sh
                     ;если иначе
.dh_n:  
        mov     ebp,eax
        sub     ebp,ecx
        add     ebx,ecx
        sub     edx,eax
        add     esi,eax
        mov     dword ed_shift_pos,ebp
        jmp     .del_ch_sh

@@:     add     esi,ecx ;указатель + смещение к реальному буфферу
        mov     ebx,esi
        inc     esi
        cld

        sub     edx,ecx
.del_ch_sh:

        push    edi
        mov     edi,ebx
@@:
        lodsb
        stosb
        dec edx
        jns @b
        
        pop edi
        ret
;вычислить закрашиваемую область
;соглашение в ebp - передается ed_size
.clear_bg:
        call    .get_n  ;получить размер в символах ширины компонента
        push    eax
        mov     ebx,ed_offset
        add     eax,ebx ;eax = w_off= ed_offset+width
        mov     ebx,ebp ;ed_size
        
        cmp     eax,ebx
        jb      @f
        mov     eax,ed_pos
        sub     ebx,eax
        mov     ecx,ed_offset
        sub     eax,ecx
        jmp     .nxt
@@:     mov     ebx,ed_pos
        push    ebx
        sub     eax,ebx
        mov     ebx,eax ;It is don't optimal
        
        pop     eax     ;ed_pos
        mov     ecx,ed_offset
        sub     eax,ecx
.nxt:
        mov     ebp,eax  ;проверка на выход закрашиваемой области за пределы длины
        add     ebp,ebx
        pop     edx
        cmp     ebp,edx
        je      @f
        inc     ebx

@@:     mov     edx,ebx
        lea     ebx,[eax*2+eax]
        shl     ebx,1
        add     ebx,ed_left
        inc     ebx
        shl     ebx,16
        lea     ecx,[edx*2+edx]
        shl     ecx,1   
        mov     bx,cx
        mov     edx,ed_color
        call    .draw_bg_eax
        ret
;;;;;;;;;;;;;;;;;;;
;;; Обработка примитивов
;;;;;;;;;;;;;;;;;;;;
;Нарисовать прямоугольник, цвет передается в ebp
;входные параметры:
;eax=dword ed_pos
;ebp=-цвет ed_color or shift_color 
.draw_rectangle:
        mov     ecx,dword ed_offset
        sub     eax,ecx
        lea     ebx,[eax*2+eax]
        shl     ebx,1
        inc     ebx
        add     ebx,ed_left
        shl     ebx,16
        add     ebx,6
        mov     edx,ebp
        call    .draw_bg_eax
        ret
;;;;;;;;;;;;;;;;;;
;;Проверка нажат ли shift
;;;;;;;;;;;;;;;;;;
.check_shift:
pusha   ;сохраним все регистры
        mcall   66,3
        test    al,0x03
        je      @f
        or      word ed_flags,ed_shift   ;установим флаг
@@:edit_ex
}
;макрос клавиш на которые происходит реакция 
macro use_key_process backspase,delete,left,right,home,end,insert
{
if backspase eq 
else
        cmp     ah,8
        jz      .backspace
end if
if delete eq 
else
        cmp     ah,0xb6
        jz      .delete
end if
if left eq 
else
        cmp     ah,176
        jz      .left
end if
if right eq 
else
        cmp     ah,179
        jz      .right
end if
if home eq 
else
        cmp     ah,180
        jz      .home
end if
if home eq 
else
        cmp     ah,181
        jz      .end
end if
if insert eq 
else
        cmp     ah,185  ;insert
        jz      .insert
end if
}
macro use_key_no_process  up,down,esc,enter,tab,numl,capsl,scrolll
{
if up eq 
else
        cmp     ah,177
        jz      edit_box.editbox_exit
end if
if down eq 
else
        cmp     ah,178
        jz      edit_box.editbox_exit
end if
if esc eq 
else
        cmp     ah,27   ;ESC - клавиша ))
        jz      edit_box.editbox_exit
end if
if enter eq 
else
        cmp     ah,13   ;ENTER - клавиша ))
        jz      edit_box.editbox_exit
end if
if tab eq 
else
        cmp     ah,9   ;TAB - клавиша ))
        jz      edit_box.editbox_exit
end if

if numl eq 
else
        cmp     ah,4   ;Num Lock - клавиша ))
        jz      edit_box.editbox_exit
end if

if capsl eq 
else
        cmp     ah,2   ;Caps Lock - клавиша ))
        jz      edit_box.editbox_exit
end if

if scrolll eq 
else
        cmp     ah,1   ;Scroll Lock - клавиша ))
        jz      edit_box.editbox_exit
end if

}

macro use_key_figures_only
{
        test    word ed_flags,ed_figure_only  ; только цифры ?
        jz      @f
        cmp     ah,'0'
        jb      .editbox_exit
        cmp     ah,'9'
        ja      .editbox_exit
@@:
}
macro are_key_shift_press
{
        test    word ed_flags,ed_shift_on
        je      @f
        ;Входные данные edx=ed_size;ecx=ed_pos
        push    eax
        mov     edx,ed_size
        mov     ecx, ed_pos
        pusha
;;;;;;;;;;;;;;;;;;;;;
;clear input arrea
        mov     ebp,ed_color
        mov     ebx,dword       ed_shift_pos
        call    .sh_cl_
        mov     ebp,ed_size
        call    .clear_bg
;;;;;;;;;;;;;;;;;;;;;
        popa 
        call    .del_char
;;;;
        mov     eax,dword ed_shift_pos
        mov     ebx,ed_size
        sub     ebx,eax
        mov     ed_size,ebx
        pop     eax
@@:
}
macro are_key_cur_end
{
        mov     ecx,ed_size
        mov     edx, ed_max
        test    word ed_flags,ed_insert
        jne     @f
        cmp     ecx,edx
        jae     .editbox_exit
@@:     mov     ebx, ed_pos
        cmp     ebx,edx
        jl      @f ; если меньше или равно
        jmp     .editbox_exit

@@:     ; сдвигаем символы после курсора вправо
        mov     ecx,ed_size
        push    edi eax
        mov     ebp,edi
        mov     esi,ed_text     ; Указатель на буфер
                                ;Будем работать со строкой
        add     esi,ecx         ;add ed_size добавим max size
        mov     edi,esi

        cmp     ecx,ebx         ;Если у нас позиция курсора = текущему размеру напечатанных символов т.е. курсор стоит в конце
        je      .In_k

        test    word [ebp+40],ed_insert ;IF insert is enable  т.к. edi изменен адресуем через ebp
        jne     .ins_v
;clear
pusha
        mov     edi,ebp
        mov     ebp,ed_size
        call    .clear_bg
popa
        sub     ecx,ebx         ;Найдем кол-во символов для передвижения.
        inc     edi             ;Сместим наши символы в право
        std
        inc     ecx
   @@:  
        ;--------
        lodsb
        stosb
        ;--------
        loop    @b
.In_k:  cld
        pop eax
        mov al,ah
        stosb
        pop edi
; вставляем код клавиши туда, где курсор
        ; увеличиваем значение размера и позиции
        inc      dword ed_size
        inc      dword ed_pos
        call    .draw_all2
        jmp     .shift
}
macro use_work_key
{
.insert: test   word ed_flags,ed_insert ;not    word ed_insert
         je     @f
         and    word ed_flags,ed_insert_cl
        jmp     .editbox_exit
@@:
        or      word ed_flags,ed_insert
        jmp     .editbox_exit
.ins_v:
        dec     dword [ebp+42];ed_size    ;processing is insert
        sub     esi,ecx
        add     esi,ebx
        mov     edi,esi
;clear
pusha
        mov     edi,ebp
        mov     ebp,ed_pos
        call    .clear_bg
popa
        jmp     .In_k
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.delete:        
        mov     edx,ed_size
        mov     ecx,ed_pos
        cmp     edx,ecx
        jg      .bac_del
        test    word ed_flags,ed_shift_on
        jne     .del_bac
edit_ex
.bac_del:       
        call    .del_char
        jmp     .draw_all
;;;;;;;;;;;;;;;;;;;;;;;;;;;;        
;--- нажата клавиша backspace ---
.backspace:
        ; проверяем, курсор у левого края ?
        mov     ecx,ed_pos
        test    ecx,ecx
        jnz     .del_bac
        test    word ed_flags,ed_shift_on
        jne     .bac_del

edit_ex
.del_bac:
        mov     edx,ed_size
        cmp     edx,ecx ;if ed_pos=ed_size
        je      @f
        dec     ecx
        call    .del_char
@@:     test    word ed_flags,ed_shift_on
        jne     .bac_del
        dec      dword ed_pos
.draw_all:
        push    .shift;.draw_cursor_text;eax

        test    word ed_flags,ed_shift_on
        je      @f
        mov     eax,dword ed_shift_pos
        mov     ebx,ed_size
        sub     ebx,eax
        mov     ed_size,ebx

        mov     ebp,ed_color
        call    .clear_cursor
        call    .check_offset
        call    .draw_bg
        ret
@@:     dec      dword ed_size

.draw_all2:
        and    word ed_flags,ed_shift_cl
        mov     ebp,ed_color
        call    .clear_cursor
        call    .check_offset
        mov     ebp,ed_size
        call    .clear_bg
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;--- нажата клавиша left ---
.left:  mov     ebx,ed_pos
        test    ebx,ebx
        jz      .sh_st_of
        or      word ed_flags,ed_left_fl
        call    .sh_first_sh
        dec      dword ed_pos
        call    .sh_enable
        jmp     .draw_cursor_text
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;--- нажата клавиша right ---
.right: mov     ebx,ed_pos
        cmp     ebx,ed_size
        je      .sh_st_of
        and     word ed_flags,ed_right_fl
        call    .sh_first_sh
        inc     dword  ed_pos
        call    .sh_enable
        jmp     .draw_cursor_text
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.home:  
        mov     ebx,ed_pos
        test    ebx,ebx
        jz      .sh_st_of
        call    .sh_first_sh
        xor     eax,eax
        mov     ed_pos,eax
        call    .sh_home_end
        jmp     .draw_cursor_text
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.end:   
        mov     ebx,ed_pos
        cmp     ebx,dword ed_size
        je      .sh_st_of
        call    .sh_first_sh
        mov     eax,ed_size
        mov     ed_pos,eax
        call    .sh_home_end
        jmp     .draw_cursor_text
}

macro use_mouse_func
{
;----------------------------------------------------------
;--- Обработка .mouse_wigwag
;----------------------------------------------------------
.mouse_wigwag:
        shr     eax,16
        or      word ed_flags,ed_shift_bac+ed_shift_on+ed_shift
;;;;;;;;;;;;;;;;;;
;;процедура обработки положения выделенного текста, когда происходит выход за пределы editbox
;;;;;;;;;;;;;;;;;;
        test    ax,0x8000
        jnz     .mleft

        mov     ebx,ed_left
        cmp     eax,ebx
        jb      .mleft

        add     ebx,ed_width
        cmp     eax,ebx
        ja      .mright 

        sub     ebx,ed_width

        xor     edx,edx
        sub     eax,ebx ; вычтим из координат мышки по оси х координаты до editbox по оси х
        mov     ebx,6
        div     ebx
;;;;;;;;;;;;;;;;;;
;;процедура обработки положения выделенного текста, в пределах области editbox
;;;;;;;;;;;;;;;;;;
;Получили координаты в eax мышки, т.е. куда она переместилась
;Рисование закрашеных прямоугольников и очистка их
        add     eax,ed_offset   ;добавим смещение
        cmp     eax,dword ed_size       ;если вышли за пределы, то ничего не делать
        ja      .mwigvag
.mdraw: 
        mov     dword   ed_pos,eax ;сохраним новое значение
;Рисование закрашеных прямоугольников и очистка их
        mov     ecx,dword       ed_shift_pos
        mov     ebx,dword       ed_shift_pos_old
        mov     dword   ed_shift_pos_old,eax    ;внесем новое значение старой позиции курсора
;проверка и рисование закрашеных областей
        cmp     ecx,ebx         ;выясняем куда было движение на один шаг назад
        je      .m1_shem        ;движения не было ранее 
        jb      .msmaller       ;движение было ->
        cmp     ebx,eax         ;движение было до этого <- и тут мы проверяем сейчас куда движение происходит
        ja      .m1_shem        ;если было движение <- то нужно закрасить область
        je      .mwigvag        ;если изменения не было, то ничего не делать
        mov     ebp,ed_color    ;тут нужно очистить область c ed_pos ed_shift_pos_old
;входные параметры ebp=color ebx=ed_shift_pos
        call    .sh_cl_
        jmp     .mwigvag
.msmaller:
        cmp     ebx,eax
        jb      .m1_shem
        mov     ebp,ed_color
;входные параметры ebp=color ebx=ed_shift_pos
        call    .sh_cl_
        jmp     .mwigvag
;alike  =
.m1_shem: 
        mov     ebp,shift_color
;входные параметры ebp=color ebx=ed_shift_pos
        mov     ebx,ecx
        call    .sh_cl_
        jmp     .mwigvag
.mwigvag:
        and     word ed_flags,ed_shift_mcl
        jmp     .draw_cursor_text
;       popa
;       ret
.mleft:

        mov     eax,ed_pos
        cmp     eax,0                                        
        jbe      .mwigvag
        dec     eax
        call    .check_offset
        push    eax
        mov     ebx,ed_shift_pos
        mov     ebp,shift_color
        call    .sh_cl_
        pop     eax
        jmp     .mdraw
.mright:
        mov     eax,ed_pos
        mov     ebx,ed_size
        cmp     eax,ebx
        jae     .mwigvag
        inc     eax
        call    .check_offset
        mov     ebx,ed_shift_pos
        mov     ebp,shift_color
        push    eax
        call    .sh_cl_
        pop     eax
        jmp     .mdraw  
}

macro use_work_mouse
;----------------------------------------------------------
;--- А не удерживаем ли мы клавишу мышки, перемещая курсор, во все разные стороны?
;----------------------------------------------------------
{
        test    word ed_flags,ed_mouse_on
        jne     .mouse_wigwag
;----------------------------------------------------------
;--- проверяем, попадает ли курсор в edit box -------------
;----------------------------------------------------------

        mov     ebx,ed_top
        cmp     ax,bx
        jl      ._blur;.mouse_end_no_focus
        
        add     ebx,ed_height
        cmp     ax,bx
        jg      ._blur;.mouse_end_no_focus

        shr     eax,16

        mov     ebx,ed_left
        cmp     ax,bx
        jl      ._blur;.mouse_end_no_focus

        add     ebx,ed_width

        cmp     ax,bx
        jg      ._blur;.mouse_end_no_focus        

;--- изменяем позицию курсора ---
        push    eax
        mov     ebp,ed_color
        call    .clear_cursor
        pop     eax
._mvpos:
      
        xor     edx,edx
        sub     eax,ed_left

        mov     ebx,6
        div     bx
        add     eax,ed_offset
        cmp     eax,ed_size
        jna     ._mshift
        mov     eax,ed_size
._mshift:
;;;;;;;
;;Секция обработки shift и выделения по shift
;;;;;;;
        test    word ed_flags,ed_shift_bac
        je      @f
        mov     ebp,dword       ed_color
        mov     ebx,dword ed_shift_pos
        push    eax
        call    .sh_cl_
        and     word ed_flags,ed_shift_bac_cl
        pop     eax
@@:     
        test    word ed_flags,ed_mouse_on
        jne     @f
        
        mov     dword ed_shift_pos,eax
        or      word  ed_flags,ed_mouse_on
        mov     dword ed_pos,eax
        mov     dword [mouse_flag],edi          ;установим идентификатор
        bts     word ed_flags,1                 ;установка фокуса
        jmp     .m_sh
@@:             
        cmp     eax,dword ed_shift_pos  ;если позиции не изменились
        je      .editbox_exit
        mov     ed_pos,eax
        mov     ebp,dword shift_color
        mov     ebx,dword ed_shift_pos
        call    .sh_cl_
        or      word ed_flags,ed_mous_adn_b     ;установим бит что мы выделили +shift_on +
.m_sh:  call    .draw_text
        call    .draw_cursor
;----------------------------------------------------------
;--- процедура установки фокуса ---------------------------
;----------------------------------------------------------
        jmp     .drc
._blur:
        test    word ed_flags,ed_always_focus
        jne     .editbox_exit
        btr     word ed_flags,1 ; если не в фокусе, выходим
        jnc     .editbox_exit

        mov     ebp,ed_color
        call    .clear_cursor
.drc:   call    .draw_border
        jmp     .editbox_exit
}


; Макрос выхода
macro edit_ex
{
popad          
ret
}
macro debug
{
        ;-----------  отладка
        pushad
;        mov     dword [ed_buffer.2],0
;        mov     eax,edi
        mov eax,dword [ed_buffer.2]
        mov edi,ed_buffer.3
        call .str
        ;рисование фона
        mov eax,13
        mov ebx,178*65536+70
        mov ecx,28*65536+10
        xor edx,edx
        int 0x40
        ;вывод значения на экран
        mov eax,4
        mov ebx,180*65536+30
        mov ecx,0x10DDBBCC
        mov edx,ed_buffer.3
        mov esi,8
        int 0x40
        popad
        ;----------- отладка
}
macro   debug_func
{
.str:
        mov ecx,0x0a ;задается система счисления изменяются регистры ebx,eax,ecx,edx входные параметры eax - число
         ;преревод числа в ASCII строку взодные данные ecx=система счисленя edi адрес куда записывать, будем строку, причем конец переменной 
        cmp eax,ecx  ;сравнить если в eax меньше чем в ecx то перейти на @@-1 т.е. на pop eax
        jb @f
        xor edx,edx  ;очистить edx
        div ecx      ;разделить - остаток в edx
        push edx     ;положить в стек
        ;dec edi             ;смещение необходимое для записи с конца строки
        call .str;перейти на саму себя т.е. вызвать саму себя и так до того момента пока в eax не станет меньше чем в ecx
        pop eax
        @@: ;cmp al,10 ;проверить не меньше ли значение в al чем 10 (для системы счисленя 10 данная команда - лишная))
        ;sbb al,$69  ;- честно данная инструкция меня заставляет задуматься т.е. я не знаю как это работает
        ;das        ;после данной команды как бы происходит уменьшение al на 66h  (в книге написано другое)
        or al,0x30  ;данная команда короче  чем две выше 
        stosb       ;записать элемент из регистра al в ячеку памяти es:edi
 
        ret         ;вернуться чень интересный ход т.к. пока в стеке храниться кол-во вызовов то столько раз мы и будем вызываться
}

;;;;;;;;;;;;;;;
;For LibGui
;;;;;;;;;;;;;;;
macro srt_ed_libgui
{
ed_width        equ [EditBox.ed_width]            ;ширина компонента
ed_left         equ [EditBox.ed_left]             ;положение по оси х
ed_top          equ [EditBox.ed_top]              ;положение по оси у
ed_color        equ [EditBox.ed_color]            ;цвет фона компонента
shift_color     equ [EditBox.shift_color]         ;=0x6a9480
ed_focus_border_color   equ [EditBox.ed_focus_border_color]   ;цвет рамки компонента
ed_blur_border_color    equ [EditBox.ed_blur_border_color]    ;цвет не активного компонента
ed_text_color   equ [EditBox.ed_text_color]       ;цвет текста
ed_max          equ [EditBox.ed_max]              ;кол-во символов которые можно максимально ввести
ed_text         equ [EditBox.ed_text]             ;указатель на буфер
ed_flags        equ [EditBox.ed_flags]            ;флаги
ed_size equ [EditBox.ed_size]                     ;кол-во символов
ed_pos  equ [EditBox.ed_poz]                      ;позиция курсора
ed_offset       equ [EditBox.ed_offset]           ;смещение
cl_curs_x       equ [EditBox.cl_curs_x]           ;предыдущее координата курсора по х
cl_curs_y       equ [EditBox.cl_curs_y]           ;предыдущее координата курсора по у
ed_shift_pos    equ [EditBox.ed_shift_pos]        ;положение курсора
ed_shift_pos_old equ [EditBox.ed_shift_pos_old]   ;старое положение курсора
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Bit mask from editbox 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ed_figure_only= 1000000000000000b   ;одни символы 
ed_always_focus= 100000000000000b
ed_focus=                     10b   ;фокус приложения
ed_shift_on=                1000b   ;если не установлен -значит впервые нажат shift,если был установлен, значит мы уже что - то делали удерживая shift
ed_shift_on_off=1111111111110111b
ed_shift=                    100b   ;включается при нажатии на shift т.е. если нажимаю
ed_shift_off=   1111111111111011b
ed_shift_bac=              10000b   ;бит для очистки выделеного shift т.е. при установке говорит что есть выделение
ed_shift_bac_cl=1111111111101111b   ;очистка при удалении выделения
ed_shift_cl=    1111111111100011b
ed_shift_mcl=   1111111111111011b
ed_left_fl=               100000b
ed_right_fl=    1111111111011111b
ed_offset_fl=            1000000b
ed_offset_cl=   1111111110111111b
ed_insert=              10000000b
ed_insert_cl=   1111111101111111b
ed_mouse_on =          100000000b
ed_mous_adn_b=         100011000b
ed_mouse_on_off=1111111011111111b
ed_height=14 ; высота
}