#!/usr/bin/perl -w
# Copyright (c) 2010-2014 David Sugar, Tycho Softworks
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

require 5.004;

use File::Basename;
use POSIX qw(strftime tmpnam);
use strict;

# command line flag variables...
my $fix_flag = 0;       # whether to fix copyright in original file...
my $update_flag = 0;    # update also for current year...
my $expand_flag = 0;    # expand xxxx-yyyy copyrights...

# unitialized globals, set as the file is processed...
my $lastline;
my $range;
my $suffix;
my $prefix;
my $latest;
my $original;
my $dash;
my $count;

# initialized global values...
my $current = strftime "%Y", localtime;
my $copyright="Copyright (C)";
my $minimal = $current;
my $prior = 0;

sub update
{
    my $next = $latest;
    ++$next;
    ++$prior;

    if ($latest >= $current) {
        return;
    }

    if(($count == 1) && ($dash == 0) && ($next >= $minimal) && ($expand_flag < 1)) {
        $range="$range-$current";
        return;
    }

    if(($count == 1) && ($dash > 0) && ($next >= $minimal)) {
        $range="$original-$current";
        return;
    }

    if($next < $minimal) {
        $range="$range, $current";
        return;
    }

    if($dash > 0) {
        $range = substr($range, 0, ((length $range) - 4)) . $current;
        return;
    }

    foreach my $year ($next .. $current) {
        $range="$range, $year";
    }
}

sub years
{
    my $result = "";
    my ($first, $last, $year);

    $count = 0;

    foreach my $index (0 .. $#_) {
        ++$count;
        if($count > 1) {
            $prior = $latest;
        }
        $dash = 0;
        $_[$index] =~ s/^\s+//;
        $_[$index] =~ s/\s+$//;
        if($_[$index] =~ /[-]/) {
            ($first, $last) = split('-', $_[$index]);
            if($expand_flag < 1) {
                ++$dash;
            }
        }
        else {
            $first = $last = $_[$index];
        }
        $first =~ s/^\s+//;
        $first =~ s/\s+$//;
        $last =~ s/^\s+//;
        $last =~ s/\s+$//;
        if($count == 1) {
            $original="$first";
        }
        $latest = $last;
        if($dash > 0) {
            if(length $result > 0) {
                $result="$result, $first-$last";
            }
            else {
                $result="$first-$last";
            }
            next;
        }
        foreach $year ($first .. $last) {
            if(length $result > 0) {
                $result="$result, $year";
            }
            else {
                $result=$year;
            }
        }
    }
    return $result;
}

sub scan
{
    $lastline = 0;

    my ($input, $temp);
    my $lines = 0;
    my $filename = $_[0];
    my $tempname = dirname($filename) . "/_" . basename(tmpnam()) . "_.tmp";
    my $name = basename($filename);
    my $maxline = 10;

    open FILE, "<", "$filename" or die "*** $filename: cannot access\n";

    if ($fix_flag > 0) {
        open TEMP, "+>", "$tempname" or die "*** cannot modify\n";
        unlink "$tempname";
    }

    while($input = <FILE>) {
        ++$lines;
        if(($lines < $maxline) && ($input =~ /[Cc]opyright \([cC]\) /)) {
            ($prefix, $temp) = split(/[Cc]opyright \([cC]\) /, $input);
            ($range) = split(/[a-zA-Z]/, $temp);
            my $len = length $range;
            $suffix = substr $temp, $len;
            $range = years(split(',', $range));
            $input = "$prefix$copyright $range $suffix";
            $lastline = $lines;
            if ($fix_flag < 1) {
                print "$name: $input";
            }
        }
        if($fix_flag > 0) {
            print(TEMP "$input");
        }
    }

    close(FILE);

    if ($fix_flag < 1) {
        return;
    }

    if($lastline < 1) {
        close(TEMP);
        return;
    }

    open FILE, ">", "$filename" or die "*** $filename: cannot modify\n";

    $lines = 0;
    seek(TEMP, 0, 0);
    while($input = <TEMP>) {
        ++$lines;
        if (($lines == $lastline) && ($update_flag > 0)) {
            update;
            $input = "$prefix$copyright $range $suffix";
        }
        if (($lines < $maxline) && ($input =~ /[Cc]opyright \([cC]\) /)) {
            print "$name: $input";
        }
        print(FILE "$input");
    }

    close(TEMP);
}

foreach my $index (0 .. $#ARGV) {
    my $arg = $ARGV[$index];
    if (($arg eq "-f") || ($arg eq "-fix")) {
        ++$fix_flag;
    }
    elsif(($arg eq "-u") || ($arg eq "-update")) {
        ++$fix_flag;
        ++$update_flag;
    }
    elsif(($arg eq "-x") || ($arg eq "-expand")) {
        ++$expand_flag;
    }
    elsif( $arg =~ /^[-].*/ ) {
        $minimal = substr $arg, 1;
        if($minimal < 2000) {
            die "*** $arg: unknown option\n";
        }

        # The -year format is used as a -u option that also consolidates from
        # a specific year forward.

        ++$fix_flag;
        ++$update_flag;
    }
    else {
        if( -T $arg ) {
            scan($arg);
        }
        else {
            die "*** $arg: invalid file\n";
        }
    }
}

