;************************************************
;*          Menuet GUI Object Library           *
;************************************************
;------------------------------------------------------------------------------
;TEXTBOX Object(s)                                 starts at

  ;[x start]*65536 + [x size]                        0
  ;[y start]*65536 + [y size]                        4
  ;32 bit invisable button ID                        8
  ;32 bit backcolor 0x0e0e0e                         12
  ;32 bit cursor position in chars                   16
  ;32 bit cursor color                               20
  ;32 pointer to text length                         24
  ;pointer to begining of text 32 bytes              28
  ;max charachter length - controls cursor           32
  ;text color                                        36
  ;has focus 0=false anything else=true              40
  ;highlight data start and length in chars          44
TEXTBOX:
    ;eax =  0 or 1 or 2 or 3
    ;0 is creat a textbox and initialize positions and strings
    ;1 is do event based on key code sent in
    ;2 sets the textbox to be active or not
    ;3 highlights from char to char from a packed integer set
     ;EAX = 0
      ;edi = pointer to text box data block
      ;All are consecutive 32 bit chunks, no matter the size
      ;[x start]*65536 + [x size]
      ;[y start]*65536 + [y size]
      ;32 bit invisable button ID
      ;32 bit backcolor 0x0e0e0e
      ;32 bit cursor position in chars
      ;32 bit cursor color
      ;32 text length
      ;32 pointer to text
      ;32 max chars
      ;32 font/color of text
      ;32 focus
      ;32 highlight points
      ;ret: nothing
     ;EAX = 1
    ; ebx = keycode
    ; edi = pointer to text box data block
    ; ret: position of cursor in eax
     ;EAX = 2
    ; ebx = not focused = 0, focused >0
    ; edi = pointer to text box data block
    ; ret: nothing
     ;EAX = 3
    ; ebx = highlight start & length in a packed integer
    ; edi = address of textbox data
  ;SET LOCAL VARIABLES
  pusha
    ;set the event handle
    mov [eventhandle],eax

    mov eax,[edi+40]
    mov [myfocus],eax ;save focus

    mov eax,[edi+44]
    mov [highlight],eax ;save highlight

  popa
  ;HANDLER --------------
    cmp eax,0
    je tb_create
    cmp eax,1
    je tb_doevent
    cmp eax,2
    je tb_focus
    cmp eax,3
    je tb_highlight
    jmp tb_done ;if the command code is wrong just get outahere

  ;LOCAL DATA
  eventhandle dd -1
  myfocus     dd 1
  highlight   dd 0

  ;LOCAL METHODS --------------
  shiftback:
    ;push edi
    mov edx,edi
    mov edi,[edx+28] ;get address of string
    add edi,[edx+16] ;add to it the cursor position
    mov esi,edi            ;copy it to start position
    inc esi                ;inc the end position
    mov ecx,dword [edx+32] ;max char length
    add ecx,2 ;adjust 2 bigger
    ;mov ecx,43 - the above two lines replaced this
    sub ecx,[edx+16]
    cld
    rep movsb
    ;pop edi
    ret

  ;----------------------------

   tb_create: ;create a button with a cursor (and position var)

;     pusha
   drawstring:
      mov  eax,8     ;invisible button
      mov  ebx,[edi]  ;21*65536+258
      mov  ecx,[edi+4]  ;40*65536+15
      mov  edx,[edi+8]  ;0x40000002
      ;mov  esi,[txboxdata+12]
      int  0x40

      mov  eax,13      ;bar
      mov  edx,[edi+12] ;0xe0e0e0
      int  0x40

      cmp [highlight],0 ;highlight chars or not?
      je @f
        mov eax,[highlight]
        shr eax,16 ;cut off end point
        push ebx
        mov ebx,6
        mul ebx ;scale by char width
        pop ebx
        shl eax,16 ;slide back to start
        add ebx,eax ;add to start done by above bar
        mov eax,[highlight]
        shl eax,16 ;cut off start point
        shr eax,16 ;slide back
        push ebx
        mov ebx,6
        mul ebx ;scale by char width for end point
        pop ebx
        shr ebx,16 ;cut off old end point
        shl ebx,16
        add ebx,eax ;put on new end point
        mov eax,13
        mov edx,0x00006600 ;greener :P
        int 0x40
        mov [highlight],0 ;rest for nest textbox

      @@:
      cmp [myfocus],0 ;show the cursor or not?
      je @f
      push eax     ;cursor
      mov  eax,6*65536
      mul  dword [edi+16]
      mov  edx,[edi]; get the x offset + x size
      shr  edx,16 ;cut off the size
      shl  edx,16
      add  eax,edx ;word [txboxdata] ;X offset from [x start]*65536 +
      add  eax,6
      mov  ebx,eax
      pop  eax
      mov  edx,[edi+20] ;0x6a73d0
      int  0x40

      @@:
      mov  eax,4      ;path
      mov  edx,dword [edi]
      shr  edx,16 ;cut off the x size
      shl  edx,16
      mov  ebx,edx
      mov  edx,dword [edi+4]
      shr  edx,16 ;cut off the y size
      ;shl  edx,16
      add  ebx,edx
      add  ebx,3
      mov  ecx,[edi+36] ;path color
      cmp  [myfocus],0 ;fade the text?
      ja @f
      mov  ecx,0x00909090 ;make lighter - this can mess with font :/
      @@:
      mov  esi,edi
      add  esi,32 ;max size
      mov  esi,[esi]

      mov  edx,[edi+28] ;string pointer
      int  0x40
      ;popa

    jmp tb_done ;were done with create
    tb_doevent:
      mov [myfocus],1 ;sets focus to true.. we are doing stuff so...
      mov [edi+40],dword 1 ;sets focus to true in main data

      ;ebx will contain the textbox offset
      ;ecx will hold the key sent
      ; key
      mov eax,ecx

      cmp ah,19 ;ctrl+s moves selected start to cursor pos
      jne noctrls
      mov ax,[edi+16] ;get cursor pos
      mov [edi+46],ax ;damn little endian format >.<

      mov eax,[edi+44] ;put this in the start
      mov [highlight],eax
      call drawstring
      jmp tb_done
    noctrls:
      cmp ah,5 ;ctrl+e moves length up by 1
      jne noctrle
      inc dword [edi+44]
      mov eax,[edi+44]
      mov [highlight],eax
      call drawstring
      jmp tb_done
    noctrle:
      cmp ah,4 ;ctrl+d moves length down by 1
      jne noctrld
      mov eax,[edi+44]
      shl eax,16
      shr eax,16 ;cut off start
      cmp eax,0
      je @f
      dec dword [edi+44]
      mov eax,[edi+44]
      mov [highlight],eax
      @@:
      call drawstring
      jmp tb_done
    noctrld:
      cmp ah,181    ;this doesnt quite work... not sure why :/
      jne no_end
      mov eax,[edi+28] ;pointer of string
      dec eax ;behind first letter
      @@:
      inc eax ;next char
      cmp byte [eax],0 ;check for null char
      jne @b
      ;now we have the adress of the end of the string, sub from start addy
      mov ebx,[edi+28]
      sub eax,ebx ;end address - start address = offset
      ;now we have the difference in bytes
      mov [edi+16],ebx ;put that into the cursor pos
      call drawstring
      jmp tb_done
    no_end:
      cmp ah,180
      jne nohome
      mov [edi+16],dword 0
      call drawstring
      jmp tb_done
    nohome:
      cmp  ah,179 ;right?
      jne  noright
      mov  eax,[edi+16]
      mov  ebx, dword [edi+32] ;max char length
      sub  ebx,2 ;adjust
      cmp  eax,ebx       ;make sure cursor doesnt run off end
      ja tb_done ;eax is already cursor pos
      inc  eax
      mov  [edi+16],eax  ;mov cursor over to right
      call drawstring
      jmp  tb_done
    noright:
      cmp  ah,176 ;left?
      jne  noleft
      mov  eax,[edi+16]
      test eax,eax       ;make sure cursor doesnt run off begining
      je   tb_done
      dec  eax
      mov  [edi+16],eax
      call drawstring
      jmp  tb_done
    noleft:
      cmp  ah,182        ;del
      jne  nodelet
      push edi
      call shiftback
      pop  edi
      call drawstring
      jmp  tb_done
   nodelet:
      cmp  ah,8          ;zaboy
      jne  noback
      mov  eax,[edi+16]
      test eax,eax
      je   tb_done
      dec  eax
      mov  [edi+16],eax
      push edi
      call shiftback
      pop edi
      call drawstring
      jmp  tb_done
    noback:
      cmp  ah,13
      jne  noenter
    enter1:
     ; mov  al,byte ' '
     ; mov  edi,[edi+28]
      ;push edi
      ;mov  edi,edx
     ; mov  ecx,43
     ; cld
     ; repne scasb
     ; dec  edi
     ; mov  byte [edi],0
      jmp  tb_done
    noenter:
      cmp  ah,27
      jne  noesc
      jmp  tb_done
    noesc:
      mov  ebx,dword [edi+32] ;get max char length
      cmp  dword [edi+16],ebx ;upper limit of cursor
      jae  tb_done
      push edi
      push dword [edi+16] ;save the cursor pos cause we need edi
      mov  edi,[edi+28]
      add  edi,ebx ;end of string
      mov  esi,edi
      dec  esi
      mov  ecx,ebx ;add max length
      pop  ebx     ;got that cursor pos back
      sub  ecx,ebx ;[edi+16] now we can use ebx instead of [edi+16]
      std
      rep  movsb
      pop edi

     ;put in the pressed key
      shr  eax,8
      mov  esi,[edi+28]
      add  esi,[edi+16]
      mov  byte [esi],al
      inc  dword [edi+16]
      call drawstring
    jmp tb_done ;were done with the event handler

    tb_focus:
      ;ebx will contain the new focus value
      ;edi will be the text box data block address
      mov [myfocus],ebx
      mov [edi+40],ebx
      call drawstring
    jmp tb_done ;were done getting the string pointer and size
    tb_highlight:
      ;ebx will contain start and length chars
      ;edi will be the text box data block address
      mov [edi+44],ebx
      call drawstring
    jmp tb_done ;were done setting the string

    tb_done:	;we are done doing this textbox
    ;handle return values

    ;copy lower block to add more return values/last minute calcs,etc
    cmp [eventhandle],1
    jne @f
      mov eax,[edi+16]
        ;returns cursor position in eax
    ret

    @@:

    ret