
# screen.pl -- Copyright (c) 1990, Henk P. Penning.
# You may distribute under the terms of the GNU General Public License
# as specified in the README file that comes with the Jinx 2.1 kit.

sub setKeyValueCols
  { local(*keys) = @_ ;
    local($_) ;
    $firstKeyCol = 2 ;
    $numKeyCols = &min(int $COLS/4,&maxStrlen(*keys,0,$#keys)) + 3 ;
    $lastKeyCol = $firstKeyCol + $numKeyCols - 1 ;
    $firstValueCol = $lastKeyCol + 1 ;
    $lastValueCol = $COLS - 1 ;
    $numValueCols = $lastValueCol - $firstValueCol + 1 ;
  }

sub setInfoLines
  { local(*keys) = @_ ;
    $lastInfoLine = &min($lastFieldLine,$firstFieldLine+$#keys) ;
    $numFieldsShown = $lastInfoLine - $firstFieldLine + 1 ;
  }

sub setKeyScreen
  { local(*keys) = @_ ;
    &setKeyValueCols(*keys) ;
    &setInfoLines(*keys) ;
    &blankFieldLines ;
  }

sub setDataScreen
  { local(*keys) = @_ ;
    &setInfoLines(*keys) ;
    &blankFieldLines ;
  }

sub initParamsScreen
  { $cursesLine = 0 ;
    $jinxLineD = 1 ;
    $jinxLineR = 2 ;
    $firstFieldLine = $jinxLineR + 2 ;
    $commandLine = $LINES - 1 ;
    $statusLine = $commandLine - 1 ;
    $lastMenuLine = $statusLine - 2 ;
    $numMenuLines = $maxMenuSize + 1 ;
    $firstMenuLine = $lastMenuLine - $numMenuLines + 1 ;
    $lastFieldLine = $firstMenuLine - 2 ;
    $numFieldLines = $lastFieldLine - $firstFieldLine + 1 ;
    $currInfoCol = 0 ;
    $firstInfoCol = $currInfoCol + 2 ;
    $lastInfoCol = $COLS - 1 ;
    $numInfoCols = $lastInfoCol - $firstInfoCol + 1 ;

    $hLine   = '-' x $COLS ;
    $topOpen = '<' x $COLS ;
    $botOpen = '>' x $COLS ;

    $hLineCol = $hLine ;
    substr($hLineCol,int($COLS/2)-5,10) = ' col view ' ;
    $hLineRaw = $hLine ;
    substr($hLineRaw,int($COLS/2)-5,10) = ' raw view ' ;

    $topOpenCol = $topOpen ;
    substr($topOpenCol,int($COLS/2)-5,10) = ' col view ' ;
    $topOpenRaw = $topOpen ;
    substr($topOpenRaw,int($COLS/2)-5,10) = ' raw view ' ;
  }

sub topOpen { $colView ? $topOpenCol : $topOpenRaw ; } ;
sub hLine   { $colView ? $hLineCol   : $hLineRaw ; } ;

sub showTopBottomD
  { local(*info,$infoY) = @_ ;
    &mvaddstr($firstFieldLine-1,0, ($infoY==0) ? &hLine : &topOpen ) ;
    &mvaddstr($lastInfoLine+1,0,
      ($infoY + $numFieldLines <= $#info) ? $botOpen : $hLine) ;
  }

sub showTopBottomR
  { local(*info,$infoY) = @_ ;
    &mvaddstr($firstFieldLine-1,0, ($infoY==0) ? $hLine : $topOpen ) ;
    &mvaddstr($lastInfoLine+1,0,
      ($infoY + $numFieldLines <= $#info) ? $botOpen : $hLine) ;
  }

sub layoutCols
  { local(*info,$infoY,$infoX) = @_ ;
    local(@res) = @info[$infoY..&min($#info,$infoY+$numFieldLines-1)] ;
    local($newInfoX,$res,$_,@record,$i,@notNum,@maxlen,$formatD) ;

    for $res ( @res )
      { @record = split(/$;/,$res,$numNames+1) ;
	$i = 0 ; 
	for ( @record )
	  { $maxlen[$i] = length($_) if length($_) > $maxlen[$i] ;
	    $notNum[$i] |= /\D/ if ! $notNum[$i] ;
	    $i++ ;
	  }
      }

    $i = 0 ;
    for ( @maxlen )
      { $_ = 1 unless $_ ;
	$formatD .= $notNum[$i] ? "%-${_}s$;" : "%${_}s$;" ;
	$newInfoX += $_ + 1 if $i < $infoX ;
	$i++ ;
      }

    chop $formatD ;

    for ( @res )
      { $_ = sprintf($formatD,split(/$;/,$_,$numNames+1)) ; }
    return($newInfoX,@res) ;
  }

sub showInfo
  { local(*info,$infoY,$infoX,$xBegin,$xEnd) = @_ ;
    local($i,$delim) ;
    local($xNum) = $xEnd - $xBegin - 1 ;
    for ($i=$infoY ; $i < $infoY + $numFieldLines ; $i++ )
      { last if $i > $#info ;
        if ( $info[$i] eq '' )
          { $str = '' ;
	    $delim = ':<>:' ;
	  }
	elsif ( $infoX == 0 )
          { $str = $info[$i] ;
	    $delim = '|<>|' ;
          }
        else
          { $str = &tailstr($info[$i],$infoX) ;
	    $delim = '<<>|' ;
          }
	$str =~ s/$;/|/g ;
	&show($str,0,$i-$infoY+$firstFieldLine,$xBegin,$xNum,$delim) ;
      }
  }

sub showCursorScr
  { local($curr,$Y) = @_ ;
    $curPos = $curr - $Y + $firstFieldLine ;
    &mvaddstr($curPos,0,'> ') ;
    $oldCurr = $curr ;
  }

sub unShowCursorScr
  { &mvaddstr($curPos,0,'  ') ;
    $oldCurr = undef ;
  }

sub blankFieldLines
  { &clrreg($firstFieldLine-1,$lastFieldLine+1) ; # -1,+1 are for <<< --- >>>
    $oldCurr = undef ;
  }

sub moveCursorScreen
  { local($curr,$infoY) = @_ ;
    &unShowCursorScr if defined $oldCurr ;
    &showCursorScr($curr,$infoY) ;
  }

sub showDataScreen
  { local(*info,$infoY,$infoX,$curr) = @_ ;
    &showTopBottomD(*info,$infoY) ;
    &unShowCursorScr if defined $oldCurr ;
    &showCursorScr($curr,$infoY) if $#info >= 0 ;
    if ( $colView )
      { local($newInfoX,@colInfo) = &layoutCols(*info,$infoY,$infoX) ;
	&showInfo(*colInfo,0,$newInfoX,$firstInfoCol,$lastInfoCol) ;
      }
    else
      { &showInfo(*info,$infoY,$infoX,$firstInfoCol,$lastInfoCol) ; }
  }

sub showKeysScreen
  { local(*info,$infoY,$infoX,$curr) = @_ ;
    &showTopBottomR(*info,$infoY) ;
    &unShowCursorScr if defined $oldCurr ;
    &showCursorScr($curr,$infoY) if $#info >= 0 ;
    &showInfo(*info,$infoY,$infoX,$firstKeyCol,$lastKeyCol) ;
  }

sub showValuesScreen
  { local(*info,$infoY,$infoX) = @_ ;
    &showInfo(*info,$infoY,$infoX,$firstValueCol,$lastValueCol) ;
  }

sub showValueScreen
  { local($value,$field,$infoY) = @_ ;
    &show($value,0,$field-$infoY+$firstFieldLine,
	  $firstValueCol,$numValueCols-2,'|<>|') ;
  }

sub editValueScreen
  { local($value,$field,$infoY) = @_ ;
    local(@res) = &edit($value,0,$field-$infoY+$firstFieldLine,
			$firstValueCol,$numValueCols-2,'|<>|') ;
    return @res ;
  }

1;
