#!/usr/bin/perl

use Text::Todo::Simple;
use Getopt::Long;

use warnings;
use strict;

=head1 NAME

t - Help people finish those damn tasks

=head1 VERSION

version 0.14

=head1 SYNOPSIS

 t [OPTIONS] [ACTION] [ARGS]

 Actions:
   add, a       TEXT
   do           ID
   remove, rm   ID
   list, ls     [STRING]
   move, mv     ID NEW
   edit, ed     ID TEXT/REGEX

 Options:
   --todo, -t   FILE
   --done, -d   FILE

=cut

my ($default_todo, $default_done);

if ($^O eq 'MSWin32') {
	$default_todo = $ENV{USERPROFILE}."\\todo.txt";
	$default_done = $ENV{USERPROFILE}."\\done.txt";
} else {
	$default_todo = $ENV{HOME}."/.todo";
	$default_done = $ENV{HOME}."/.done";
}

my $todo_file		= $ENV{TODO_FILE}    ? $ENV{TODO_FILE}    : $default_todo;
my $done_file		= $ENV{DONE_FILE}    ? $ENV{DONE_FILE}    : $default_done;
my $default_action	= $ENV{TODO_DEFAULT} ? $ENV{TODO_DEFAULT} : 'help';

GetOptions (
	"todo=s" => \$todo_file,
	"done=s" => \$done_file
);

my $todo = Text::Todo::Simple -> new(
	todo_file => $todo_file,
	done_file => $done_file
);

my %actions = (
	add      => \&add,
	do       => \&do,
	remove	 => \&remove,
	list	 => \&list,
	move	 => \&move,
	edit	 => \&edit,
	help	 => \&help
);

my %aliases = (
	a    => 'add',
	rm   => 'remove',
	ls   => 'list',
	mv   => 'move',
	ed   => 'edit'
);

my $action = $ARGV[0];

if ($action && $aliases{$action}) {
	$action = $aliases{$action};
	shift @ARGV;
} elsif (!$action || !$actions{$action}) {
	$action = $default_action;
} elsif ($actions{$action}) {
	shift @ARGV;
}

$actions{$action} -> (@ARGV);

sub add {
	my $task = join ' ', @_;

	my $i = $todo -> add($task);

	print "Added task $i\n";
}

sub do {
	$todo -> do(@_);

	print "Done task ".shift()."\n";
}

sub remove {
	$todo -> remove(@_);

	print "Removed task ".shift()."\n";
}

sub list { $todo -> list(@_); }

sub move {
	$todo -> move(@_);

	print "Moved task ".$_[0]." to ".$_[1]."\n";
}

sub edit {
	my $id  = shift;

	if (!defined $id) {
		system($ENV{'EDITOR'}, $todo -> {'todo_file'});
		return;
	}

	my $task = join ' ', @_;

	chomp $task;

	$todo -> edit($id, $task);

	print "Replaced task $id\n";
}

sub help {
	my $usage = <<END;
Usage: t.pl [ACTION] [ARGS]

 Actions:
  add, a 	TEXT
  remove, rm 	ID
  list, ls 	[STRING]
  move, mv 	ID NEW
  edit, ed 	ID TEXT/REGEX

See 'perldoc t.pl' for more information.
END

	print $usage;
}

=head1 ACTION

=over 4

=item B<add>, B<a> TEXT

add a task to the list

=item B<do> ID

mark a task as done, and move it to the done file

=item B<remove>, B<rm> ID

remove a task from the list

=item B<list>, B<ls> [STRING]

list tasks containing STRING (can be empty)

=item B<move>, B<mv> ID NEW

move a task from ID to NEW

=item B<edit>, B<ed> ID TEXT/REGEX

replace the task ID with TEXT/REGEX. if TEXT begins with 's/' it will be
treated as a regex (see L<EXAMPLES>).

=back

=head1 ACTION

=over 4

=item B<--todo>, B<-t> FILE

set todo file (takes precedence on configuration)

=item B<--done>, B<-d> FILE

set todo file (takes precedence on configuration)

=back

=head1 CONFIGURATION

The following environment variables will affect t.pl behaviour:

=over

=item B<TODO_FILE>

Specifies the path of the todo file. Default ~/.todo

=item B<DONE_FILE>

Specifies the path of the done file. Default ~/.done

=item B<TODO_DEFAULT>

Set the default action, this will be used when no action is specified.
Default 'help'

=back

=head1 EXAMPLES

Add some tasks

    $ t add Do something boring
    Added task 1
    $ t add Do something else
    Added task 2

List tasks

    $ t ls
    1 Do something boring
    2 Do something else

Edit a task

    $ t ed 1 Do something funny
    Replaced task 1

or

    $ t ed 1 s/boring/funny/
    Replaced task 1

Mark a task as done

    $ t do 1
    Done task 1

Delete a task

    $ t rm 2
    Removed task 2

Count tasks

    $ t ls | wc -l
    0

=head1 WEB BOOTSTRAP

If you need to use t on a system where it is not installed (and you don't
want to install it there) you can bootstrap t from the web as follows:

    $ curl -sL  http://is.gd/kfVKP | perl -

or

    $ wget -q http://is.gd/kfVKP -O- | perl -

This method is useful since it downloads and runs t without installing or
modifying anything, but it could be a little slow as it have to download
t and its dependencies every time it is run.

=head1 AUTHOR

Alessandro Ghedini <alexbio@cpan.org>

=head1 SEE ALSO

L<Text::Todo::Simple>

=head1 LICENSE AND COPYRIGHT

Copyright 2010 Alessandro Ghedini.

This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.

=cut