use strict;
use warnings;
use Term::ReadKey;

$| = 1;

my $key;                         # Eingabetaste
my $fin = 0;                     # Merker fuer Programmende
my $seite = 1;                   # angezeigte Bildschirmseite 
my $proseite = 20;               # Datensätze pro Seite

# Datei lesen
open (DATEI, "<viele.dat");
flock (DATEI, 2);
my @daten = <DATEI>;
close DATEI;
# Zeilenanzahl der Datei festellen
my $zeilen = @daten;

# Das gibt dann Seiten gesamt
my $gesamt = int(($zeilen - 1) / $proseite + 1);

while (! $fin)
  {
  # wo beginnen?
  my $start = ($seite - 1) * $proseite;

  if ($zeilen > 0)
    {
    # Zeilen ausgeben des aktuellen Bereiches
    for my $i ($start .. ($start - 1) + $proseite)
      {
      print "$daten[$i]";
      }
    my $navi = navi_leiste($gesamt, $zeilen, $seite, $proseite);
    print '-' x length($navi), "\n";  
    print "$navi\n";
    print '-' x length($navi), "\n";  
    }
  else
    { print "Keine Daten!\n"; }
    
  # Eingabe entgegennehmen und bearbeiten
  ReadMode("raw");
  while (not defined ($key = ReadKey(-1))) { } # No key yet
  ReadMode("restore");
  if    ($key eq ' ')     # vorwaerts
    { $seite = ($seite < $gesamt)? $seite + 1 : $gesamt; }
  elsif ($key eq 'b')     # rueckwaerts
    { $seite = ($seite > 1)? $seite - 1 : 1; }
  elsif ($key eq '<')     # Anfang
    { $seite = 1; }
  elsif ($key eq '>')     # Ende
    { $seite = $gesamt; }
  elsif ($key eq 'q')     # Programmende
    { $fin = 1; }
  }
    

sub navi_leiste
  {
  my ($gesamtseiten, $zeilen, $seite, $pro_seite) = @_;
  my $anznavi = 4;            # wieviele Seiten vorher, nachher anzeigen

  my ($letzte, $erste, $navi_zeile, $i);
  my $aktuelle_seite = $seite ? $seite : 1;

  $letzte = $anznavi + $aktuelle_seite;
  $letzte = $gesamtseiten if ($letzte > $gesamtseiten);

  $erste = $aktuelle_seite - $anznavi;
  $erste = 1 if ($erste < 1);

  $navi_zeile = "Seite $aktuelle_seite von $gesamtseiten: ";
  if ($gesamtseiten != 1 && $zeilen)
    {
    $navi_zeile .=  "<< " if ($erste > 1);
    for $i ($erste .. $letzte)
      {
      if ($aktuelle_seite == $i)
        { $navi_zeile .= " [$i] "; }
      else
        { $navi_zeile .= " $i "; }
      }
    $navi_zeile .= " >>" if ($letzte < $gesamtseiten);
    }
  return $navi_zeile;
  }