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