#!/usr/bin/perl

# Created on: 2008-01-16 08:05:58
# Create by:  ivanw
# $Id$
# $Revision$, $HeadURL$, $Date$
# $Revision$, $Source$, $Date$

use strict;
use warnings;
use version;
use Scalar::Util;
use List::Util qw/max/;
use Getopt::Long;
use Pod::Usage;
use Data::Dumper qw/Dumper/;
use English qw/ -no_match_vars /;
use FindBin qw/$Bin/;
use File::Slurp;
use File::Basename;
use File::Spec;
use VCS::Which;

our $VERSION = version->new('0.1.0');
my ($name)   = $PROGRAM_NAME =~ m{^.*/(.*?)$}mxs;

my %option = (
	revision => '',
	verbose  => 0,
	man      => 0,
	help     => 0,
	VERSION  => 0,
);

if ( !@ARGV ) {
	pod2usage( -verbose => 1 );
}

main();
exit 0;

sub main {

	Getopt::Long::Configure('bundling');
	GetOptions(
		\%option,
		'file|f=s',
		'revision|r=s',
		'change|c=i',
		'verbose|v+',
		'man',
		'help',
		'VERSION!',
	) or pod2usage(2);
	$option{'file'} ||= shift @ARGV;

	if ( $option{'VERSION'} ) {
		print "$name Version = $VERSION\n";
		exit 1;
	}
	elsif ( $option{'man'} ) {
		pod2usage( -verbose => 2 );
	}
	elsif ( $option{'help'} || !-e $option{'file'} ) {
		pod2usage( -verbose => 1 );
	}

	# sort out the revision names
	my ( $rev_old, $rev_new ) = ('', '');
	if ( $option{'revision'} ) {
		($rev_old, $rev_new) =
			$option{'revision'} =~ /:/xms ? ( split /:/xms, $option{'revision'} )
			:                               ( $option{'revision'} );
	}

	if ( $option{'change'} ) {
		( $rev_old, $rev_new ) =
			$option{'change'} > 0 ? ( $option{'change'} - 1, $option{'change'} )
			:                       ( $option{'change'}, $option{'change'} - 1 );
		$option{'revision'} = "$rev_old\:$rev_new";
	}

	# create the temporary file object name
	my $tmp = "/tmp/$name.$$." . basename($option{'file'});

	# create a new VCS::Which object for the file of interest
	my $vcs = VCS::Which->new(dir => $option{file});

	if ($rev_new) {
		write_file "$tmp.$rev_new", $vcs->cat($option{file}, $rev_new);
		write_file "$tmp.$rev_old", $vcs->cat($option{file}, $rev_old);
		exec "vimdiff $tmp.$rev_new $tmp.$rev_old";
	}
	elsif ($rev_old) {
		write_file "$tmp.$rev_old", $vcs->cat($option{file}, $rev_old);
		exec "vimdiff $option{'file'} $tmp";
	}
	else {
		my $log = $vcs->log($option{file});
		my ($ver) = max keys %$log;
		my $rev = $log->{$ver}{rev} ? ".$log->{$ver}{rev}" : '';
		write_file "$tmp$rev", $vcs->cat($option{file});
		exec "vimdiff $option{'file'} $tmp$rev";
	}

	return;
}

__DATA__

=head1 NAME

vcsvimdiff - Uses vimdiff to compare a file with it unmodified version or
historic versions from subversion or bazaar.

=head1 VERSION

This documentation refers to vcsvimdiff version 0.1.0.

=head1 SYNOPSIS

   vcsvimdiff [option]

 OPTIONS:
  -r --revision=rev1[:rev2]
                Specify revisions to use for full details see vcs help diff
  -c --change=int
                Specify changes from a specific revision (see vcs help diff)

  -v --verbose  Show more detailed option
     --version  Prints the version information
     --help     Prints this help information
     --man      Prints the full documentation for vcsvimdiff

=head1 DESCRIPTION

=head1 SUBROUTINES/METHODS

=head1 DIAGNOSTICS

=head1 CONFIGURATION AND ENVIRONMENT

=head1 DEPENDENCIES

=head1 INCOMPATIBILITIES

=head1 BUGS AND LIMITATIONS

There are no known bugs in this module.

Please report problems to Ivan Wills (ivan.wills@gmail.com).

Patches are welcome.

=head1 AUTHOR

Ivan Wills - (ivan.wills@gmail.com)

=head1 LICENSE AND COPYRIGHT

Copyright (c) 2009 Ivan Wills (14 Mullion Close, Hornsby Heights, NSW, 2077)
All rights reserved.

This module is free software; you can redistribute it and/or modify it under
the same terms as Perl itself. See L<perlartistic>.  This program is
distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

=cut
