/* Manage a Group of Registers for a text window */!!

inherit(Object, #RegGroup, #(parentWin
startLine     /* top line # on window */
registerColl /* sorted collection */
groupIndex
visible?), 2, nil)!!

now(class(RegGroup))!!

/* PUBLIC */
Def new(self, parent, index, line, regColl | newInst)
{
  newInst := new( self:ancestor ) ;

  ^initialize( newInst, parent, index, line, regColl )
}
!!

now(RegGroup)!!

/* PUBLIC */
Def setGroupPosition(self, lineNum, labelWidth, valueWidth)
{
  startLine := lineNum ;
  reposition( self, labelWidth, valueWidth ) ;  /* does NOT cause redraw */
  
  ^startLine
}
!!

/* PUBLIC */
/* hDC is the display context, tmHeight is the character */
/* height (font), regIndex is the register index value   */
/* for the first register to be displayed in the window, */
/* tmWidth is the character width (font).                */
Def display(self, hDC, tmHeight, regIndex, tmWidth | origColor label yPos index)
{
  if not(visible?(self)) then ^nil endif ;

  origColor := Call GetTextColor( hDC ) ;
  yPos := 0;
  index := 0;
  do(registerColl,
  {using(reg)
     if (index >= regIndex) then
        /* Draw the label */
        displayLabel( reg, hDC, yPos) ;
        /* Draw the register value */
        display(reg, hDC, yPos, tmHeight, tmWidth);
        yPos := yPos + tmHeight;
     endif;
     index := index + 1;
    });
}
!!

/* PUBLIC */
Def groupIndex(self)
{ ^groupIndex }
!!

/* PUBLIC */
Def initialize(self, parent, index, line, regColl)
{
  parentWin    := parent ;
  startLine    := line   ;
  groupIndex   := index  ;
  registerColl := regColl ;   /* N.B.: May be nil */
}
!!

/* PUBLIC */
Def line2reg(self, lineNum | sl index)
{ 
    sl := startLine(self) ;
    if (lineNum >= sl) cand (lineNum <= (sl + size(self) - 1))
    then
      index := lineNum - sl ;
      ^registerColl[index]
    endif ;

  ^nil
}
!!

/* PUBLIC */
Def makeHidden(self)
{
  visible? := nil ;
}
!!

/* PUBLIC */
Def makeVisible(self)
{
  visible? := #true ;
}
!!

/* PUBLIC */
Def parentWin(self)
{ ^parentWin }
!!
/* PUBLIC */
Def registerColl(self)
{ ^registerColl }
!!

/* PRIVATE */
Def reposition(self labelWidth valueWidth | labelX valueX valueY pixHeight)
{
  if not( startLine ) then ^nil endif ;

  pixHeight := tmHeight( parentWin ) ;
  labelX := (labelWidth * tmWidth(parentWin)) + 2 ;
  valueX := ((labelWidth+valueWidth+1) * tmWidth(parentWin)) + 2 ;
  valueY := (startLine * pixHeight) ;
  
  do(over(0,size(registerColl)),
  {using(offset | register, Y)
    register := registerColl[offset] ;
    Y := (valueY + (offset * pixHeight)) ;
    setLabelLoc( register, point(labelX - (size(name(register))*tmWidth(parentWin)), Y) ) ;
    setValueLoc( register, point(valueX - (digits(register)*tmWidth(parentWin))    , Y) ) ;
  });
  
}
!!

/* PUBLIC */
Def setRegisterColl(self, newSortedColl)
{ ^(registerColl := newSortedColl) }
!!

/* PUBLIC -- return # lines to display */
Def size(self)
{
  if visible?
  then
    ^size(registerColl)
  else
    ^0
  endif ;
}
!!

/* PUBLIC */
Def startLine(self)
{ ^startLine }
!!

/* PUBLIC */
Def updateValues(self)
{ if visible?(self)
  then
    do(registerColl,
    {using(register)
      updateValue( register ) ;  /* registers know own IDs & how to update */
    });
  endif ;
}
!!

/* PUBLIC */
Def visible?(self)
{ ^visible? }
!!
