package GTx::APE::InputController::PLATECOUNT_InputController;

use base 'GTx::APE::InputController';

use strict;
use warnings;
use Carp;

use GTx::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.
    #################################################################
    sub createRequirements {
	my $self = shift;

	## Call the super classes createRequirements method to get the
	## basic requirements.
	$self->SUPER::createRequirements();

	## Create a Requirement that will ask the user how many plates
	## they wish to use.
	$self->unshiftRequirement
	    (new GTx::APE::InputController::Requirement
	     (arrayingEntityIndex=>-1,
	      atomicProcessIndex =>-1,
	      type               =>'Input',
	      default            =>'12',
	      description        =>'Enter the number of plates [1-12][def:12]: ',
	      checkingCode       => qr/^[1-12]/));

	## The getData method requires an EPSA_InputController method.
	$object{ $self }->{epsaInputController} =
	    new GTx::APE::InputController::EPSA_InputController
	    (atomicProcessContainer=>$self->getAtomicProcessContainer(),
	     sqlEngineObj          =>$self->getSqlEngineObj());
    }   
    
    
    #################################################################
    ## Overridden method from InputController base class.
    ## Processes a Requirment object from the requirementObjectList
    ## built by the createRequirements method.
    #################################################################
    sub process {
	my ($self,$requirementObj) = @_;

	## Check for duplicate inputs.
	if($self->isDuplicateData($requirementObj)) {
	    croak "ERROR: '",$requirementObj->getData(), "' has already been entered.\n";
	}
	
	if($requirementObj->getType() eq 'Input') {
	    ## Set the plateCount attribute based on the users requirement.
	    $object{ $self }->{plateCount} = ($requirementObj->getData() * 2) + 1;
	}else{
	    ## Get data associated with the requirement.
	    $requirementObj = eval  { $self->getData($requirementObj); };
	    if($@)                  { croak $@; }
	}

	## Push this Requirement onto the complete list.
	$self->pushCompletedRequirement($requirementObj);

	## Wait until all of the Requirement objects have been
	## returned.
	print STDERR "Testing: ",$object{ $self }->{plateCount}." == ". 
	    $self->getCompletedRequirementCount()."\n";
	if($object{ $self }->{plateCount} == $self->getCompletedRequirementCount()) {
	    ## Set the sessionId foreach ArrayingEntity via the AtomicProcessContainer.
	    eval  { ${$self->getAtomicProcessContainer()}->setSessionId($self->getSessionId()); };
	    if($@){ croak "ERROR: can't set the sessionId: $@\n";                               }
	    foreach my $req (@{$self->getCompletedRequirementList()}) {
		## Call the generic data arraying method in the base
		## class.
		$self->arrayData($req);
	    }
	    return TRUE;
	}
    }


    #################################################################
    ## Overridden method from base class to get data associated with 
    ## less well known entity types. This method creates a new       
    ## EPSA_InputController and uses its getData method as it knows 
    ## how to distinquish between an EP sense and EP antisense entity
    ## and thus get the correct information from the database.
    #################################################################
    sub getData {
	my ($self,$requirementObj) = @_;

	my $completedRequirementObj = 
	    eval  { $object{ $self }->{epsaInputController}->getData($requirementObj); };
	if($@){ croak $@; }
	
	return $completedRequirementObj;
    }


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

1;
