package APE::BarcodeFactory::ConcreteBarcode::SequenceBarcode;

use base 'APE::BarcodeFactory::ConcreteBarcode::Barcode';

use strict;
use warnings;
use Carp;

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

{
    my %_attributes = ( sequence => {} );
    
    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};
	    }
	}   

	## This concrete Barcode requires the sequence to be set.
	croak "ERROR: argument sequence has not been set."
	    unless $object{ $self }->{sequence};

	## The sequence argument should be a ref to a hash.
	croak "ERROR: argument sequence should be a reference to a hash containing sequence data."
	    unless ref $object{ $self }->{sequence} eq 'HASH';


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


    #################################################################
    ## Implemented abstract method from the super class. This method 
    ## creates and returns the actual description - this is what it's
    ## all about.
    #################################################################
    sub createBarcode {
	my $self = shift;
	my $sequenceData    = $self->getSequenceData;
	my $newEntityId     = $self->getEntityId;
	my $barcodeType     = $self->getBarcodeType;
	my $reservedData    = $self->getReservedData;
	my $name            = $reservedData->[0];
	return {Prefix  => $barcodeType,
		Barcode => $newEntityId,
		Name    => $name,
		Project => $sequenceData};
    }


    #################################################################
    ## Method to find the sequence information based on the sequence 
    ## hash used to create this object. The sequence data should be  
    ## a hash ref with process Id numbers as keys and the required 
    ## text as the value.
    ##
    ## { 6616 => 'Plate A', 6617 => 'Plate B' }
    ##
    #################################################################
    sub getSequenceData {
	my $self = shift;
	my $flushController = $self->getFlushController;
	my $entity          = $flushController->getArrayingEntity;
	my $apList          = $entity->getAtomicProcessList;
	my $sequence        = $self->getSequence;
	foreach my $atomicProcess (@$apList) {
	    my $processId = $atomicProcess->getProcessId;
	    if(exists($sequence->{$processId})) {
		return $sequence->{$processId};
	    }
	}
	return "Unknown factory sequence";
    }
}

1;
