; ***************************************************************************
; copyright   : (C) 2025 by Martin Preuss
; email       : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome".                              *
; * Please see toplevel file COPYING of that project for license details.   *
; ***************************************************************************

#ifndef AQH_AVR_GUI_BUTTON_ASM
#define AQH_AVR_GUI_BUTTON_ASM


.equ BUTTON_STATE_DOWN_BIT      = 0
.equ BUTTON_STATE_ACTIVATED_BIT = 1



.cseg


; ---------------------------------------------------------------------------
; @routine Button_Draw_Up @global
;
; Draw button in state "UP".
;
; @param Y pointer to window in SDRAM
; @param Z pointer to button data in FLASH (byte address for LPM)
; @clobbers any, !Y

Button_Draw_Up:
  clr r14
  rjmp buttonDraw
; @end



; ---------------------------------------------------------------------------
; @routine Button_Draw_Down @global
;
; Draw button in state "DOWN".
;
; @param Y pointer to window in SDRAM
; @param Z pointer to button data in FLASH (byte address for LPM)
; @clobbers any, !Y

Button_Draw_Down:
  ldi r16, 1
  mov r14, r16
  rjmp buttonDraw
; @end



; ---------------------------------------------------------------------------
; @routine Button_HandleTouch @global
;
; @param  r18 flags
; @param  r19 current state of button (bit 0: pressed, bit 1: activated)
; @param  r5:r4 x
; @param  r7:r6 Y
; @param  Z     pointer to button data in FLASH
; @return r19 new state of button (0=normal, 1=pressed)

Button_HandleTouch:
  cbr r19, (1<<BUTTON_STATE_ACTIVATED_BIT)    ; clear activated bit
  ; check for press change event
  mov r17, r18
  andi r17, (1<<DISPLAY_IFLAGS_CHGPRESS_BIT)
  breq Button_HandleTouch_ret
  ; press changed
  mov r17, r18
  andi r17, (1<<DISPLAY_IFLAGS_PRESSED_BIT)
  breq Button_HandleTouch_up
  ; touch came down
  push zl
    push zh
      push r19
        bigcall Window_IsPointInRect
      pop r19
    pop zh
  pop zl
  brcc Button_HandleTouch_ret
  tst r19
  brne Button_HandleTouch_ret                         ; already down, jmp
  sbr r19, (1<<BUTTON_STATE_DOWN_BIT)                 ; button now down
  push zl
    push zh
      push r19
        rcall Button_Draw_Down
      pop r19
    pop zh
  pop zl
  rjmp Button_HandleTouch_ret
Button_HandleTouch_up:
  ; touch came up
  tst r19
  breq Button_HandleTouch_ret                         ; already up, jmp
  cbr r19, (1<<BUTTON_STATE_DOWN_BIT)
  push zl
    push zh
      push r19
        rcall Button_Draw_Up
      pop r19
    pop zh
  pop zl
  push zl
    push zh
      push r19
        bigcall Window_IsPointInRect
      pop r19
    pop zh
  pop zl
  brcc Button_HandleTouch_ret
  ; touch ended over button
  sbr r19, (1<<BUTTON_STATE_ACTIVATED_BIT)    ; set activated bit
Button_HandleTouch_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine buttonDraw
;
; @param Y pointer to window in SDRAM
; @param Z pointer to button data in FLASH (byte address for LPM)
; @param r14 0 if normal, 1 if pressed state
; @clobbers any, !Y

buttonDraw:
  lpm r4, Z+  ; X
  lpm r5, Z+
  lpm r6, Z+  ; Y
  lpm r7, Z+
  lpm r8, Z+  ; W
  lpm r9, Z+
  lpm r10, Z+ ; H
  lpm r11, Z+
  lpm r12, Z+ ; text
  lpm r13, Z+

  rcall buttonClearBackground
  rcall buttonDrawBorder
  rcall buttonDrawText

  ret
; @end




; ---------------------------------------------------------------------------
; @routine buttonClearBackground
;
; @param Y pointer to window in SDRAM
; @param r5:r4   X
; @param r7:r6   Y
; @param r9:r8   W
; @param r11:r10 H
; @param r14     0 if normal, 1 if pressed state
; @clobbers any, !Y, !Z

buttonClearBackground:
      tst r14
      brne buttonClearBackground_bgDown
      ldi r16, LOW(STYLE_BUTTON_COL_BG_NORM)
      mov r2, r16
      ldi r16, HIGH(STYLE_BUTTON_COL_BG_NORM)
      mov r3, r16
      rjmp buttonClearBackground_bgFill
buttonClearBackground_bgDown:
      ldi r16, LOW(STYLE_BUTTON_COL_BG_PRESSED)
      mov r2, r16
      ldi r16, HIGH(STYLE_BUTTON_COL_BG_PRESSED)
      mov r3, r16
buttonClearBackground_bgFill:
      bigcall Display_FillRect
  ret
; @end



; ---------------------------------------------------------------------------
; @routine buttonDrawBorder
;
; @param Y pointer to window in SDRAM
; @param r5:r4   X
; @param r7:r6   Y
; @param r9:r8   W
; @param r11:r10 H
; @param r14     0 if normal, 1 if pressed state
; @clobbers any, !Y, !Z

buttonDrawBorder:
  ldi r16, LOW(STYLE_BUTTON_COL_BORDER)
  mov r2, r16
  ldi r16, HIGH(STYLE_BUTTON_COL_BORDER)
  mov r3, r16
  bigcall Display_DrawRect
  ret
; @end



; ---------------------------------------------------------------------------
; @routine buttonDrawText
;
; @param Y pointer to window in SDRAM
; @param r5:r4   X
; @param r7:r6   Y
; @param r9:r8   W
; @param r11:r10 H
; @param r13:r12 Text in FLASH
; @param r14     0 if normal, 1 if pressed state
; @clobbers any, !Y, !Z

buttonDrawText:
  ldi r16, 2
  clr r17
  add r4, r16   ; x+=2
  adc r5, r17
  add r6, r16   ; y+=2
  adc r7, r17
  
  ; set text colors
  tst r14
  brne buttonDrawText_down
  ; set background color
  ldi r16, LOW(STYLE_BUTTON_COL_BG_NORM)
  mov r0, r16
  ldi r16, HIGH(STYLE_BUTTON_COL_BG_NORM)
  mov r1, r16
  ; set foreground color
  ldi r16, LOW(STYLE_BUTTON_COL_FG_NORM)
  mov r2, r16
  ldi r16, HIGH(STYLE_BUTTON_COL_FG_NORM)
  mov r3, r16
  rjmp buttonDrawText_draw
buttonDrawText_down:
  ; set background color
  ldi r16, LOW(STYLE_BUTTON_COL_BG_PRESSED)
  mov r0, r16
  ldi r16, HIGH(STYLE_BUTTON_COL_BG_PRESSED)
  mov r1, r16

  ; set foreground color
  ldi r16, LOW(STYLE_BUTTON_COL_FG_PRESSED)
  mov r2, r16
  ldi r16, HIGH(STYLE_BUTTON_COL_FG_PRESSED)
  mov r3, r16
buttonDrawText_draw:
  mov zl, r12
  mov zh, r13
  bigcall Window_DrawColorTextFlash
  ret
; @end




#endif
