sub Min { my $min=shift; $_<$min and $min=$_ for @_; $min }
sub Max { my $max=shift; $_>$max and $max=$_ for @_; $max }
sub CalcNavigation {
my %P = ref($_[0]) eq "HASH" ? %{ $_[0] } : ();
$P{DefaultCount} = 20 unless defined $P{DefaultCount};
$P{PrevPages} = 10 unless defined $P{PrevPages};
$P{NextPages} = 10 unless defined $P{NextPages};
$P{$_} = 0 for grep {! defined $P{$_}}
qw(From Count Records);
$P{$_} = int($P{$_}) for
qw(DefaultCount PrevPages NextPages From Count Records);
$P{DefaultCount} = Max($P{DefaultCount}, 1);
$P{Records} = 0 unless $P{Records} > 0;
$P{From} = Min(Max($P{From}, 1), Max($P{Records}, 1));
$P{Count}= Max($P{Count}, 0) || $P{DefaultCount};
$P{Page} = int(($P{From}-1)/$P{Count})+1;
$P{From} = ($P{Page}-1)*$P{Count}+1;
$P{To} = Min($P{From}+$P{Count}-1, $P{Records});
$P{Prev} = Max($P{From}-$P{Count}, 1);
$P{Prev} = undef if $P{From} == 1;
$P{Next} = $P{From}+$P{Count};
$P{Next} = undef if $P{Next} > $P{Records};
$P{Pages}= [ map {{
Page => $_,
From => ($_-1)*$P{Count}+1,
To => Min($_*$P{Count}, $P{Records})
}} Max(1, $P{Page}-$P{PrevPages}) ..
Min($P{Page}+$P{NextPages}, ($P{Records}-1)/$P{Count}+1) ];
return \%P;
}
####
# these two commands are equal :-)
$nav=CalcNavigation({Records=>100, From=>1, Count=>10, NextPages=>2});
$nav = {
'Records' => 100,
'From' => 1,
'To' => 10,
'Count' => 10,
'Page' => 1,
'Prev' => undef,
'Next' => 11,
'Pages' => [
{ 'Page' => 1, 'From' => 1 , 'To' => 10 },
{ 'Page' => 2, 'From' => 11, 'To' => 20 },
{ 'Page' => 3, 'From' => 21, 'To' => 30 }
],
'DefaultCount' => 20,
'NextPages' => 2,
'PrevPages' => 10,
};
####
=item B( \%nav )
Use these keys from %nav (all values will be rounded by int())
=over 4
=item B
Record which must be shown on current page.
First record number is 1.
=item B
Shown records per page.
=item B
Number of last record. 0 - no records.
=item B
Set Count to DefaultCount if Count <= 0.
Default value for DefaultCount is 20.
Count = DefaultCount = 1 if Count <= 0 and DefaultCount <= 0.
=item B
=item B
Calculate per-page information for pages from Current-PrevPages to
Current+NextPages.
By default PrevPages and NextPages equal to 10.
=back
Records rounded to nearest non-negative integer.
From will be corrected by these rules:
From = 1 if From < 0;
From = Records if From > Records;
From = number of first records on current page.
Count rounded to nearest positive integer.
Return hashref to hash contains %nav keys plus these keys:
=over 4
=item B
Number of last record on current page.
If Records = 0 then To = 0.
=item B
Number of first record on previous page.
If currect page is first page then Prev = undef.
=item B
Number of first record on next page.
If current page is last page then Next = undef.
=item B
Number of current page.
=item B
Arrayref to pages from Current-PrevPages to Current+NextPages.
Every page is a hashref with these keys:
=over 4
=item B
Number of this page.
=item B
Number of first record on this page.
=item B
Number of last record on this page.
=back
=back
=cut