use strict;
use warnings FATAL => 'all';
package HTML::Tested::List;
use HTML::Tested::List::Renderer;
use HTML::Tested::List::Table;
use Carp;
sub new {
my ($class, $parent, $name, $c, %args) = @_;
$args{name} ||= $name;
my @renderers = ('HTML::Tested::List::Renderer');
push @renderers, HTML::Tested::List::Table->new if $args{render_table};
$args{renderers} ||= \@renderers;
{
no strict 'refs';
if (!$c) {
$c = "$parent\::Item$name";
push @{ "$c\::ISA" }, ($args{cbase} || "HTML::Tested");
}
*{ "$parent\::$name\_containee" } = sub { return $c; };
*{ "$parent\::$name\_containee_do" } = sub {
my ($self, $func, @args) = @_;
return $self->$name($c->$func(@args));
};
};
$args{containee} ||= $c;
my $self = bless(\%args, $class);
for my $r (@{ $self->renderers }) {
$r->init($self, $parent);
}
return $self;
}
sub name { return shift()->{name}; }
sub renderers { return shift()->{renderers}; }
sub options { return {}; }
sub _get_option { return undef; }
sub render {
my ($self, $caller, $stash, $id) = @_;
for my $r (@{ $self->renderers }) {
$r->render($self, $caller, $stash, $id);
}
}
sub containee {
my $res = shift()->{containee} or confess "No containee argument given";
return $res;
}
sub bless_from_tree {
my ($self, $p) = @_;
my $target = $self->containee;
return [ map { $target->ht_bless_from_tree($_) } @$p ];
}
sub merge_one_value { shift()->_do_one_value("merge_one_value", @_); }
sub absorb_one_value { shift()->_do_one_value("absorb_one_value", @_); }
sub _do_one_value {
my ($self, $func, $root, $val, @path) = @_;
my $arr = $root->{ $self->name } || [];
my $id = shift(@path) or return;
$arr->[--$id] ||= bless({}, $self->containee);
$arr->[$id]->_ht_set_one($func, $val, @path);
$root->{ $self->name } = $arr;
}
sub finish_load {
my ($self, $root) = @_;
my @arr = grep { $_ } @{ $root->{ $self->name } };
$root->{ $self->name } = \@arr unless $self->{keep_holes};
$_->_call_finish_load for @arr;
}
sub validate {
my ($self, $caller) = @_;
my $n = $self->name;
my $arr = $caller->$n || [];
my @res;
for (my $i = 0; $i < @$arr; $i++) {
push @res, map { [
sprintf('%s__%d__%s', $n, $i + 1, shift @$_), @$_
] } $arr->[$i]->ht_validate;
}
return @res;
}
1;