#!/usr/bin/perl -w 
#
#  This is a rough hack to get to the 1.0 phase 
#
# $Id: mail2procmail.pl,v 1.28 2001/11/03 21:57:48 timball Exp $ 

use Curses;
use Curses::Widgets qw(:all);
use strict;
#use Date::Calc qw(Add_Delta_Days);
#@tmfuture = Ad_Delta_DHMS(@today_tm, $date_h_year{$sel}, $date_h_month{$sel},
#$date_h_day{$sel}, $date_h_hours{$sel}, $date_h_min{$sel}, $date_h_sec{sel});

# Main window handle
my $mwh = undef;

# global... hrm..
my @recipe = (":0:\n");
my %headers = ();

# List of header that we want to ignore.  Salt to taste.
my @ignore_tags = (
    'Content-Disposition',
    'Content-Length',
    'Content-Type',
    'Date',
    'From ',
    'In-Reply-To',
    'Lines',
    'MIME-Version',
    'Received',
    'References',
    'Status',
    'X-Face',
    'X-From_'
);

sub clock() {
  # Update the clock in the upper right hand corner of the screen
    $mwh->standout();
    $mwh->addstr(0, ($COLS - 26), scalar (localtime));
    $mwh->standend();
    $mwh->refresh();
}

sub dialog($$$) {
    my ($thiswh, $text, $colour) = @_;
    my (@lines) = split(/\n/, $text);
    my ($i, $j, $line);

    for ($i = 1; $i < $#lines; $i++) {
        if (defined($lines[$i - 1])) {
            $line = $lines[$i -1] . "\n";
        } else {
            $line = "\n";
        }

        $thiswh->addstr($i, 2, $line);
    }

    select_colour($thiswh, $colour);
    $thiswh->box(ACS_VLINE, ACS_HLINE);
    $thiswh->attrset(0);

    touchwin($mwh);
    $mwh->refresh();
}

sub main_win() {
    noecho();
    halfdelay(5);
    $mwh->keypad(1);
    $mwh->erase();

    select_colour($mwh, 'red');
    $mwh->attrset(0);
 
    $mwh->standout();
    $mwh->addstr(0, 1, "mutt2procmail");
    $mwh->standend();
}

BEGIN: {
  # Do all this stuff first and foremost...
  # parse the mail coming to me on stdin and fill header w/ information
  # I should catch this if mail given has *NO* headers FIXME
    use Mail::Header;
 
  # Grab a copy of all the headers from the email message on stdin.
    my $i = 0;
    my $eheader = new Mail::Header \*STDIN;

  # Remove empty headers since filtering on them is pretty pointless.
    $eheader->cleanup();

  # Remove tags we don't want to filter on.
    $eheader->delete($_) foreach (@ignore_tags);

  # Make a hash containing the remaining headers.
    foreach (sort($eheader->tags())) {
        chomp(my $foo = $eheader->get($_));
        $headers{$i++} = "$_: $foo";
    }
}

MAIN: {
 
  # Hack to goto users homedir
    chdir $ENV{HOME} or die "Can't do change to home dir\n";

    # make the default directory to put things in
    if ( ! -d "$ENV{HOME}/.procmail/m2proc" ) {
        mkdir("$ENV{HOME}/.procmail/m2proc", 0700);
    }

    # read in config file
    if ( -f "$ENV{HOME}/.m2procrc" ) {
       do "$ENV{HOME}/.m2procrc";
    }
    else {
        # make a default ~/.m2procrc
        # FIXME
    }


  # Now dup STDIN to be from the tty so that we can use input from user
    open(MYTTY, "</dev/tty");
    open(STDIN, "<&MYTTY");

  # Initialize curses and create the main window.
    $mwh = new Curses;
    main_win();

  # Create our windows.
    # This is the top dialog window handle no user input
    my $dwh = $mwh->subwin(4, $COLS - 2, 1, 1);
    # This is the bottom dialog window handle no user input
    my $swh = $mwh->subwin(8, $COLS - 2, $LINES - 9, 1);

    my $text = "Please select the headers that you would like to filter on.\n" .
      "The list box will scroll. Press 'q' when done selecting.\n\n.";
    dialog($dwh, $text, 'yellow');

  # Let the user select the headers to filter on.
    my $sel = 0;
    do {
      # Display the current recipe.
        dialog($swh, "@recipe\n.", 'yellow');
      #  dialog($swh, join("h", @recipe), 'yellow');

      # Display the list of headers.
        ($text, $sel) = list_box('window'	=> $mwh,
                                 'title'	=> 'Choose one',
                                 'ypos'		=> 5,
                                 'xpos'		=> 1,
                                 'lines'	=> 8,
                                 'cols'		=> $COLS - 4,,
                                 'list'		=> \%headers,
                                 'border'	=> 'green',
                                 'selected'	=> $sel,
                                 'function'	=> \&clock);

      # Allow the list of headers to be traversed using normal vi/emacs
      # keybindings.
        if ($text eq 'k' || $text eq "\cP") {
            $sel -= 1;
        } elsif ($text eq 'j' || $text eq "\cN") {
            $sel += 1;
        }

        if ($text eq "\n" || $text eq 'l') {
          # Add this header to the recipe.
            push(@recipe, "* ^$headers{$sel}\n");

          # Delete this header from the hash.
            delete($headers{$sel});

          # Ugly hack to move the selection index back to zero so that it
          # doesn't go out of bounds.  Could be smarter about this and only
          # reset the value of 'sel' if it runs off the end of the hashtable.
            $sel = 0;

          # Yet another ugly hack!  If the hash becomes empty you can't choose 
          # any more headers to filter on so do an implicit quit.
            $text = 'q' if (keys(%headers) == 0);
        }

      # Sanity check on sel to make sure we didn't run off either end of the
      # list.
        $sel = 0 if ($sel == keys(%headers));
        $sel = keys(%headers) - 1 if ($sel == -1);

    } while ( $text ne 'q' );

  # To quiet use strict.
    my $content;

  # Get the name of the mailbox to filter to.
    dialog($dwh, "What mailbox will mail go to?\n\n\n.", 'yellow');
    ($content, $text) = input_box('title'	=> "Mailbox",
                                  'prompt'	=> "Enter mailbox name:",
                                  'border'	=> "green",
                                  'content' => "\$MAILDIR/",
                                  'function'	=> \&clock);
    # user hit cancel
    exit() if ($text == 0);
    # otherwise you hit okay and keep going
    push(@recipe, "$content\n\n");

    $text = "Edit the recipe to suit your needs.\n[tab] to continue.\n\n.";
    dialog($dwh, $text, 'yellow');

  # This calls the Text field in interactive, edit mode
    ($text, $content) = txt_field('window'	=> $mwh,
                                  'title'	=> 'Edit Recipe',
                                  'xpos'	=> 1,
                                  'ypos'	=> 5,
                                  'lines'	=> 17,
                                  'cols'	=> $COLS - 4,
                                  'content'	=> join("", @recipe),
                                  'border'	=> 'green',
                                  'function'	=> \&clock);
    #
    # put everthing back into the @recipe array for later
    @recipe = split(/(\n)/, $content);
    
    # refresh main window
    main_win();

    # deal w/ aging the thing
    $text = "How long are the recipes good for\n[tab] to continue.\n\n.";
    dialog($dwh, $text, 'yellow');

    $swh = $mwh->subwin(10, $COLS - 2, $LINES - 11, 1);
    dialog($swh, "@recipe\n.", 'cyan');
    #dialog($swh, join("\n", @recipe), 'cyan');

    # parellel hashes to deal w/ dates... this is, as well, a hack
    my %date_h = ( 1 => "days",
                   2 => "weeks",
                   3 => "months",
                   4 => "years",
                   5 => "forever",
                   6 => "custom");

    my %date_mult = ( 1 => 86400,           # day
                      2 => 86400 * 7,       # week
                      3 => 86400 * 30,      # month-ish
                      4 => 86400 * 365.2425,# year-ish
                      5 => -1,              # forever
                      6 => -2);             # custom (date widget)

 
    do {
      # Display the current recipe.
      # dialog($swh, join("\n", @recipe), 'yellow');

      # Display the list of headers.
        ($text, $sel) = list_box('window'	=> $mwh,
                                 'title'	=> 'Choose one',
                                 'ypos'		=> 5,
                                 'xpos'		=> 1,
                                 'lines'	=> 6,
                                 'cols'		=> $COLS - 4,,
                                 'list'		=> \%date_h,
                                 'border'	=> 'green',
                                 'selected'	=> $sel,
                                 'function'	=> \&clock);

      # Allow the list of headers to be traversed using normal vi/emacs
      # keybindings.
        if ($text eq 'k' || $text eq "\cP") {
            $sel -= 1;
        } elsif ($text eq 'j' || $text eq "\cN") {
            $sel += 1;
        }

        if ($text eq "\n" || $text eq 'l') {

            use Time::localtime;
            my @tmp = (); 
            my $tm = localtime;

            $text = "You picked a \"$date_h{$sel}\"\n[tab] to continue.\n\n.";
            dialog($dwh, $text, 'yellow');

           # break out of loop
           # should check if $content contains only numbers...
            my $mult = $date_mult{$sel};
            if ($mult > 0 ) {
                my $foo;
                # show input box for the date stuff
                ($content, $text) = input_box('title'       => "Keep for how long",
                                              'prompt'      => "How many $date_h{$sel}:",
                                              'content'     => "1",
                                              'border'      => "green",
                                              'function'    => \&clock);
                $foo = $content * $mult + time;

                push(@tmp, "# Selected expire time is: $foo \n");
                push(@tmp, @recipe);
                @recipe = @tmp;

                # Write file
                open(OFILE, "> .procmail/m2proc/$foo.rule") or die "Can't open fucking shit: $!\n";
                print(OFILE @recipe);
                close(OFILE);
            }
            elsif ($mult == -1) {
                push(@tmp, "# Selected expire time is: forever\n");
                push(@tmp, @recipe);
                @recipe = @tmp;

                # Write file
                open(OFILE, ">> .procmail/m2proc/forever.rule") or die "Can't open fucking shit: $!\n";
                print(OFILE @recipe);
                close(OFILE);
            }
            elsif ($mult == -2) {
                push(@tmp, "# Selected expire time is: custom\n");
                push(@tmp, @recipe);
                @recipe = @tmp;
                
                # Write file
                open(OFILE, ">> .procmail/m2proc/custom.rule") or die "Can't open fucking shit: $!\n";
                print(OFILE @recipe);
                close(OFILE);
            }

           next;
        }

      # Sanity check on sel to make sure we didn't run off either end of the
      # list.
        $sel = 0 if ($sel == keys(%date_h));
        $sel = keys(%date_h) - 1 if ($sel == -1);

    } while ( $text ne 'q' );

}


END {
# stop doing things
    endwin();
    #@recipe = join("\n", @recipe);
    #print(@recipe);
    #    my ($DAY, $MONTH+1, $YEAR) = (localtime)[3,4,5];
    #printf ("$DAY-$MONTH-$YEAR\n");
    close(STDIN);
    close(MYTTY);
    system("generateproc.pl");
}
