#!/usr/bin/perl 
# 
#  Usage: find_replace.pl PATTERN_orig PATTERN_new 
#  recursively searches files starting in current directory and prints
#  lines that would be changed to screen.  No files are modified.
#
#  Usage: find_replace.pl PATTERN_orig PATTERN_new 1
#  Files are modified.
#
#  R.S. Weigel 03/05/2005;

use File::Find;
use Term::Cap;
use Time::HiRes qw(time);

$| = 1;

my (%file_count);
###############################################################################
$num = scalar(@ARGV); # number of input arguments.
if ($num < 3) {$ARGV[2] = 0;}
$OLDPATTERN = $ARGV[0];
$NEWPATTERN = $ARGV[1];

if ($ARGV[3]) {
    $QUIET = $ARGV[3];
} else {
    $QUIET = 0
}

if ($QUIET) {
    $PROGRESS = 1;
    $MAXCOUNT = 0;
    $TERMINAL = Tgetent Term::Cap { TERM => undef, OSPEED => undef };
    $STARTBAR = "Progress: [";
    $ENDBAR   = "]  ";
    $BARCHAR  = '-';
    $NOCHAR   = ' ';
    $rc = `stty size 2>&1`;
    if ( $rc =~ /^\s*(\d+)\s+(\d+)\s*/ ) {
	( $r, $c ) = ( $1, $2 );
    } else {
	$c = $TERMINAL->{'_co'};
    }
    $BARWIDTH = $c - (length($STARTBAR) + length($ENDBAR) + 5);
    $CURCOUNT = 0;
    $PERCENT  = -1;
}

if ($QUIET==0) {
    print "Pattern to replace: $OLDPATTERN\n";
    print "New Pattern       : $NEWPATTERN\n";
    if ($ARGV[2] == 1) {
	print "Modify files?     : yes\n";
    } else {
	print "Modify files?     : no\n";
    }
}

###############################################################################
@directory = ("./");
@files;

%find_options = (
    wanted   => \&check,
    no_chdir => 1,
);

print STDERR "Locating files which need to be modified..." if $PROGRESS;

find(\%find_options,  @directory);


print STDERR $TERMINAL->Tputs('cr', 1) if $PROGRESS;
print STDERR "Modifying files...                         \n" if $PROGRESS;

$MAXCOUNT = $#files + 1;

$msize = length($MAXCOUNT);
$BARWIDTH -= $msize*2 + 20;

$start = time();

foreach my $f (@files) {
    wanted( $f );
}

print STDERR "\n\n" if $PROGRESS;

if ($QUIET==1) {
    for $ext (sort keys %file_count) {
	print "$ext ($file_count{$ext}); ";
    }
    print "\n";
}

sub check {
    my  $f = $_;
    if ( $f =~ m/(\.net|\.cfg|\.animate|\.m)$/ &&
	 $f !~ m|^\./required_packages/| ) {
	push( @files, $f );
    }
}

sub progress_bar {
    $CURCOUNT += 1;
    $per       = $CURCOUNT/$MAXCOUNT;
    $per       = 1.0 if ($per > 1.0);
    $size      = int( $per * $BARWIDTH );    
    $per       = int( $per * 100 );
    
    $CURSIZE = $size;
    $PERCENT = $per;

    $timeleft = (time() - $start) * ( ($MAXCOUNT/$CURCOUNT) - 1);
    $min = int( $timeleft / 60 );
    $sec = int( $timeleft % 60 );

    print STDERR $TERMINAL->Tputs('cr', 1);
    print STDERR $STARTBAR;
    print STDERR $BARCHAR x $CURSIZE;
    print STDERR $NOCHAR  x ($BARWIDTH - $CURSIZE);
    print STDERR $ENDBAR;
    print STDERR sprintf("%3d", $PERCENT) . "%";
    print STDERR "  (". sprintf("%.${msize}d",$CURCOUNT)."/".$MAXCOUNT.")  ETA ".sprintf("%.2d", $min)."m:".sprintf("%.2d",$sec)."s";
}

sub wanted {

    my ($f) = @_;

    progress_bar() if $PROGRESS;

    my $line_count = 0;

    # Modify files with these extensions
    if ( $f =~ m/(\.[^.]*)$/ ){
	my $ext = $1;

	open(DATA_in,"$f");

	if ($ARGV[2] == 1) {
	    system("cp -p $f $f.tmp");
	    open(DATA_out,">$f.tmp");
	}

	while ($line = <DATA_in>){

	    $line_o = $line;

	    if ($line =~ s/$OLDPATTERN/$NEWPATTERN/g) {
		if ($QUIET==0) {
		    print "File: $f\n";
		    print "--Original $f: $line_o";
		    print "--Modified $f: $line";
		} else {
		    $file_count{$ext}+=1
		}
	    }
	    
	    if ($ARGV[2] == 1) {
		print DATA_out "$line";
	    }
	    
	}
	close(DATA_in);

	if ($ARGV[2] == 1) {
	    close(DATA_out);
	    #system("cp -p $f.tmp $f");
	    system("mv -f $f.tmp $f");
	}
    }    
}
