1package PDF::FromHTML::Template::Container::Loop;
2
3use strict;
4
5BEGIN {
6    use vars qw(@ISA);
7    @ISA = qw(PDF::FromHTML::Template::Container);
8
9    use PDF::FromHTML::Template::Container;
10}
11
12sub new
13{
14    my $class = shift;
15    my $self = $class->SUPER::new(@_);
16
17    if (exists $self->{MAXITERS} && $self->{MAXITERS} < 1)
18    {
19        die "<loop> MAXITERS must be greater than or equal to 1", $/;
20    }
21    else
22    {
23        $self->{MAXITERS} = 0;
24    }
25
26    return $self;
27}
28
29sub _do_page
30{
31    my $self=shift;
32    my ($context) = @_;
33    return 0 unless $self->should_render($context);
34    unless ($self->{ITERATOR} && $self->{ITERATOR}->more_params)
35    {
36        $self->{ITERATOR} = $self->make_iterator($context);
37    }
38    my $iterator = $self->{ITERATOR};
39    $iterator->enter_scope;
40    while ($iterator->can_continue)
41    {
42        $iterator->next;
43        $self->SUPER::begin_page($context);
44    }
45    $iterator->exit_scope;
46    return 1;
47}
48
49sub begin_page
50{
51    _do_page(@_,'begin_page');
52}
53
54sub end_page
55{
56    _do_page(@_,'end_page');
57}
58
59sub make_iterator
60{
61    my $self = shift;
62    my ($context) = @_;
63
64    return PDF::FromHTML::Template::Factory->create('ITERATOR',
65        NAME     => $context->get($self, 'NAME'),
66        MAXITERS => $context->get($self, 'MAXITERS'),
67        CONTEXT  => $context,
68    );
69}
70
71sub render
72{
73    my $self = shift;
74    my ($context) = @_;
75
76    return 0 unless $self->should_render($context);
77
78    unless ($self->{ITERATOR} && $self->{ITERATOR}->more_params)
79    {
80        $self->{ITERATOR} = $self->make_iterator($context);
81    }
82    my $iterator = $self->{ITERATOR};
83
84    $iterator->enter_scope;
85
86    while ($iterator->can_continue)
87    {
88        $iterator->next;
89
90        unless ($self->iterate_over_children($context))
91        {
92            $iterator->back_up;
93            last;
94        }
95
96        $self->reset;
97    }
98
99    $iterator->exit_scope;
100
101    if ($iterator->more_params) {
102        splice(@{$iterator->{DATA}}, 0, $iterator->{INDEX}+1);
103        $iterator->{MAX_INDEX} = $#{$iterator->{DATA}};
104        return 0;
105    }
106
107    return 1;
108}
109
110sub total_of
111{
112    my $self = shift;
113    my ($context, $attr) = @_;
114
115    my $iterator = $self->make_iterator($context);
116
117    my $total = 0;
118
119    $iterator->enter_scope;
120    while ($iterator->can_continue)
121    {
122        $iterator->next;
123        $total += $self->SUPER::total_of($context, $attr);
124    }
125    $iterator->exit_scope;
126
127    return $total;
128}
129
130sub max_of
131{
132    my $self = shift;
133    my ($context, $attr) = @_;
134
135    my $iterator = $self->make_iterator($context);
136
137    my $max = $context->get($self, $attr);
138
139    $iterator->enter_scope;
140    while ($iterator->can_continue)
141    {
142        $iterator->next;
143        my $v = $self->SUPER::max_of($context, $attr);
144
145        $max = $v if $max < $v;
146    }
147    $iterator->exit_scope;
148
149    return $max;
150}
151
1521;
153__END__
154
155=head1 NAME
156
157PDF::FromHTML::Template::Container::Loop
158
159=head1 PURPOSE
160
161To provide a looping construct
162
163=head1 NODE NAME
164
165LOOP
166
167=head1 INHERITANCE
168
169PDF::FromHTML::Template::Container
170
171=head1 ATTRIBUTES
172
173=over 4
174
175=item * NAME - the name of a parameter that points to an array of hashes.
176
177=back
178
179=head1 CHILDREN
180
181None
182
183=head1 AFFECTS
184
185Nothing
186
187=head1 DEPENDENCIES
188
189FOOTER - indicates where to pagebreak
190
191=head1 USAGE
192
193  <loop name="LOOPY">
194    ... Children here ...
195  </loop>
196
197The children tags will have access to the values specified in LOOPY, as well as
198the parameters specifed outside.
199
200=head1 AUTHOR
201
202Rob Kinyon (rkinyon@columbus.rr.com)
203
204=head1 SEE ALSO
205
206HTML::Template, FOOTER
207
208=cut
209