; ***************************************************************************
; 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_GUI2_VALUELABEL_ASM
#define AQH_AVR_GUI2_VALUELABEL_ASM


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

.equ VLABEL_OFFS_BEGIN           =  WIDGET_SIZE
.equ VLABEL_OFFS_VALUE_LO        =  VLABEL_OFFS_BEGIN+0
.equ VLABEL_OFFS_VALUE_HI        =  VLABEL_OFFS_BEGIN+1
.equ VLABEL_OFFS_POSTKOMMADIGITS =  VLABEL_OFFS_BEGIN+2
.equ VLABEL_OFFS_TOTALDIGITS     =  VLABEL_OFFS_BEGIN+3
.equ VLABEL_SIZE                 =  VLABEL_OFFS_BEGIN+4



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

.cseg



; ---------------------------------------------------------------------------
; @routine ValueLabel_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 r20 number of postkomma digits
; @param r21 total number of digits (0=variable)
; @clobbers any

ValueLabel_new:
  push r20
    push r21
      ldi r24, LOW(VLABEL_SIZE)
      ldi r25, HIGH(VLABEL_SIZE)
      bigcall Object_Alloc           ; (!r16, !r17, !X)
    pop r21
  pop r20
  brcc ValueLabel_new_ret
  rcall ValueLabel_Init               ; (r16, r17, X)
  sec
ValueLabel_new_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine ValueLabel_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 r20 number of postkomma digits
; @param r21 total number of digits (0=variable)
; @clobbers r16, r17, X

ValueLabel_Init:
  push r20
    push r21
      ; call base class
      bigcall Widget_Init                       ; (r16, r17, X)
    pop r21
  pop r20

  ; setup valueLabel data
  std Y+VLABEL_OFFS_POSTKOMMADIGITS, r20
  std Y+VLABEL_OFFS_TOTALDIGITS, r21
  
  ; set default signal map
  ldi r16, LOW(ValueLabel_DefaultSignalmap*2)
  std Y+OBJECT_OFFS_SIGNALMAP_LO, r16
  ldi r16, HIGH(ValueLabel_DefaultSignalmap*2)
  std Y+OBJECT_OFFS_SIGNALMAP_HI, r16

  ret
; @end



; ---------------------------------------------------------------------------
; @routine ValueLabel_OnSetValue @global
;
; @param Y address of widget
; @param X new value
; @return CFLAG set if signal handled
; @clobbers r17

ValueLabel_OnSetValue:
  std Y+VLABEL_OFFS_VALUE_LO, xl
  std Y+VLABEL_OFFS_VALUE_HI, xh
  
  ldd r17, Y+OBJECT_OFFS_FLAGS
  ori r17, (1<<WIDGET_FLAGS_DIRTY_BIT)
  std Y+OBJECT_OFFS_FLAGS, r17

  sec
  ret
; @end



; ---------------------------------------------------------------------------
; @routine ValueLabel_OnGetValue @global
;
; @param  Y       address of widget
; @param  X       new value
; @return CFLAG   set if signal handled
; @return r19:r18 value
; @clobbers r17

ValueLabel_OnGetValue:
  ldd r18, Y+VLABEL_OFFS_VALUE_LO
  ldd r19, Y+VLABEL_OFFS_VALUE_HI
  sec
  ret
; @end



; ---------------------------------------------------------------------------
; @routine ValueLabel_OnDraw @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @clobbers any, !Y

ValueLabel_OnDraw:
  ldd r16, Y+OBJECT_OFFS_FLAGS
  andi r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
  breq ValueLabel_OnDraw_ret

  bigcall Widget_Clear
  rcall valueLabelWriteValue
  
  ldd r16, Y+OBJECT_OFFS_OPTS
  andi r16, (1<<WIDGET_OPTS_BORDER_BIT)
  breq ValueLabel_OnDraw_done
  bigcall Widget_DrawBorder

ValueLabel_OnDraw_done:
  ldd r16, Y+OBJECT_OFFS_FLAGS
  cbr r16, (1<<WIDGET_FLAGS_DIRTY_BIT)
  std Y+OBJECT_OFFS_FLAGS, r16

ValueLabel_OnDraw_ret:
  ret
; @end



; ---------------------------------------------------------------------------
; @routine ValueLabel_OnGetDefaultWidth @global
;
; @param Y address of widget
; @param r17 value requested
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y

ValueLabel_OnGetDefaultWidth:
  ldd r17, Y+VLABEL_OFFS_TOTALDIGITS
  tst r17
  breq ValueLabel_OnGetDefaultWidth_calcRealSize
  bigcall Widget_CalcFixedStringWidth
  rjmp ValueLabel_OnGetDefaultWidth_done
ValueLabel_OnGetDefaultWidth_calcRealSize:
  rcall valueLabelCalcTextWidth
ValueLabel_OnGetDefaultWidth_done:
  mov r18, r12
  mov r19, r13
  bigcall Widget_AddOuterStyleBorders  ; (r20, r21)
  sec
  ret
; @end



; ---------------------------------------------------------------------------
; @routine ValueLabel_OnGetDefaultHeight @global
;
; @param Y address of widget
; @param xl param1
; @param xh param2
; @return CFLAG set if signal handled
; @return r19:r18 value
; @clobbers any, !Y

ValueLabel_OnGetDefaultHeight:
  bigcall Widget_GetCharHeight    ; R16=char height
  mov r18, r16
  clr r19
  bigcall Widget_AddOuterStyleBorders  ; (r20, r21)
  sec
  ret
; @end



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

valueLabelWriteValue:
  rcall valueLabelAlignTextXY  ; X=ptr to text (r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19)
  bigcall Widget_DrawTextRam   ; (any, !Y)
  ret
; @end



; ---------------------------------------------------------------------------
; @routine valueLabelAlignTextXY
;
; @param  Y       address of widget
; @param  R13:R12 width of object to align
; @return R5:R4   X
; @return R7:R6   Y
; @return X pointer to text in SDRAM
; @clobbers r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, r20, r21, r22, r23, r24, r25

valueLabelAlignTextXY:
  rcall valueLabelCalcTextWidth       ; X=ptr to text in SDRAM, R13:R12=text width (r16, r17, r18)
  push xl
    push xh
      bigcall Widget_PackContentX       ; R5:R4=X (r17, r18, r19, r20, r21)
    
      bigcall Widget_GetCharHeight      ; R16=char height
      mov r12, r16
      clr r13
      bigcall Widget_PackContentY       ; R7:R6=Y (r17, r18, r19, r20, r21)
    pop xh
  pop xl
  ret
; @end



; ---------------------------------------------------------------------------
; @routine valueLabelCalcTextWidth
;
; @param  Y       address of widget
; @return X       pointer to text in SDRAM
; @return r13:r12 width of string
; @clobbers r16, r17, r18

valueLabelCalcTextWidth:
  ldd r20, Y+VLABEL_OFFS_VALUE_LO
  ldd r21, Y+VLABEL_OFFS_VALUE_HI
  ldd r24, Y+VLABEL_OFFS_POSTKOMMADIGITS
  bigcall IntToAscii                        ; X=pointer to text
  bigcall Widget_GetCharWidth                 ; R16=char width
  mov r18, r16
  bigcall Widget_CalcStringWidthSDRAM       ; r13:r12=size (r16)
valueLabelCalcTextWidth_ret:
  ret
; @end



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

ValueLabel_DefaultSignalmap:
  ; header
  .dw Widget_DefaultSignalmap*2  ; next table to use
  ; entries
  .db 0,                           WIDGET_SIGNAL_DRAW,     LOW(ValueLabel_OnDraw),             HIGH(ValueLabel_OnDraw)
  .db WIDGET_VALUE_CURRENTVALUE,   WIDGET_SIGNAL_SETVALUE, LOW(ValueLabel_OnSetValue),         HIGH(ValueLabel_OnSetValue)
  .db WIDGET_VALUE_CURRENTVALUE,   WIDGET_SIGNAL_GETVALUE, LOW(ValueLabel_OnGetValue),         HIGH(ValueLabel_OnGetValue)
  .db WIDGET_VALUE_DEFAULT_WIDTH,  WIDGET_SIGNAL_GETVALUE, LOW(ValueLabel_OnGetDefaultWidth),  HIGH(ValueLabel_OnGetDefaultWidth)
  .db WIDGET_VALUE_DEFAULT_HEIGHT, WIDGET_SIGNAL_GETVALUE, LOW(ValueLabel_OnGetDefaultHeight), HIGH(ValueLabel_OnGetDefaultHeight)

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


#endif

