use strict;
use warnings;

use vars qw($completionRequest);

my $oldCompleter=$completionRequest;

#TODO: efficient storage
my @words;


sub addCompletionWord {
  my $word=shift;
  unless (grep {$word eq $_} @words) {
    #prevent duplicates
    push @words,$word;
  }
}

sub complete {
  my $word=shift;

  my @matches=grep {$word eq substr $_,0,length $word; } @words;
  if (scalar(@matches)==1) {
    $word=$matches[0];
  } elsif (scalar(@matches)>1) {
     my $shortest=$matches[0];
     foreach my $match (@matches) {
       my $ns=$word;
       # hmm, geht das schneller?
       for(my $i=length($word); $i < length($shortest) and $i < length($match); ++$i) {
	 if (substr($shortest,$i,1) eq substr($match,$i,1)) {
	   $ns.=substr($shortest,$i,1);
	 } else {
	   last;
	 }
       }
       if (length($ns) < length($shortest)) {
	 $shortest=$ns;
       }
     }
     if ($word eq $shortest) {
       statusWindow()->setFGColor(GREEN);
       statusWindow()->setIntensive(1);
       statusWindow()->print("\nPossible Completions:\n");
       statusWindow()->setIntensive(0);
       statusWindow()->print('"'.join('", "',@matches)."\"\n");
       statusWindow()->resetAttributes();
     }
    $word=$shortest;
  }
  return $word;
}

$completionRequest=sub {
  my $iline = focusedInputLine();
  my ($text,$line,$col)=($iline->getText(), $iline->getCursorY(),
			 $iline->getCursorX());
  # call old one first
#  if (ref $oldCompleter eq 'CODE') {
#    ($text,$line,$col)= &$oldCompleter($text,$line,$col);
#  }

  my @lines=split /\n/,$text;
  $lines[$line]="" if not defined $lines[$line];

  my $front=substr $lines[$line],0,$col;
  my $back=substr $lines[$line],$col;
  my $word="";
  if ($front =~ s/(\w+)$//) {
    $word=complete($1);
    

  }

  $lines[$line]=$front.$word.$back;
  $col=length($front) + length($word);
  $text=join "\n",@lines;

  $iline->setText($text);
  $iline->setCursorY($line);
  $iline->setCursorX($col);
};

delKeyBinding('^Completion$');
addKeyBinding("Completion", ".000.... Tab", $completionRequest);

# example for an Alias filling the lexicon.
#addAlias("COMPLETION",qr/.?/,sub {
#	   my $line=shift;
#	   foreach my $word (split /\W+/,$line) {
#	     addCompletionWord($word) if length($word)>2;
#	   }
#	   return $line;
#	 });

