package jspell;

$ENV{'LC_CTYPE'} = $ENV{'LC_CTYPE'} || 'iso_8859_1';
use locale;

BEGIN{
use Exporter ();
@ISA=qw(Exporter);
@EXPORT = qw(&setstopwords &der &flags &nlgrep2 &nlgrep &nlgrep3 &rad 
   &fea &any2str) ;

use IPC::Open3;  # para redireccionar stdin, stdout stderr dum comando

%stop =();

chop($jspell = `which jspell`);
#$jspell = '/home/jj/bin/jspell' unless (-e $jspell );
die ("cant find jspell\n") unless (-e $jspell );

($jspelllib = $jspell) =~ s!/bin/jspell!/lib/jspell!;

chop($agrep = `which agrep`);
#$agrep = '/home/jj/bin/agrep' unless (-e $agrep );
die ("cant find agrep\n") unless (-e $agrep );

$pid1 = open3(DW,DR,DE,
        "$jspell -d port -a  -W 0 -y -o'%s!%s:%s:%s:%s'") ||
               die "cant find 'jspell' program";
my $lixo = <DR>;
$tmp="/tmp";
}

sub flags {
  my $w = shift;
  print DW "\$\"$w\n";
  my $a=<DR>;
  chop $a;
  my @b = split(/[# ,]+/,$a);
  @b;
}

sub der {
  my $w = shift;
  my @der = flags($w);
  my $old=$/;
  my %res=();
  my $command= sprintf("echo '%s'|$jspell -d port -e -o '' ",join("\n",@der));
  $/="\n";

  for (`$command`){chop;
           s/(=|, | $)//g;
           for(split){
           $res{$_}++;}
  }
  $/=$old;
  keys %res;
}

sub setstopwords {
  for(@_){ $stop{$_}=1;}
}

sub nlgrep {
        my $proc=shift;
        my $file_list=join(' ',@_);

        open(TMPp,"> $tmp/_jspell$$") || die(" can't open tmp ");
        for (der($proc)) { print TMPp "$_\n" unless $stop{$_}; }
        close(TMPp);

        my @res=();
        for (`$agrep -h -i -w -f $tmp/_jspell$$ $file_list`) {
                push(@res,$_);
        }
        unlink "$tmp/_jspell$$";
        @res;
}

sub nlgrep3 {
        my $proc=shift;
        my $qt=shift;
        my $file_list=join(' ',@_);

        open(TMPp,"> $tmp/_jspell$$") || die(" can't open tmp ");
        for (der($proc)) { print TMPp "$_\n" unless $stop{$_}; }
        close(TMPp);

        my @res=();
        for (`$agrep -h -i -w -f $tmp/_jspell$$ $file_list | head -$qt`) {
                push(@res,$_);
        }
        unlink "$tmp/_jspell$$";
        @res;
}

sub nlgrep2 {
        my $proc=shift;
        my $old = $/;
        my $sep=shift;
        my $file_list=join(' ',@_);
        my $a;

        open(TMPp,"> $tmp/_jspell$$") || die(" can't open tmp\n ");
        for (der($proc)) { print TMPp "$_\n" unless $stop{$_}; }
        close(TMPp);

        my @res=();
        $/=$sep;
        open(TMPp,"$agrep -d '$sep' -h -i -w -f $tmp/_jspell$$ $file_list | ") or
                die "cant agrep :-((";

        while ($a=<TMPp>){
                chomp($a);
                push(@res,$a);
        }
        $/ = $old;
        close(TMPp);
        unlink "$tmp/_jspell$$";
        @res;
}

sub rad {my $w =shift;
  if ($w =~ /\!/){return ();}
  my %rad = ();
  print DW " $w\n";
  for ($a_=<DR>;($a_ ne "\n");$a_=<DR>){       # l^e as respostas
      chop $a_;
      %rad = ($a_ =~ m/(?: |:)([^ =:,!]+)(\!)/g ) ;
      }
  (keys %rad);
   }

sub fea{my $w =shift;
  if ($w =~ /\!/){return ();}
  my  @r=();
  print DW " $w\n";
  my $a=<DR>;
  for (;($a ne "\n");$a=<DR>){       # l^e as respostas
    for($a){
      chop;
      my ($lixo,$clas) = /(.*?):(.*)/;
      for(split(/, /,$clas)){
        ($rad,$cla)=/(.*?)\!:*(.*):*$/;
        $cla =~ s/:+/,/g;
        my %ana = split(/[=,]/,$cla );

        if($lixo =~ /^&/) { $rad =~ s/.*?= //;
                            $ana{"unknown"} = 1 ; }
        if($rad ne "" )   { push(@r,+{"rad" => $rad, %ana});
           }}
    }}
  (@r);
}

sub any2str {
   my ($r,$i)= @_;
   my $ind = ($i >= 0)? (" " x $i) : "";
   if (ref($r) eq "HASH" )
      { "$ind {". hash2str($r,abs($i)+3) . "}" }
   elsif (ref($r) eq "ARRAY")
      { "$ind [\n" . join("\n", map (any2str($_,abs($i)+3), @$r)) . "]" }
   else {"$ind$r"}
}

sub hash2str {my($r,$i)=($_[0],$_[1]);
   my $c="";
   for(keys %$r) {$c .= "\n". any2str($_,$i). " => ". any2str($r->{$_},-$i);}
   $c;}

=head1 Name

Jspell.pm a perl module for natural language processing

=head1 Synopsis


  der(word)             		-> list of derived words
  flags(word)           		-> list of possible roots and flags
  nlgrep(word,filename*) 		-> list of lines
  nlgrep2(word,RecSeparator,filename*) 	-> list of lines
  nlgrep3(word,N,filename*)	 	-> list up to N lines
  setstopwords(word*)	 	        -> words to be avoid in nlgrep
  rad(word)             		-> list of possible normalized words
  fea(word)             		-> list of analisis

=head1 Description

jspell.pm uses the "jspell" program in background.

=head1 See also

  jspell

=head1 Example

  #!/usr/local/bin/perl

  use jspell;
  my $a;

  while(<>){
    chop;
    $a= { NAME => $_,
          FLA  => [flags($_)],
          DER  => [der($_)],
          PRO  => [nlgrep($_,"/home/jj/public_html/pln/proverbio.dic")] };

    $a->{RAD}    = [rad($_)];
    $a->{JSPELL} = [fea($_)];

    print any2str($a,2);
  }

=cut


1;
