################################################################## 
## Class Name: DefaultFlushController                           ##
##                                                              ##
## Description: This class is the default concrete controller   ##
##              class that is instantiated and returned by the  ##
##              default flush controller factory.               ##
##                                                              ##
## Arguments: None.                                             ##
##                                                              ##
##################################################################
package APE::FlushControllerFactory::ConcreteFlushController::DefaultFlushController;

use base 'APE::FlushControllerFactory::ConcreteFlushController::FlushController';

$APE::FlushControllerFactory::ConcreteFlushController::DefaultFlushController::VERSION = '0.1';

use strict;
use warnings;
use Carp;

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

{
    my %_attributes = ();

    my %object;

    ## Autoloader wannabe. Inserts the sub calls that I want to be
    ## accessible into the symbol table.
    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};
	    }
	}

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

    
    #################################################################
    ## Method to flush the arrayed data to STDOUT. 
    #################################################################
    sub flush {
	my $self = shift;
	eval { 
	    my $entity    = $self->getArrayingEntity;
	    my $sessionId = $entity->getSessionId();
	    my $atomicProcessCount = 0;
	    warn "Creating a '". $entity->getOutDescription(). 
                "' (".$entity->getOutPrefix(). ") entity - " .
		"sessionId: $sessionId ....\n";
	    foreach my $atomicProcess (@{$entity->getAtomicProcessList()}) {
		my $aph = $atomicProcess->getArrayPatternHash();
		my $arrayPatternCount = 0;
		foreach my $inMapId (keys(%{$aph})) {
		    foreach my $arrayPattern 
                        (sort{$a->getOutMapId() 
                                  <=> $b->getOutMapId()} 
                         @{$aph->{$inMapId}}) {
                            my $inMapId  = $arrayPattern->getInMapId;
                            my $outMapId = $arrayPattern->getOutMapId;
                            foreach my $outData 
                                (@{$arrayPattern->getOutData}) {
                                    warn "\tInDataId: ". 
                                        $atomicProcess->getInDataId . 
                                        " -> In '$inMapId' to Out ".
                                        "'$outMapId' with data ".
                                        "'@$outData'\n";
                            }
                            $arrayPatternCount++;
                        }
		}
		$atomicProcessCount++;
		warn "\tArrayPattern count: $arrayPatternCount\n";
	    }
	    warn "AtomicProcess count: $atomicProcessCount\n";
	};
	if($@) { croak $@; }
    }
    
    
    #################################################################
    ## Method offered to subclasses. Further functionality to come.
    #################################################################
    sub beginTransaction    {}
    sub rollbackTransaction {}
    sub commitTransaction   {}
    sub getDescription      { return "DefaultFlushController class"; }
    
    #################################################################
    ## Method to destory this object.
    #################################################################
    sub DESTROY { 
	my $self = shift;
	delete $object{ $self };
    }
}

1;
