package APE::InputController::DTUNIQUEIND_InputController;

use base 'APE::InputController';

use strict;
use warnings;
use Carp;

use APE::InputController::Requirement;

use constant TRUE  => 1;
use constant FALSE => 0;

{
    my %_attributes = ( 
			## ** Add your object attributes here **
			## They will automatically be given a get method.
			## e.g. attribute 'personForename' can be accessed
			## using getPersonForname(). There are no automatic 
			## set routines, they must be declared or the attribute 
			## value must be parsed in the constructor 
			## i.e new InputController(personForename=>'Simon');
		       );

    my %object;
    
    foreach my $attName (keys(%_attributes)) {
	no strict 'refs';
	*{__PACKAGE__ . "::get\u$attName"} = sub { $object{ $_[0] }->{$attName} }
    }


    #################################################################
    ## Initialise the objects private attributes. The argument is
    ## deleted as it is found, initialised and set.
    #################################################################
    sub _init {	
	my ($self,%args) = @_;
	foreach my $attName (keys(%args)) {
	    if(exists($_attributes{$attName})) { 
		$object{ $self }->{$attName} = delete $args{$attName};
	    }
	}   

	## Set the description as this is a specialised InputController.
	$args{description} = "Template_InputController - no description set.";
	
	return $self->SUPER::_init(%args);
    }
    

    #################################################################
    ## Overridden method from InputController base class.
    ## Processes a Requirment object from the requirementObjectList
    ## built by the createRequirements method.
    #################################################################
    sub process {
	my ($self,$requirementObj) = @_;
	## Call supers process method that will call this objects
	## getData method if the Requirement object is not type Input.
	eval { $self->SUPER::process($requirementObj); };
	if($@){ croak $@; }


	## Check if the individuals DNA has been used before.
	if(my $duplicateIndReq = $self->hasDuplicateInd($requirementObj)) {
	    croak "ERROR: '" . $requirementObj->getData() .
		"' contains the same individuals DNA as '" .
		$duplicateIndReq->getData() . "'\n";;
	}
    }


    #################################################################
    ## Method to find if the Requirement object currently being
    ## processed has the same id_ind as a previously entered DNA tube
    ## entity. All DT tubes should contain a single individuals DNA
    ## sample.
    #################################################################
    sub hasDuplicateInd {
	my ($self,$requirementObj) = @_;
	return if $requirementObj->getType() eq 'Input';
	my $idInd = $requirementObj->getDataStore()->[0][4];
	foreach my $reqCon (@{$self->getRequirementContainerList}) {
	    next if $reqCon->isInput;
	    foreach my $req (@{$reqCon->getRequirementList}) {
		next if $req->getType eq 'Input';
		next if $req == $requirementObj;
		my $dataStore = $req->getDataStore;
		next unless $dataStore;
		if($req->getDataStore()->[0][4] == $idInd) {
		    return $req;
		}
	    }
	}
    }


    #################################################################
    ## Method to destroy this object.
    #################################################################
    sub DESTROY {
	my $self = shift;
	delete $object{$self};
	$self->SUPER::DESTROY;
    }
}

1;
