package ExoSeq::APE::InputControllerFactory;

$ExoSeq::APE::InputControllerFactory::VERSION = '0.1';

use base qw(APE::InputControllerFactory::ExoApeInputControllerFactory);
use strict;
use warnings;

use ExoSeq::APE::InputController::SortTypeIC;

=head1 NAME

ExoSeq::APE::InputControllerFactory - an APE::InputControllerFactory
for the ExoSeq project.


=head1 SYNOPSIS

use ExoSeq::APE::InputControllerFactory

my $object = ExoSeq::APE::InputControllerFactory->new
  ();

my $inputController = $object->getInstance
  (atomicProcessContainer => $apc,
   parentProcessId        => $ppid,
   rules                  => {});


=head1 DESCRIPTION

An APE::InputControllerFactory for the ExoSeq project. Instantiates
and returns concrete input controller objects based on passed
arguments.


=head1 CONSTANTS

=over 5

=item TRUE

This is a boolean true constant.

=cut

use constant TRUE  => 1;


=item FALSE

This is a boolean false constant.

=cut

use constant FALSE => 0;


=back

=head1 CONSTRUCTOR

=over 5

=item $object = ExoSeq::APE::InputControllerFactory->new(option => value,...?);

The constructor for this class calls the populateWells method (see
populateWells() method) to create as many Entity::Well objects as the
format of the plate. Override the populateWells method to use derived
instances of Entity::Well objects or to alter the number of
Entity::Well objects created.

The following arguments may be passed to the constructor so are
options for all derived classes of type Entity.

=over 5

=item atomicProcessContainer

Required. An APE::AtomicProcessContainer object that represents the
arraying process being executed.

=item parentProcessId

Required. The process id of the parent process. This is normally the
result of the APE::AtomicProcessContainer::getParentProcessId() method.

=item rules

Required. A hash reference containing rules to execute - see
APE::AtomicProcessContainer for a description of rules.

=back

=cut

my %_attributes = ();



=head2 INSTANTIATION PROCESS

The new method for this object calls the _init() method on $self. If
$self is a derived class then it's _init() method will be called
giving it the chance to remove any arguments it requires from the
%args hash. If there is no _init() method in the derived class then
the _init() method in this class is called.

Derived classes implementing a _init() method should return the %args
hash to the base class:

package Derived::Class;

sub _init {
   my ($self,%args) = @_;
   my $argument = delete $args{classArgument};
   return $self->SUPER::_init(%args);
}


=head1 METHODS

=over 10

=item $plate->_init(%args);

Private method. This method is called by the new method during object
instantiation (see the INSTANTIATION process). The method removes any
of the arguments required by the object from the %args hash and
returns it.

See the INSTANTIATION section for information on how to use this
method in a derived class.

=cut

sub _init {
    my ($self,%args) = @_;
    foreach my $arg (keys(%args)) {
	$self->{"_".$arg} = delete $args{$arg}
	  if exists $_attributes{$arg};
    }

    ## Check for required attributes.
    foreach my $requiredArg (qw//) {
	die "Error: argument '$requiredArg' is required"
	  unless $self->{"_".$requiredArg};
    }

    return $self->SUPER::_init(%args);
}


=item example_get_method

XXX fill in attribute get method documentation.

=cut

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


=item $icf->getInstance(APE::AtomicProcessContainer,$ppid,$rules)

Returns an input controller object based on the parent process id
($ppid) passed in. Validates instance arguments by calling the
APE::ControllerFactory base classes validateInstanceRequest() method.

=cut

sub getInstance {
    my ($self,%args) = @_;
    %args = $self->validateInstanceRequest(%args);
    my $parentProcessId = delete $args{parentProcessId};
    my $ic;
    if($parentProcessId == 6659) {
	$ic = ExoSeq::APE::InputController::SortTypeIC->new(%args);
    }

    else {
	$args{parentProcessId} = $parentProcessId;
	$ic = $self->SUPER::getInstance(%args);
    }
    return $ic;
}

1;

=back

=head1 ALSO SEE

APE::AtomicProcessContainer, APE::ControllerFactory,
APE::InputControllerFactory,
APE::InputControllerFactory::DefaultInputControllerFactory

=head1 AUTHOR

Simon Holroyd <holroyd@sanger.ac.uk>

=cut
