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

;----------------------------------------------------------
;--- процедура получения количества символов в текущей щирине компонента
;----------------------------------------------------------
.get_n:
        mov     eax,[EditBox.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,[EditBox.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,[EditBox.ed_left]
        mov     ecx,[EditBox.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 [EditBox.ed_flags],ed_focus
        mov     edx,[EditBox.ed_focus_border_color]
        jne     @f
        mov     edx,[EditBox.ed_blur_border_color]
@@:
;--- сверху ---
        mov     eax,38
        mov     ebx,[EditBox.ed_left]
        mov     ecx,ebx
        shl     ebx,16
        mov     bx,cx
        add     ebx,[EditBox.ed_width]
        mov     ecx,[EditBox.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,[EditBox.ed_width]
        mcall
;--- справа ---
        mov     ebx,ebp
        shl     ebx,16
        mov     bx,bp
        mcall
ret
;----------------------------------------------------------
;--- проверка, зашел ли курсор за границы и, если надо, ---
;--- изменяем смещение ------------------------------------
;--- если смещение было установка флага ed_offset_cl иначе
; если ничего не изменилось то выставление ed_offset_fl
; в общей битовой маррице состояния компонентов word [EditBox.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,[EditBox.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 [EditBox.ed_flags],ed_offset_cl
edit_ex
@@:
        or      word [EditBox.ed_flags],ed_offset_fl
edit_ex
}

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

@@:     mov     ebp,[EditBox.shift_color]
        or      word [EditBox.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 [EditBox.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,[EditBox.ed_left]
        inc     ebx
        shl     ebx,16
        lea     ecx,[edx*2+edx]
        shl     ecx,1
        mov     bx,cx
        inc     ebx
        mov     edx,ebp;[EditBox.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,[EditBox.shift_color]
        call    .clear_cursor

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

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

        test    word [EditBox.ed_flags],ed_shift_bac
        je      @f
        call    .check_offset

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

@@:     mov     ebp,[EditBox.ed_color]
        call    .clear_cursor
        call    .check_offset
        ret
.sh_ext_en:
        call    .check_offset
        test    word [EditBox.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 [EditBox.ed_flags],ed_shift_off
        ret
@@:     mov     ebp,[EditBox.shift_color]
        mov     ebx,dword       ed_shift_pos
        call    .sh_cl_
        jmp     .sh_e_end
;функция для обработки shift при нажатии home and end
.sh_home_end:
        mov     ebp,[EditBox.ed_color]
        call    .clear_cursor
        test    word [EditBox.ed_flags],ed_shift_bac
        je      @f
        mov     ebp,[EditBox.ed_color]
        mov     ebx,dword       ed_shift_pos_old
        call    .sh_cl_

@@:     test    word [EditBox.ed_flags],ed_shift
        je      .sh_exit_ ;выйти
        mov     ebp,[EditBox.shift_color]
        mov     ebx,dword       ed_shift_pos
        call    .sh_cl_
        or      word [EditBox.ed_flags],ed_shift_bac ;установка флага, выделенной области
        jmp     .sh_e_end
.sh_exit_:      call    .check_offset
        ret
;функция внесения 0 по адресу [EditBox.ed_size]+1
.enable_null:
        pusha
        mov     eax,[EditBox.ed_size]
        mov     ebx,[EditBox.ed_text]
        test    eax,eax
        add     eax,ebx
        jne     @f
        inc     eax
@@:     xor     ebx,ebx
        mov     [eax],bl
edit_ex
;- удаление символа
;Входные данные edx=[EditBox.ed_size];ecx=ed_pos
.del_char:
        mov     esi,[EditBox.ed_text]
        test    word [EditBox.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 - передается [EditBox.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 ;[EditBox.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,[EditBox.ed_left]
        inc     ebx
        shl     ebx,16
        lea     ecx,[edx*2+edx]
        shl     ecx,1
        mov     bx,cx
        mov     edx,[EditBox.ed_color]
        call    .draw_bg_eax
        ret
;;;;;;;;;;;;;;;;;;;
;;; Обработка примитивов
;;;;;;;;;;;;;;;;;;;;
;Нарисовать прямоугольник, цвет передается в ebp
;входные параметры:
;eax=dword ed_pos
;ebp=-цвет [EditBox.ed_color] or [EditBox.shift_color]
.draw_rectangle:
        mov     ecx,dword ed_offset
        sub     eax,ecx
        lea     ebx,[eax*2+eax]
        shl     ebx,1
        inc     ebx
        add     ebx,[EditBox.ed_left]
        shl     ebx,16
        add     ebx,6
        mov     edx,ebp
        call    .draw_bg_eax
        ret
;;;;;;;;;;;;;;;;;;
;;Проверка нажат ли shift
;;;;;;;;;;;;;;;;;;
.check_shift:
pusha   ;сохраним все регистры
        mcall   66,3,1
        test    al,0x03
        je      @f
        or      word [EditBox.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
{
if up eq
else
        cmp     ah,177
        jz      .editbox_exit
end if
if down eq
else
        cmp     ah,178
        jz      .editbox_exit
end if
if esc eq
else
        cmp     ah,27   ;ESC - клавиша ))
        jz      .editbox_exit
end if
}

macro use_key_figures_only
{
        test    word [EditBox.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 [EditBox.ed_flags],ed_shift_on
        je      @f
        ;Входные данные edx=[EditBox.ed_size];ecx=ed_pos
        push    eax
        mov     edx,[EditBox.ed_size]
        mov     ecx, ed_pos
        pusha
;;;;;;;;;;;;;;;;;;;;;
        mov     ebp,[EditBox.ed_color]
        mov     ebx,dword       ed_shift_pos
        call    .sh_cl_
;;;;;;;;;;;;;;;;;;;;;
        popa
        call    .del_char
;;;;
        mov     eax,dword ed_shift_pos
        mov     ebx,[EditBox.ed_size]
        sub     ebx,eax
        mov     [EditBox.ed_size],ebx
        pop     eax
@@:
}
macro are_key_cur_end
{
        mov     ecx,[EditBox.ed_size]
        mov     edx, [EditBox.ed_max]
        test    word [EditBox.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,[EditBox.ed_size]
        push    edi eax
        mov     ebp,edi
        mov     esi,[EditBox.ed_text]     ; Указатель на буфер
                                ;Будем работать со строкой
        add     esi,ecx         ;add [EditBox.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,[EditBox.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 [EditBox.ed_size]
        inc      dword ed_pos
        call    .draw_all2
        jmp     .shift
}
macro use_work_key
{
.insert: test   word [EditBox.ed_flags],ed_insert ;not    word ed_insert
         je     @f
         and    word [EditBox.ed_flags],ed_insert_cl
        jmp     .editbox_exit
@@:
        or      word [EditBox.ed_flags],ed_insert
        jmp     .editbox_exit
.ins_v:
        dec     dword [ebp+42];[EditBox.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,[EditBox.ed_size]
        mov     ecx,ed_pos
        cmp     edx,ecx
        jg      .bac_del
        test    word [EditBox.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 [EditBox.ed_flags],ed_shift_on
        jne     .bac_del

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

        test    word [EditBox.ed_flags],ed_shift_on
        je      @f
        mov     eax,dword ed_shift_pos
        mov     ebx,[EditBox.ed_size]
        sub     ebx,eax
        mov     [EditBox.ed_size],ebx

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

.draw_all2:
        and    word [EditBox.ed_flags],ed_shift_cl
        mov     ebp,[EditBox.ed_color]
        call    .clear_cursor
        call    .check_offset
        mov     ebp,[EditBox.ed_size]
        call    .clear_bg
        ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;--- нажата клавиша left ---
.left:  mov     ebx,ed_pos
        test    ebx,ebx
        jz      .sh_st_of
        or      word [EditBox.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,[EditBox.ed_size]
        je      .sh_st_of
        and     word [EditBox.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 [EditBox.ed_size]
        je      .sh_st_of
        call    .sh_first_sh
        mov     eax,[EditBox.ed_size]
        mov     ed_pos,eax
        call    .sh_home_end
        jmp     .draw_cursor_text
}

macro use_mouse_func scr_w
{
;----------------------------------------------------------
;--- Обработка .mouse_wigwag
;----------------------------------------------------------
.mouse_wigwag:
        shr     eax,16
        or      word [EditBox.ed_flags],ed_shift_bac+ed_shift_on+ed_shift
;;;;;;;;;;;;;;;;;;
;;процедура обработки положения выделенного текста, когда происходит выход за пределы editbox
;;;;;;;;;;;;;;;;;;
        ;mov     ebx,[IPC_table.box.left]
        mov     ebx,[EditBox.ed_left]
;if scr_w eq
;else
;        add     ebx,dword scr_w
;end if
        cmp     eax,ebx
        jb      .mleft

        add     ebx,[EditBox.ed_width]
        cmp     eax,ebx
        ja      .mright

        sub     ebx,[EditBox.ed_width]

        xor     edx,edx
        sub     eax,ebx ; вычтим из координат мышки по оси х координаты до editbox по оси х
        mov     ebx,6
        div     ebx
;;;;;;;;;;;;;;;;;;
;;процедура обработки положения выделенного текста, в пределах области editbox
;;;;;;;;;;;;;;;;;;
;Получили координаты в eax мышки, т.е. куда она переместилась
;Рисование закрашеных прямоугольников и очистка их
        add     eax,ed_offset   ;добавим смещение
        cmp     eax,dword [EditBox.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,[EditBox.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,[EditBox.ed_color]
;входные параметры ebp=color ebx=ed_shift_pos
        call    .sh_cl_
        jmp     .mwigvag
;alike  =
.m1_shem:
        mov     ebp,[EditBox.shift_color]
;входные параметры ebp=color ebx=ed_shift_pos
        mov     ebx,ecx
        call    .sh_cl_
        jmp     .mwigvag
.mwigvag:
        and     word [EditBox.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,[EditBox.shift_color]
        call    .sh_cl_
        pop     eax
        jmp     .mdraw
.mright:
        mov     eax,ed_pos
        mov     ebx,[EditBox.ed_size]
        cmp     eax,ebx
        jae     .mwigvag
        inc     eax
        call    .check_offset
        mov     ebx,ed_shift_pos
        mov     ebp,[EditBox.shift_color]
        push    eax
        call    .sh_cl_
        pop     eax
        jmp     .mdraw
}

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

        mov     eax,[EditBox.ed_left]
        mov     ebx,[EditBox.ed_top]
        mov     ecx,[EditBox.ed_width]
        mov     edx,[EditBox.ed_height]
        mov     esi,[EditBox.mouseX]
        mov     edi,[EditBox.mouseY]

        call CheckCrossingBox

        cmp eax,0xffffff
        jne ._blur

;if scr_h eq
;else
;        add     ebx,scr_h
;end if
        ;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,[IPC_table.box.left]
        ;add     ebx,[EditBox.ed_left]
;if scr_w eq
;else
;        add     ebx,scr_w
;end if
        ;cmp     ax,bx
        ;jl      ._blur;.mouse_end_no_focus

        ;add     ebx,[EditBox.ed_width]
        ;cmp     ax,bx
        ;jg      ._blur;.mouse_end_no_focus

        ;mov eax,[EditBox.mouseX]

;--- изменяем позицию курсора ---
        ;push    eax
        mov     ebp,[EditBox.ed_color]
        call    .clear_cursor
        ;pop     eax
        mov eax,[EditBox.mouseX]
._mvpos:
        ;mov     ebx,dword [IPC_table.box.left]
        xor     edx,edx
        sub     eax,[EditBox.ed_left]
        ;sub     eax,ebx
;if scr_w eq
;else
;        add     ebx,scr_w
;        sub     eax,2
;end if
        mov     ebx,6
        div     bx
        add     eax,ed_offset
        cmp     eax,[EditBox.ed_size]
        jna     ._mshift
        mov     eax,[EditBox.ed_size]
._mshift:
;;;;;;;
;;Секция обработки shift и выделения по shift
;;;;;;;
        test    word [EditBox.ed_flags],ed_shift_bac
        je      @f
        mov     ebp,dword [EditBox.ed_color]
        mov     ebx,dword ed_shift_pos
        push    eax
        call    .sh_cl_
        and     word [EditBox.ed_flags],ed_shift_bac_cl
        pop     eax
@@:
        test    word [EditBox.ed_flags],ed_mouse_on
        jne     @f

        mov     dword ed_shift_pos,eax
        or      word  [EditBox.ed_flags],ed_mouse_on
        mov     dword ed_pos,eax
        ;mov     dword [mouse_flag],edi          ;установим идентификатор
        bts     word [EditBox.ed_flags],1                 ;установка фокуса
        jmp     .m_sh
@@:
        cmp     eax,dword ed_shift_pos  ;если позиции не изменились
        je      .editbox_exit
        mov     ed_pos,eax
        mov     ebp,dword [EditBox.shift_color]
        mov     ebx,dword ed_shift_pos
        call    .sh_cl_
        or      word [EditBox.ed_flags],ed_mous_adn_b     ;установим бит что мы выделили +shift_on +
.m_sh:  call    .draw_text
        call    .draw_cursor
;----------------------------------------------------------
;--- процедура установки фокуса ---------------------------
;----------------------------------------------------------
        jmp     .drc
._blur:
        test    word [EditBox.ed_flags],ed_always_focus
        jne     .editbox_exit
        btr     word [EditBox.ed_flags],1 ; если не в фокусе, выходим
        jnc     .editbox_exit

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


; Макрос выхода
macro edit_ex
{
popa
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
{
;[EditBox.ed_width]        equ [EditBox.ed_width]            ;ширина компонента
;[EditBox.ed_left]         equ [EditBox.ed_left]             ;положение по оси х
;[EditBox.ed_top]          equ [EditBox.ed_top]              ;положение по оси у
;[EditBox.ed_color]        equ [EditBox.ed_color]            ;цвет фона компонента
;[EditBox.shift_color]     equ [EditBox.shift_color]         ;=0x6a9480
;[EditBox.ed_focus_border_color]   equ [EditBox.ed_focus_border_color]   ;цвет рамки компонента
;[EditBox.ed_blur_border_color]    equ [EditBox.ed_blur_border_color]    ;цвет не активного компонента
;[EditBox.ed_text_color]   equ [EditBox.ed_text_color]       ;цвет текста
;[EditBox.ed_max]          equ [EditBox.ed_max]              ;кол-во символов которые можно максимально ввести
;[EditBox.ed_text]         equ [EditBox.ed_text]             ;указатель на буфер
;[EditBox.ed_flags]        equ [EditBox.ed_flags]            ;флаги
;[EditBox.ed_size] equ [EditBox.ed_size]                     ;кол-во символов
ed_pos  equ [EditBox.ed_pos]                      ;позиция курсора
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 ; высота
}