package Rose::HTML::Object::MakeMethods::Generic;
use strict;
use Carp();
use base 'Rose::Object::MakeMethods';
our $VERSION = '0.606';
sub array
{
my($class, $name, $args) = @_;
require Rose::HTML::Text;
my %methods;
my $key = $args->{'hash_key'} || $name;
my $interface = $args->{'interface'} || 'get_set';
#unless($class->can('parent'))
#{
# $methods{'parent'} = sub
# {
# my($self) = shift;
# return Scalar::Util::weaken($self->{'parent'} = shift) if(@_);
# return $self->{'parent'};
# };
#}
if($interface eq 'get_set_init')
{
my $init_method = $args->{'init_method'} || "init_$name";
$methods{$name} = sub
{
my($self) = shift;
# If called with no arguments, return array contents
unless(@_)
{
$self->{$key} = $self->$init_method() unless(defined $self->{$key});
return wantarray ? @{$self->{$key} ||= []} : $self->{$key};
}
# If called with a array ref, set new value
if(@_ == 1 && ref $_[0] eq 'ARRAY')
{
$self->{$key} = [ map { _coerce_html_object($self, $_) } @{$_[0]} ];
}
else
{
$self->{$key} = [ map { _coerce_html_object($self, $_) } @_ ];
}
return wantarray ? @{$self->{$key}} : $self->{$key};
}
}
elsif($interface eq 'get_set_inited')
{
$methods{$name} = sub
{
my($self) = shift;
# If called with no arguments, return array contents
unless(@_)
{
$self->{$key} = [] unless(defined $self->{$key});
return wantarray ? @{$self->{$key}} : $self->{$key};
}
# If called with a array ref, set new value
if(@_ == 1 && ref $_[0] eq 'ARRAY')
{
$self->{$key} = [ map { _coerce_html_object($self, $_) } @{$_[0]} ];
}
else
{
$self->{$key} = [ map { _coerce_html_object($self, $_) } @_ ];
}
return wantarray ? @{$self->{$key}} : $self->{$key};
}
}
elsif($interface eq 'get_set_item')
{
$methods{$name} = sub
{
my($self) = shift;
Carp::croak "Missing array index" unless(@_);
if(@_ == 2)
{
return $self->{$key}[$_[0]] = _coerce_html_object($self, $_[1]);
}
else
{
return $self->{$key}[$_[0]]
}
}
}
elsif($interface eq 'get_item')
{
$methods{$name} = sub
{
my($self) = shift;
Carp::croak "Missing array index" unless(@_);
return $self->{$key}[$_[0]];
}
}
elsif($interface eq 'delete_item')
{
$methods{$name} = sub
{
my($self) = shift;
Carp::croak "Missing array index" unless(@_);
no warnings;
splice(@{$self->{$key} || []}, $_[0], 1);
}
}
elsif($interface eq 'unshift')
{
$methods{$name} = sub
{
my($self) = shift;
Carp::croak "Missing value(s) to add" unless(@_);
unshift(@{$self->{$key} ||= []}, map { _coerce_html_object($self, $_) } (@_ == 1 && ref $_[0] eq 'ARRAY') ? @{$_[0]} : @_);
}
}
elsif($interface eq 'shift')
{
$methods{$name} = sub
{
my($self) = shift;
return splice(@{$self->{$key} ||= []}, 0, $_[0]) if(@_);
return shift(@{$self->{$key} ||= []})
}
}
elsif($interface eq 'clear')
{
$methods{$name} = sub
{
$_[0]->{$key} = []
}
}
elsif($interface eq 'reset')
{
$methods{$name} = sub
{
$_[0]->{$key} = undef;
}
}
elsif($interface =~ /^(?:push|add)$/)
{
$methods{$name} = sub
{
my($self) = shift;
Carp::croak "Missing value(s) to add" unless(@_);
push(@{$self->{$key} ||= []}, map { _coerce_html_object($self, $_) } (@_ == 1 && ref $_[0] && ref $_[0] eq 'ARRAY') ? @{$_[0]} : @_);
}
}
elsif($interface eq 'pop')
{
$methods{$name} = sub
{
my($self) = shift;
if(@_)
{
my $a = $self->{$key} ||= [];
my $offset = @$a - $_[0];
return splice(@$a, $offset < 0 ? 0 : $offset)
}
return pop(@{$self->{$key} ||= []})
}
}
elsif($interface eq 'get_set')
{
$methods{$name} = sub
{
my($self) = shift;
# If called with no arguments, return array contents
unless(@_)
{
return wantarray ? (defined $self->{$key} ? @{$self->{$key}} : ()) : $self->{$key}
}
# If called with a array ref, set new value
if(@_ == 1 && ref $_[0] eq 'ARRAY')
{
$self->{$key} = [ map { _coerce_html_object($self, $_) } @{$_[0]} ];
}
else
{
$self->{$key} = [ map { _coerce_html_object($self, $_) } @_ ];
}
return wantarray ? @{$self->{$key}} : $self->{$key};
}
}
else { Carp::croak "Unknown interface: $interface" }
return \%methods;
}
sub _coerce_html_object
{
my($self, $arg) = (shift, shift);
if(!ref $arg)
{
return Rose::HTML::Text->new(text => $arg, parent => $self);
}
elsif(!$arg->isa('Rose::HTML::Object'))
{
return Rose::HTML::Text->new(text => $arg, parent => $self);
}
$arg->parent($self);
return $arg;
}
1;