package Yaa::LookupMap::Result;

use strict;
use vars qw ($VERSION $Error);

######################################################
#               OBJECT CONSTRUCTOR                   #
######################################################

sub new {
	my $proto = shift;
	my $class = ref($proto) || $proto;
	my $self = {};

	##################################################
	#               PUBLIC VARS                      #
	##################################################
	
	# last error
	$self->{error} = undef;

	######################################################
	#                 PRIVATE VARS                       #
	######################################################

	# result table
	$self->{_results} = qw();
	
	# current result position
	$self->{_result_pos} = -1;

	bless($self, $class);
	return $self;
}

####################################################
#               PUBLIC METHODS                     #
####################################################

sub error {
	my ($self) = @_;
	return $self->{error};
}

sub clear {
	my ($self) = @_;

	$self->{_result} = qw();
	$self->{_result_num} = 0;
	$self->{_result_pos} = -1;

	return 1;
}

sub addMatch {
	my ($self, $match) = @_;
	
	if (! defined $match) {
		$self->{error} = "Cannot add undefined match. Match should be hash reference.";
		return 0;
	}
	elsif (ref $match ne 'HASH') {
		$self->{error} = "New match was not given as hash reference.";
		return 0;
	}

	push(@{$self->{_results}}, $match);
	return 1;
}


sub getNumMatches {
	my ($self) = @_;
	
	return ($#{$self->{_results}} + 1);
}

sub getCurrentPosition {
	my ($self) = @_;
	return $self->{_result_pos};
}

sub getNextMatch {
	my ($self) = @_;
	my $next_pos = $self->{_result_pos} + 1;

	unless ($self->_validatePosition($next_pos)) {
		$self->{error} = "There is no next match.";
		return undef;
	}
	
	return $self->{_results}[$next_pos];
}

sub getPrevMatch {
	my ($self) = @_;
	my $prev_pos = $self->{_result_pos} - 1;

	unless ($self->_validatePosition($prev_pos)) {
		$self->{error} = "There is no previous match.";
		return undef;
	}
	
	return $self->{_results}[$prev_pos];
}

sub getFirstMatch {
	my ($self) = @_;
	unless ($self->_validatePosition(0)) {
		$self->{error} = "There is no first match.";
		return undef;
	}
	
	return $self->{_results}[0];
}

sub getLastMatch {
	my ($self) = @_;
	my $last_pos = self->getNumMatches() - 1;
	unless ($self->_validatePosition($last_pos)) {
		$self->{error} = "There is no last match.";
		return undef;
	}
	
	return $self->{_results}[$last_pos];
}

sub getMatchByPos {
	my ($self, $pos) = @_;
	return undef unless ($self->_validatePosition($pos));
	
	return $self->{_results}[$pos];
}

sub moveNext {
	my ($self) = @_;
	return 0 unless ($self->_validatePosition($self->{_result_pos} + 1));
	$self->{_result_pos}++;
	return 1;
}

sub movePrev {
	my ($self) = @_;
	return 0 unless ($self->_validatePosition($self->{_result_pos} - 1));
	$self->{_result_pos}--;
	return 1;
}

sub moveFirst {
	my ($self) = @_;
	return 0 unless ($self->_validatePosition(0));
	$self->{_result_pos} = 0;
	return 1;
}

sub moveLast {
	my ($self) = @_;
	my $last_pos = $self->getNumMatches() - 1;
	return 0 unless ($self->_validatePosition($last_pos));
	$self->{_result_pos} = $last_pos;
	return 1;
}

sub moveToPos {
	my ($self, $pos) = @_;
	return 0 unless ($self->_validatePosition($pos));
	$self->{_result_pos} = $pos;
	return 1;
}

sub getMatch {
	my ($self) = @_;
	return $self->{_results}[$self->{_result_pos}];
}

sub getMatchValueByKey {
	my ($self, $key) = @_;

	if (! defined $key) {
		$self->{error} = "Lookup key not defined.";
		return undef;
	}
	elsif (! defined $self->{_results}[$self->{_result_pos}]->{$key}) {
		$self->{error} = "Lookup key not found in a result match.";
		return undef;
	}
	
	return $self->{_results}[$self->{_result_pos}]->{$key};
}

####################################################
#               PRIVATE METHODS                    #
####################################################

sub _validatePosition {
	my ($self, $pos) = @_;

	if (! defined $pos) {
		$self->{error} = "Position was not defined.";
		return 0;
	}
	elsif ($pos < 0) {
		$self->{error} = "Position cannot be less than 0.";
		return 0;
	}
	elsif ($pos > ($self->getNumMatches() -1)) {
		$self->{error} = "Too big position given.";
		return 0;
	}
	
	return 1;
}

1;
