package FormValidator::Simple::Results;
use strict;
use base qw/Class::Accessor::Fast/;
use FormValidator::Simple::Result;
use FormValidator::Simple::Exception;
use FormValidator::Simple::Constants;

__PACKAGE__->mk_accessors(qw/_records/);

sub new {
	my $class = shift;
	my $self  = bless { }, $class;
	$self->_init(@_);
	return $self;
}

sub _init {
	my $self = shift;
	$self->_records( { } );
}

sub register {
	my ($self, $name) = @_;
	$self->_records->{$name}
		||= FormValidator::Simple::Result->new($name);
}

sub record {
	my ($self, $name) = @_;
	FormValidator::Simple::Exception->throw(
		qq/result of "$name" isn't set./
	) unless exists $self->_records->{$name};
	return $self->_records->{$name};
}

sub set_result {
    my ($self, $name, $type, $result) = @_;
    $self->register($name);
    $self->record($name)->set($type, $result);
}

sub has_blank {
	my $self = shift;
	foreach my $record ( values %{ $self->_records } ) {
		return TRUE if $record->is_blank;
	}
	return FALSE;
}

*has_missing = \&has_blank;

sub has_invalid {
	my $self = shift;
	foreach my $record ( values %{ $self->_records } ) {
		return TRUE if $record->is_invalid;
	}
	return FALSE;
}

sub valid {
	my ($self, $name) = @_;
	if ($name) {
		return $self->record($name)->is_valid
			 ? $self->record($name)->data : FALSE;
	}
    else {
		my @valids
            = sort { $a cmp $b    }
			  map  { $_->name     }
			  grep { $_->is_valid }
			       values %{ $self->_records };

		return wantarray ? @valids : \@valids;
	}
}

sub blank {
	my ($self, $name) = @_;
	if ($name) {
		return $self->record($name)->is_blank ? TRUE : FALSE;
	}
    else {
		my @blanks
            = sort { $a cmp $b    }
			  map  { $_->name     }
			  grep { $_->is_blank }
			       values %{ $self->_records };

		return wantarray ? @blanks : \@blanks;
	}
}

*missing = \&blank;

sub invalid {
	my ($self, $name, $constraint) = @_;
	if ($name) {
		if ($constraint) {
			$self->record($name)->is_invalid_for($constraint)
				? TRUE : FALSE;
		}
        else {
			$self->record($name)->is_invalid
				? TRUE : FALSE;
		}
	}
    else {
		my @invalids
            = sort { $a cmp $b      }
			  map  { $_->name       }
			  grep { $_->is_invalid }
			       values %{ $self->_records };

		return wantarray ? @invalids : \@invalids;
	}
}

1;
__END__

