package APE::BarcodeFactory::ConcreteBarcode::DefaultBarcode;

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

use strict;
use warnings;
use Carp;

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

{
    my %_attributes = ();
    my %object;

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

    ##################################################################
    ### Constructor method for this object. Returns a new
    ### DefaultBarcode object.
    ##################################################################
    sub new {
	my ($proto,%args) = @_;
	my $class = ref($proto) || $proto;
	my $self  = bless {}, $class;
	%args = $self->_init(%args);
	my @leftover = keys %args;
	confess "Error: the following arguments are unknown - @leftover\n" if @leftover;
	return $self;
    }


    #################################################################
    ## 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};
	    }
	}
	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 $flushController = $self->getFlushController;
	my $barcodeType     = $self->getBarcodeType;
	my $reservedData    = $self->getReservedData;
	my $newEntityId     = $self->getEntityId;#$flushController->getNewEntityId;

	if($barcodeType eq 'DT') {
	    my $dnaName = $reservedData->[0];#$flushController->getDnaName;
	    return {Prefix  => $barcodeType,
		    Barcode => $newEntityId,
		    Name    => $dnaName,
		    Project => $barcodeType.$newEntityId,
		    Owner   => $dnaName};
	}
	elsif($barcodeType eq 'DN') {
	    my $dnaName       = $reservedData->[0];#$flushController->getReservedData;
	    my $rootTractData = $self->findRootTract;
	    if($self->getProcessId() == 6680) {
		$dnaName = "384w - " . $dnaName;
	    }
	    return {Prefix  => $barcodeType,
		    Barcode => $newEntityId,
		    Name    => $dnaName,
		    Project => $rootTractData->{tract}[1]};
	}
	elsif($barcodeType eq 'EP') {
	    my $oligoNames    = $reservedData->[0];#$flushController->getOligoNames;
	    my $rootTractData;
	    if  ($self->getProcessId == 2) { $rootTractData->{tract}[1] = "Re-array"; }
	    else                           { $rootTractData = $self->findRootTract;      }
	    return {Prefix  => $barcodeType,
		    Barcode => $newEntityId,
		    Name    => $oligoNames,
		    Project => $rootTractData->{tract}[1]};
	}

	elsif($barcodeType eq 'PC') {
	    my $epName        = $reservedData->[0];#$flushController->getReservedData;
	    my $rootTractData;
	    if($self->getProcessId == 1) {
		$rootTractData->{tract}[1] = "Cherry Pick";
	    }else{
		$rootTractData = $self->findRootTract;
	    }
	    return {Prefix  => $barcodeType,
		    Barcode => $newEntityId,
		    Name    => $epName,
		    Project => $rootTractData->{tract}[1]};
	}

	else {
	    my $rootTractData = $self->findRootTract;
	    return {Prefix  => $barcodeType,
		    Barcode => $newEntityId,
		    Name    => "Unknown type",
		    Project => $rootTractData->{tract}[1]};
	}
    }
    

    #################################################################
    ## Method to encapsulate the call to find the root tract data so
    ## that it can be called only when needed by the createBarcode
    ## method.
    #################################################################
    sub findRootTract {
	my $self = shift;
	my $rootTractData = eval { $self->SUPER::findRootTract; };
	if($@){ croak "ERROR: $@";                              }
	return $rootTractData;
    }
}

1;
