; ***************************************************************************
; 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_WIN_WIDGET_H
#define AQH_AVR_WIN_WIDGET_H



; ***************************************************************************
; defs



; ***************************************************************************
; code

.cseg



; ---------------------------------------------------------------------------
; @routine Widget_Init @global
;
; @param Y pointer to window SRAM
; @param X pointer to parent
; @param r18 OBJ options
; @param r19 WID_OFFS_OPTIONS1
; @param r20 WID_OFFS_OPTIONS2
; @clobbers r16, r17, X, Z

Widget_Init:
  push r19
    push r20
      push xl
        push xh
          ldi zl, LOW(Widget_Handler)  ; handler
          ldi zh, HIGH(Widget_Handler)
          rcall OBJ_Init                   ; (r16, r17, X)
        pop xh
      pop xl
    pop r20
  pop r19

  ; store options
  std Y+WID_OFFS_OPTIONS1, r19
  std Y+WID_OFFS_OPTIONS2, r20

  ; set basic handler
  ldi zl, LOW(Widget_Handler)  ; handler
  ldi zh, HIGH(Widget_Handler)
  rcall OBJ_SetHandler

  mov r16, xl
  or r16, xh
  breq Widget_noParent

  ; copy defaults from parent
  adiw xh:xl, WID_OFFS_BG_COL_LO
  ld r16, X+                       ; WID_OFFS_BG_COL_LO
  std Y+WID_OFFS_BG_COL_LO, r16
  ld r16, X+                       ; WID_OFFS_BG_COL_HI
  std Y+WID_OFFS_BG_COL_HI, r16
  ld r16, X+                       ; WID_OFFS_FG_COL_LO
  std Y+WID_OFFS_FG_COL_LO, r16
  ld r16, X+                       ; WID_OFFS_FG_COL_HI
  std Y+WID_OFFS_FG_COL_HI, r16
  ld r16, X+                       ; WID_OFFS_FONT_LO
  std Y+WID_OFFS_FONT_LO, r16
  ld r16, X+                       ; WID_OFFS_FONT_HI
  std Y+WID_OFFS_FONT_HI, r16
  rjmp Widget_end

Widget_noParent:               ; preset without parent
  clr r16
  std Y+WID_OFFS_FONT_LO, r16
  std Y+WID_OFFS_FONT_HI, r16
  
  std Y+WID_OFFS_FG_COL_LO, r16    ; foreground black
  std Y+WID_OFFS_FG_COL_HI, r16
  dec r16
  std Y+WID_OFFS_BG_COL_LO, r16    ; background white
  std Y+WID_OFFS_BG_COL_HI, r16
  
  ldi r16, 2                       ; default borders
  std Y+WID_OFFS_BORDER_TOP, r16
  std Y+WID_OFFS_BORDER_BOT, r16
  std Y+WID_OFFS_BORDER_LEFT, r16
  std Y+WID_OFFS_BORDER_RIGHT, r16
Widget_end:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine Widget_Handler @global
;
; Signal handler for an object. A signal can have up to 3 parameters
; conveyed in registers R18, R19 and X.
;
; @param Y pointer to object SRAM
; @param r18 signal
; @param r19 srcIdForTarget
; @param R20 1st param
; @param R21 2nd param
; @param X   3rd param
; @clobbers any, !Y

Widget_Handler:
  cpi r18, OBJ_SIGNAL_DESTROY
  breq Widget_Handler_destroy
  cpi r18, WID_SIGNAL_DRAW
  breq Widget_Handler_draw
  clc
  rjmp Widget_Handler_ret
Widget_Handler_destroy:
  ; nothing to do here (for HEAP objects we would call Heap_Free)
  rjmp Widget_Handler_secRet
Widget_Handler_draw:
  rcall Widget_Draw
Widget_Handler_secRet:
  sec
Widget_Handler_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine Widget_Draw @global
;
; @param Y pointer to object SRAM
; @clobbers

Widget_Draw:
  ldd r16, Y+OBJ_OFFS_OPTIONS
  sbrs r16,  WID_OPTIONS0_BIT_VISIBLE    ; only draw visible widgets
    rjmp widgetDraw_ret
  cbr r16, (1<<WID_OPTIONS0_BIT_DIRTY)
  std Y+OBJ_OFFS_OPTIONS, r16
  
  ; fill window background
  ldd r2,  Y+WID_OFFS_BG_COL_LO
  ldd r3,  Y+WID_OFFS_BG_COL_HI
  ldd r4,  Y+WID_OFFS_ABS_X_LO
  ldd r5,  Y+WID_OFFS_ABS_X_HI
  ldd r6,  Y+WID_OFFS_ABS_Y_LO
  ldd r7,  Y+WID_OFFS_ABS_Y_HI
  ldd r8,  Y+WID_OFFS_WIDTH_LO
  ldd r9,  Y+WID_OFFS_WIDTH_HI
  ldd r10, Y+WID_OFFS_HEIGHT_LO
  ldd r11, Y+WID_OFFS_HEIGHT_HI
  bigcall Display_FillRect
widgetDraw_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine Widget_SetAbsoluteCoords @global
;

Widget_SetAbsoluteCoords:
  push yl
    push yh
Widget_SetAbsoluteCoords_loop:
      ldd r18, Y+OBJ_OFFS_OPTIONS
      andi r18, WID_OPTIONS0_BIT_VISIBLE
      breq Widget_SetAbsoluteCoords_nextSibling
      push yl
        push yh
          bigcall Tree_GetParentObject
          clr r18
          clr r19
          clr r20
          clr r21
          mov r17, xl
          or r17, xh
          breq Widget_SetAbsoluteCoords_r1820set
          mov yl, xl
          mov yh, xh
          ldd r18, Y+WID_OFFS_ABS_X_LO
          ldd r19, Y+WID_OFFS_ABS_X_HI
          ldd r20, Y+WID_OFFS_ABS_Y_LO
          ldd r21, Y+WID_OFFS_ABS_Y_HI
Widget_SetAbsoluteCoords_r1820set:
        pop yh
      pop yl
      ; handle X
      ldd r16, Y+WID_OFFS_REL_X_LO
      ldd r17, Y+WID_OFFS_REL_X_HI
      add r16, r18
      adc r17, r19
      std Y+WID_OFFS_ABS_X_LO, r16
      std Y+WID_OFFS_ABS_X_HI, r17
      ; handle Y
      ldd r16, Y+WID_OFFS_REL_Y_LO
      ldd r17, Y+WID_OFFS_REL_Y_HI
      add r16, r20
      adc r17, r21
      std Y+WID_OFFS_ABS_Y_LO, r16
      std Y+WID_OFFS_ABS_Y_HI, r17
      bigcall Tree_GetObjectBelow
      rjmp Widget_SetAbsoluteCoords_loopEnd
Widget_SetAbsoluteCoords_nextSibling:
      bigcall Tree_GetNextSibling
Widget_SetAbsoluteCoords_loopEnd:
      mov r17, xl
      or r17, xh
      breq Widget_SetAbsoluteCoords_end
      mov yl, xl
      mov yh, xh
    rjmp Widget_SetAbsoluteCoords_loop
Widget_SetAbsoluteCoords_end:
    pop yh
  pop yl
  ret
; @end






#endif ; AQH_AVR_WIN_WIDGET_H


