package APE::FlushControllerFactory::ExoApeFlushControllerFactory;

use base 'APE::FlushControllerFactory';

$APE::FlushControllerFactory::ExoApeFlushControllerFactory::VERSION = '0.1';

use strict;
use warnings;
use Carp;

use APE::FlushControllerFactory::ConcreteFlushController::DefaultExoApeFlushController;
use APE::FlushControllerFactory::ConcreteFlushController::DT_FlushController;
use APE::FlushControllerFactory::ConcreteFlushController::DN_FlushController;
use APE::FlushControllerFactory::ConcreteFlushController::EP_FlushController;
use APE::FlushControllerFactory::ConcreteFlushController::PC_FlushController;
use ExoSeq::APE::DnaCollection_FC;

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

{
    my %_attributes = (userObj => undef);


    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};
	    }
	}

	## Requires a reference to a User object reference so the
	## concrete flush controller instance knows who is flushing.
	die "Error: reference to a User.pm object required."
	    unless $object{ $self }->{userObj} && 
	    ${$object{ $self }->{userObj}}->isa('User');

	## Register the program name instance attribute.
	$self->registerInstanceArg({'programName' => $0});

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


    #################################################################
    ## Implemented abstract method from base class. This method creates
    ## a description object depending on the process id and returns it.
    #################################################################
    sub getInstance {
	my ($self,%args) = @_;

	%args = $self->SUPER::validateInstanceRequest(%args);

	my $arrayingEntity = $args{arrayingEntity};
	my $processId      = $arrayingEntity->getParentProcessId;
	my $prefix         = $arrayingEntity->getOutPrefix;
	$args{userObj}     = $self->getUserObj;

	my $fc;

	if($prefix eq 'DT') {
	    $fc = new APE::FlushControllerFactory::ConcreteFlushController::DT_FlushController
		(%args);
	}
	elsif($prefix eq 'DN') {
	    if($processId == 6674) {
		## DNA Collection project - makes exoape backward
		## compatible with dnaCollection.pl
		$fc = ExoSeq::APE::DnaCollection_FC->new(%args);
	    }else{
		$fc = new APE::FlushControllerFactory::ConcreteFlushController::DN_FlushController
		  (%args);
	    }
	}
	elsif($prefix eq 'EP') {
	    $fc = new APE::FlushControllerFactory::ConcreteFlushController::EP_FlushController
		(%args);
	}
	elsif($prefix eq 'PC') {
	    $fc = new APE::FlushControllerFactory::ConcreteFlushController::PC_FlushController
		(%args);
	}
	else {
	    ## Return the default flush controller for the exoape project.
	    $fc = new APE::FlushControllerFactory::ConcreteFlushController::DefaultExoApeFlushController
		(%args);
	}
	warn "*** '$self' returning FlushController '$fc' for prefix '$prefix' with ppid '$processId'";
	return $fc;
    }
}

1;
