##
# Copyright (c) 2008 Health Market Science, Inc
##
package _TMP;
use strict;
use warnings;
our $CVS_ID = '$Id: emacs-utils.el,v 1.82 2008/07/11 13:35:40 kburton Exp $'; #'
our $VERSION = ( qw$Revision: 1.82 $ )[1];

use Data::Dumper qw(Dumper);

$|++;

my $morse = <<EOM;
    A  .-          N  -.          1  .----       .  .-.-.-
    B  -...        O  ---         2  ..---       ,  --..--
    C  -.-.        P  .--.        3  ...--       ?  ..--..
    D  -..         Q  --.-        4  ....-       (  -.--.
    E  .           R  .-.         5  .....       )  -.--.-
    F  ..-.        S  ...         6  -....       -  -....-
    G  --.         T  -           7  --...       "  .-..-.
    H  ....        U  ..-         8  ---..       _  ..--.-
    I  ..          V  ...-        9  ----.       '  .----.
    J  .---        W  .--         0  -----       :  ---...
    K  -.-         X  -..-        /  -..-.       ;  -.-.-.
    L  .-..        Y  -.--        +  .-.-.       \$  ...-..-
    M  --          Z  --..        =  -...-
EOM

# the $ is a 'gotcha' if
# you have warnings turned on, you'll find that it needs to be backslashed as above :)

# "

my $signature = "$0 (encode|decode) input.txt output.txt";

sub run {
  my($self,$cmd,$inputFile,$outputFile) = @_;

  my %dispatch = (
                  'encode' => 'encodeFile',
                  'decode' => 'decodeFile'
                 );

  die "You must supply either encode or decode"              unless $cmd;
  die "You must supply either encode or decode"              unless exists $dispatch{$cmd};
  die "You must supply an input file: $signature\n"          unless $inputFile;
  die "You must supply an output file: $signature\n"         unless $outputFile;
  die "Input file ($inputFile) does not exist: $signature\n" unless -e $inputFile;

  # print "morse: $morse\n";
  # my @pairs = $self->parseTable($morse);
  # print "Table: \n";
  # print Dumper(\@pairs),"\n";

  my $method = $dispatch{$cmd};
  $self->$method($inputFile,$outputFile);
}

sub encodeFile {
  my($self,$inputFile,$outputFile) = @_;

  my $map = { map { $_->[0] => $_->[1] } $self->parseTable($morse) };
  #print "Encode: ", Dumper($map),"\n";
  my $out = $self->openFile($outputFile,">");

  foreach my $line (split /(\n)/, $self->readFile($inputFile)) {
    $line = uc $line;
    foreach my $ch (split //, $line) {
      print $out (exists $map->{$ch} ? $map->{$ch} : $ch), ", ";
    }
  }
}

sub decodeFile {
  my($self,$inputFile,$outputFile) = @_;

  my $map = { map { $_->[1] => $_->[0] } $self->parseTable($morse) };
  #print "Decode: ", Dumper(\%decode),"\n";

  my $out = $self->openFile($outputFile,">");

  foreach my $line (split /(\n)/, $self->readFile($inputFile)) {
    $line = uc $line;
    foreach my $ch (split /, /, $line) {
      print $out (exists $map->{$ch} ? $map->{$ch} : $ch);
    }
  }
}


sub readFile {
  my($self,$file) = @_;
  local $/ = undef;
  my $fh = $self->openFile($file);
  my $d = <$fh>;
  close $fh;
  return $d;
}

sub openFile {
  my($self,$file,$mode) = @_;
  $mode = '<' unless defined $mode;
  my $fh;
  unless (open $fh, $mode, $file) {
    die "Error opening file: '$mode' '$file' : $!\n";
  }
  return $fh;
}

sub parseTable {
  my($self,$table) = @_;

  map { 
    my @parts = grep { length } split /\s+/, $_;
    my @ret;
    while (@parts) {
      push @ret, [ shift @parts, shift @parts ];
    }
    @ret
  } grep { $_ !~ /^\s+$/ } split /\n/, $table;
}

1;

_TMP->run(@ARGV);
