; ***************************************************************************
; copyright   : (C) 2026 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_IMGLABEL_ASM
#define AQH_AVR_GUI_IMGLABEL_ASM


; ***************************************************************************
; TODO
; ***************************************************************************




; ***************************************************************************
; defines

.equ IMGLABEL_OFFS_BEGIN      =  WIDGET_SIZE
.equ IMGLABEL_OFFS_IMGRES_LO  =  IMGLABEL_OFFS_BEGIN+0
.equ IMGLABEL_OFFS_IMGRES_HI  =  IMGLABEL_OFFS_BEGIN+1
.equ IMGLABEL_OFFS_TXTRES_LO  =  IMGLABEL_OFFS_BEGIN+2
.equ IMGLABEL_OFFS_TXTRES_HI  =  IMGLABEL_OFFS_BEGIN+3
.equ IMGLABEL_OFFS_USER_LO    =  IMGLABEL_OFFS_BEGIN+4
.equ IMGLABEL_OFFS_USER_HI    =  IMGLABEL_OFFS_BEGIN+5
.equ IMGLABEL_SIZE            =  IMGLABEL_OFFS_BEGIN+6





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

.cseg



; ---------------------------------------------------------------------------
; @routine ImgLabel_new @global
;
; @return CFLAG set of okay, cleared otherwise
; @return Y address of newly created object
; @param X parent widget
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r21:r20 img ressource id
; @param r23:r22 txt ressource id
; @clobbers any

ImgLabel_new:
  push r20
    push r21
      push r22
        push r23
          ldi r24, LOW(IMGLABEL_SIZE)
          ldi r25, HIGH(IMGLABEL_SIZE)
          bigcall Object_Alloc           ; (!r16, !r17, !X)
        pop r23
      pop r22
    pop r21
  pop r20
  brcc ImgLabel_new_ret
  rcall ImgLabel_Init               ; (r16, r17, X)
  sec
ImgLabel_new_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine ImgLabel_Init @global
;
; @param Y address of widget
; @param X parent widget (if any)
; @param r16 value for OBJECT_OFFS_OPTS
; @param r17 value for WIDGET_OFFS_PACK
; @param r21:r20 img ressource id
; @param r23:r22 txt ressource id
; @clobbers r16, r17, X

ImgLabel_Init:
  push r20
    push r21
      push r22
        push r23
          ; call base class
          bigcall Widget_Init
        pop r23
      pop r22
    pop r21
  pop r20
  brcc ImgLabel_Init_ret
  ; save params
  std Y+IMGLABEL_OFFS_IMGRES_LO, r20
  std Y+IMGLABEL_OFFS_IMGRES_HI, r21
  std Y+IMGLABEL_OFFS_TXTRES_LO, r22
  std Y+IMGLABEL_OFFS_TXTRES_HI, r23
ImgLabel_Init_ret:
  ret
; @end





; ***************************************************************************
; signal handlers


; ---------------------------------------------------------------------------
; @routine ImgLabel_OnSetValue @global
;
; @param  Y       address of widget
; @param  X       value
; @return CFLAG   set upon return
; @clobbers none

ImgLabel_OnSetValue:
  std Y+IMGLABEL_OFFS_USER_LO, xl
  std Y+IMGLABEL_OFFS_USER_HI, xh
  sec
  ret
; @end



; ---------------------------------------------------------------------------
; @routine ImgLabel_OnGetValue @global
;
; @param  Y       address of widget
; @return CFLAG   set upon return
; @return r19:r18 value
; @clobbers none

ImgLabel_OnGetValue:
  ldd r18, Y+IMGLABEL_OFFS_USER_LO
  ldd r19, Y+IMGLABEL_OFFS_USER_HI
  sec
  ret
; @end



; ---------------------------------------------------------------------------
; @routine ImgLabel_OnGetDefaultWidth @global
;
; @param  Y       address of widget
; @return CFLAG   set upon return
; @return r19:r18 value
; @clobbers any, !Y

ImgLabel_OnGetDefaultWidth:
  bigcall Widget_GetBorderAndSpacing ; r22=spacing, r23=border (none)
  mov r20, r23 ; add border
  clr r21
  lsl r20      ; twice
  rol r21
  rcall imgLabelGetImageRessource    ; Z=ressource (r16, r17, r18)
  brcc ImgLabel_OnGetDefaultWidth_handleText
  rcall imgLabelGetImageWidth                ; r13:r12=size (none)
  add r20, r12                               ; add width
  adc r21, r13
  add r20, r22                               ; add spacing
  adc r21, r22
  sub r21, r22
ImgLabel_OnGetDefaultWidth_handleText:
  rcall imgLabelGetTextRessource
  brcc ImgLabel_OnGetDefaultWidth_done
  rcall imgLabelGetTextWidth                 ; r13:r12 (r16, r18)
  add r20, r12                               ; add width
  adc r21, r13
ImgLabel_OnGetDefaultWidth_done:
  mov r18, r20
  mov r19, r21
ImgLabel_OnGetDefaultWidth_ret:
  sec
  ret
; @end



; ---------------------------------------------------------------------------
; @routine ImgLabel_OnGetDefaultHeight @global
;
; @param  Y       address of widget
; @return CFLAG   set upon return
; @return r19:r18 value
; @clobbers any, !Y

ImgLabel_OnGetDefaultHeight:
  clr r20
  clr r21
  rcall imgLabelGetImageRessource             ; Z=ressource (r16, r17, r18)
  brcc ImgLabel_OnGetDefaultHeight_handleText
  rcall imgLabelGetImageHeight
  cp r20, r12
  cpc r21, r13
  brcc ImgLabel_OnGetDefaultHeight_handleText
  mov r20, r12
  mov r21, r13
ImgLabel_OnGetDefaultHeight_handleText:
  rcall imgLabelGetTextRessource              ; Z=ressource (r16, r17, r18)
  brcc ImgLabel_OnGetDefaultHeight_done
  rcall imgLabelGetTextHeight
  cp r20, r12
  cpc r21, r13
  brcc ImgLabel_OnGetDefaultHeight_done
  mov r20, r12
  mov r21, r13
ImgLabel_OnGetDefaultHeight_done:
  mov r18, r20
  mov r19, r21
  bigcall Widget_AddOuterStyleBorders         ; (r20, r21)
  sec
  ret
; @end



; ---------------------------------------------------------------------------
; @routine ImgLabel_OnDraw @global
;
; @param Y address of widget
; @clobbers any, !Y

ImgLabel_OnDraw:
  ldd r16, Y+OBJECT_OFFS_FLAGS
  andi r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
  breq ImgLabel_OnDraw_ret

  ; actually draw
  bigcall Widget_Clear
  rcall imgLabelDrawImg
  rcall imgLabelDrawTxt
  
  ; maybe draw border
  ldd r16, Y+OBJECT_OFFS_OPTS
  andi r16, (1<<WIDGET_OPTS_BORDER_BIT)
  breq ImgLabel_OnDraw_done
  bigcall Widget_DrawBorder

ImgLabel_OnDraw_done:
  ; clear dirty flag
  ldd r16, Y+OBJECT_OFFS_FLAGS
  cbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
  std Y+OBJECT_OFFS_FLAGS, r16
ImgLabel_OnDraw_ret:
  sec
  ret
; @end







; ---------------------------------------------------------------------------
; @routine imgLabelDrawImg @global
;
; @param Y address of widget
; @clobbers any, !Y

imgLabelDrawImg:
  bigcall Widget_GetBorderAndSpacing ; r22=spacing, r23=border (none)
  ; preset X
  mov r4, r23
  clr r5
  ; get image
  rcall imgLabelGetImageRessource    ; Z=ressource (r16, r17, r18)
  brcc imgLabelDrawImg_ret
  ; set Y
  rcall imgLabelGetImageHeight       ; R13:R12=height (r16, r17, r18, Z)
  bigcall Widget_PackContentY        ; R7:R6=Y (r17, r18, r19, r20, r21)
  bigcall Widget_SelectColors        ; (R16)
  bigcall Widget_DrawImage
imgLabelDrawImg_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine imgLabelDrawTxt @global
;
; @param Y address of widget
; @clobbers any, !Y

imgLabelDrawTxt:
  bigcall Widget_GetBorderAndSpacing  ; r22=spacing, r23=border (none)
  ; preset X
  mov r4, r23
  clr r5
  ; get image
  rcall imgLabelGetImageRessource     ; Z=ressource (r16, r17, r18)
  brcc imgLabelDrawTxt_handleText
  ; set X
  rcall imgLabelGetImageWidth         ; R13:R12=width (none)
  add r4, r12
  adc r5, r13
  ; add spacing to X
  add r4, r22
  adc r5, r22
  sub r5, r22
imgLabelDrawTxt_handleText:
  ; get txt
  rcall imgLabelGetTextRessource      ; Z=ressource (r16, r17, r18)
  brcc imgLabelDrawTxt_ret
  ; set Y
  rcall imgLabelGetTextHeight         ; r16=height (none)
  mov r12, r16
  clr r13
  bigcall Widget_PackContentY         ; R7:R6=Y (r17, r18, r19, r20, r21)
  ; draw text
  bigcall Widget_DrawTextFlash        ; (any, !Y)
imgLabelDrawTxt_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine imgLabelGetImageRessource
;
; @param  Y     address of widget
; @return CFLAG set if ressource found, cleared on error
; @return Z     pointer to ressource

imgLabelGetImageRessource:
  ldd r16, Y+IMGLABEL_OFFS_IMGRES_LO
  ldd r17, Y+IMGLABEL_OFFS_IMGRES_HI
  bigjmp Widget_GetRessource               ; Z=ressource (r16, r17, r18)
; @end



; ---------------------------------------------------------------------------
; @routine imgLabelGetImageWidth
;
; @param  Y       address of widget
; @param  Z       byte address pointer to image ressource
; @return r13:r12 image width
; @clobbers none

imgLabelGetImageWidth:
  adiw zh:zl, RES_IMAGE_OFFS_WIDTH_LO
  lpm r12, Z+
  lpm r13, Z
  sbiw zh:zl, (RES_IMAGE_OFFS_WIDTH_LO+1)
  ret
; @end



; ---------------------------------------------------------------------------
; @routine imgLabelGetImageHeight
;
; @param  Y       address of widget
; @param  Z       byte address pointer to image ressource
; @return r13:r12 image height
; @clobbers none

imgLabelGetImageHeight:
  adiw zh:zl, RES_IMAGE_OFFS_HEIGHT_LO
  lpm r12, Z+
  lpm r13, Z
  sbiw zh:zl, (RES_IMAGE_OFFS_HEIGHT_LO+1)
  ret
; @end



; ---------------------------------------------------------------------------
; @routine imgLabelGetTextRessource
;
; @param  Y     address of widget
; @return CFLAG set if ressource found, cleared on error
; @return Z     pointer to ressource

imgLabelGetTextRessource:
  ldd r16, Y+IMGLABEL_OFFS_TXTRES_LO
  ldd r17, Y+IMGLABEL_OFFS_TXTRES_HI
  bigjmp Widget_GetRessource               ; Z=ressource (r16, r17, r18)
; @end



; ---------------------------------------------------------------------------
; @routine imgLabelGetTextWidth
;
; @param  Y       address of widget
; @param  Z       byte address pointer to text ressource
; @return r13:r12 text width
; @clobbers r16, r18

imgLabelGetTextWidth:
  bigcall Widget_GetCharWidth           ; R16=char width
  mov r18, r16
  bigjmp Widget_CalcStringWidthFLASH    ; r13:r12=size (r16)
; @end



; ---------------------------------------------------------------------------
; @routine imgLabelGetTextHeight
;
; @param  Y       address of widget
; @return r13:r12 text width
; @clobbers none

imgLabelGetTextHeight:
  bigjmp Widget_GetCharHeight           ; R16=char width
; @end





; ***************************************************************************
; data in FLASH

ImgLabel_DefaultSignalmap:
  ; header
  .dw Widget_DefaultSignalmap*2  ; next table to use
  ; entries
  .db 0,                           WIDGET_SIGNAL_DRAW,      LOW(ImgLabel_OnDraw),             HIGH(ImgLabel_OnDraw)
  .db WIDGET_VALUE_CURRENTVALUE,   WIDGET_SIGNAL_GETVALUE,  LOW(ImgLabel_OnGetValue),         HIGH(ImgLabel_OnGetValue)
  .db WIDGET_VALUE_CURRENTVALUE,   WIDGET_SIGNAL_SETVALUE,  LOW(ImgLabel_OnSetValue),         HIGH(ImgLabel_OnSetValue)
  .db WIDGET_VALUE_DEFAULT_WIDTH,  WIDGET_SIGNAL_GETVALUE,  LOW(ImgLabel_OnGetDefaultWidth),  HIGH(ImgLabel_OnGetDefaultWidth)
  .db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE,  LOW(ImgLabel_OnGetDefaultHeight), HIGH(ImgLabel_OnGetDefaultHeight)

  .db 0, 0, 0, 0  ; end of table



#endif



