
package Lingua::PT::NamedEntity::JSpellFilter;

use warnings;
use strict;
use locale;

use jspell;

use Lingua::PT::NamedEntity;
use Lingua::PT::NamedEntity::JSpellFilters qw(%filters);

require Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw();
our @EXPORT_OK = qw();
our @EXPORT_TAGS = qw(:DEFAULT => []);

our $version = "0.01";


use Data::Dumper;

sub new {
    my $proto = shift || __PACKAGE__;
    my $class = ref($proto) || $proto;

    my %options = (
		   dict => "port",
		   global => {},
		   pipeline => [],
		   
		   @_);

    die "No filters to apply" if @{$options{pipeline}} == 0;

    my $self = {jspell => jspell::new($options{dict}),
		ne => Lingua::PT::NamedEntity::new(),
		global => $options{global},
		base_pipeline => $options{pipeline},
		need_reset => 1,
	    };
    $self->{jspell}->setmode("-nm"); # desactivar near misses
    bless($self, $proto);

    #$self->reset();

    return $self;
}

sub reset {
    my $self = shift;

    my %options = (pipeline => $self->{base_pipeline},
		   @_);

    #$self->cleanup();

    # Calcular pipeline
    my @cleanup;
    my @pipeline = map {
	my $filter = $_;

	die "Filtros disponíveis: ".join(", ", keys %filters)."\n"
	    if $filter->{name} eq "help";
	die "Filtro inexistente: '$filter->{name}'\n"
	    if not exists $filters{$filter->{name}};

	#print STDERR "START FILTER SETUP ($filter->{name})\n";
	#print STDERR Dumper($options{pipeline});
	# BUG1 esta chamada pode fazer com que o valor de retorno deste bloco seja undef ?????????
	#      (filter_names_gazetteer_setup)
	$filters{$filter->{name}}->{setup}->(global => $self->{global}, %{$filter->{options}})
	    if defined $filters{$filter->{name}}->{setup};
	#print STDERR "END FILTER SETUP ($filter->{name})\n";
	#print STDERR Dumper($options{pipeline});

	push @cleanup, {call => $filters{$filter->{name}}->{cleanup}, options => $filter->{options}}
	    if defined $filters{$filter->{name}}->{cleanup};

	{filter => $filters{$filter->{name}}->{filter}, options => $filter->{options}}
    } @{$options{pipeline}};

    $self->{pipeline} = \@pipeline;
    $self->{cleanup} = \@cleanup;
    $self->{chunks} = [];
    $self->{part} = 0;
    
    $self->{need_reset} = 0;
}

sub has_chunks {
    my $self = shift;

    return scalar(@{$self->{chunks}});
}

sub chunks {
    my $self = shift;
    return $self->{chunks};
}

sub process {
    my $self = shift;

    my %options = (text => undef,
		   @_);
    my $text = $options{text};

    $self->reset() if $self->{need_reset};

    die "JSpellFilter::process needs text!\n" if not defined $text;

    $self->{part}++;

    $self->{ne}->process(text => $text,
			 perChunk => sub { push @{$self->{chunks}}, {@_, part => $self->{part}} });
}

sub apply {
    my $self = shift;

    $self->{chunks} = $_->{filter}->(chunks => $self->{chunks},
				     global => $self->{global},
				     jspell => $self->{jspell},
				     %{$_->{options}},
				     )
	for @{$self->{pipeline}};
    $self->cleanup();
}

sub cleanup {
    my $self = shift;

    $_->{call}->(chunks => $self->{chunks},
		 global => $self->{global},
		 jspell => $self->{jspell},
		 %{$_->{options}},
		 )
	for @{$self->{cleanup}};
    $self->{need_reset} = 1;
}


1;

__END__
