#!/usr/bin/perl -w

############################################################################
# NAME: finf (Find in Files)
# DESC: Perl script recursively looks in file directory for text that 
#	matches the pattern.  Pattern uses Regular expressions so have fun.
#	One can limit the search by
# 
############################################################################
use strict;
use warnings;

use File::Basename;
use File::Copy;
use Getopt::Std;

my $size = @ARGV; 
my %opt;

my $tMarg=5;
my $bMarg=3;
my $lMarg=3;
my $rMarg=3;
my $fszFind;
my $fszReplace;
my $modPageStyle;
my $verbose;
my $outputFile;
my %gPageStyle;
my %gTextStyle;
my $tmpDir=".x_lrf2lrf";

my $opt_string= 'o:f:t:b:l:r:a:p:evx:s:h';
my $lrfFileToFix=$ARGV[($size-1)]; 

################### DEF
sub printRecommendPageStyle(){

    my $hps=highestPageStyle();
    return unless (defined $hps);
    $modPageStyle = $hps;
    if(defined $verbose){
        print "Recommend PageStyle = ".$hps."\n";
        foreach my $value (keys %gPageStyle){
            print "Found PageStyle = ".$value." Occurrence = ".$gPageStyle{$value}."\n";
        }
    }
}

sub printRecommendTextStyle(){

    my $hps=highestTextStyle();
    return unless (defined $hps);
    $fszFind = $hps;
    if(defined $verbose){
        print "Recommend TextStyle = ".$hps."\n";
        foreach my $value (keys %gTextStyle){
            print "Found TextStyle = ".$value." Occurrence = ".$gTextStyle{$value}->{'COUNT'}."\n";
        }
    }
}

#################

getopts( "$opt_string", \%opt );
Help() if (($opt{'h'}) || !(defined $lrfFileToFix));


my @suff = ('LRF', 'Lrf', 'lrf');
my $lrsFile  = basename($lrfFileToFix, @suff);
my $bExplore = 1 if ($opt{'e'});

$lrsFile  = ".".$lrsFile."lrs.tmp";

if ($opt{'o'}){
    $outputFile=$opt{'o'}  if ($opt{'o'});
}else{
    $outputFile = $lrfFileToFix;
}

Help() if ($opt{'h'});
$tMarg = $opt{'t'} if ($opt{'t'});
$bMarg = $opt{'b'} if ($opt{'b'});
$lMarg = $opt{'l'} if ($opt{'l'});
$rMarg  = $opt{'r'} if ($opt{'r'});
$tMarg = $bMarg = $lMarg = $rMarg = $opt{'a'} if ($opt{'a'});
$fszFind = $opt{'f'} if ($opt{'f'});
$fszFind = $opt{'x'} if ($opt{'x'});
undef $opt{'f'} if (defined $opt{'x'});

$fszReplace = $opt{'s'} if ($opt{'s'});
$modPageStyle = $opt{'p'} if($opt{'p'});
$verbose = 1 if ($opt{'v'});

# Create LRS
 mkdir $tmpDir = $tmpDir.$lrsFile;
 chdir $tmpDir;
 system("lrf2lrs","-o","$lrsFile","../$lrfFileToFix");


if(defined $bExplore){
    $verbose = 1;
    exploreLRS($lrsFile );
    addUpPageStyle($lrsFile);
    addUpTextStyle($lrsFile);
    printRecommendPageStyle();
    printRecommendTextStyle();
    unlink($lrsFile);
}else{
    my $lrsFileOut = $lrsFile.".1";
    exploreLRS($lrsFile ) unless ($opt{'p'} && $opt{'x'});

    unless ($opt{'p'}){
        addUpPageStyle($lrsFile);
        $modPageStyle =highestPageStyle();
    }
    unless ($opt{'x'} || $opt{'f'}){
        addUpTextStyle($lrsFile) unless ($opt{'f'});
        $fszFind = highestTextStyle();
    }


    parseLRS($lrsFile, $lrsFileOut, $fszFind,$fszReplace, $modPageStyle);
    system( "lrs2lrf","-o", "../$outputFile","$lrsFileOut");
    unlink($lrsFile);
    unlink($lrsFileOut);
}

  removeTempFiles($tmpDir);


sub parseLRS {
	my $file = shift;
	my $outfile = shift;
    my $fszFind = shift;
    my $fszReplace = shift;
    my $modPageStyle = shift;
    my $bWriteOut;
    my $szReplaceFontSize = "^\\s*<\\s*TextStyle.*fontsize=\"";
    my $szReplace         = "^\\s*<\\s*TextStyle.*fontsize=\"";
	
	return unless -f $file;

    if ($opt{'f'}){
        $szReplace = "^\\s*<\\s*TextStyle.*fontsize=\"";
    }else{
        $szReplace = "^\\s*<\\s*TextStyle.*objid=\"";
    }

    $modPageStyle="###############"  unless defined $modPageStyle; 
    $fszFind ="100" unless defined $fszFind; 
    $fszReplace ="80" unless defined $fszReplace; 
    print "LOOKING FOR $modPageStyle, $fszFind, $fszReplace\n";
    #should need this but just in case
	binmode(STDIN);
	binmode(STDOUT);

	open FI, $file or print "couldn't open $file\n" && return;
    if(defined $outfile){
	    open FO, ">$outfile" or print "couldn't open $file\n" && return;
        $bWriteOut = 1;
    }

    while (<FI>) {
        chomp;
	    if (m/($szReplace)($fszFind)(".*)/gi){
            my $szFont = $fszFind;

            # Get the font size. Unlessed user defined size.
            $szFont = $gTextStyle{$fszFind}->{'FONT_SIZE'} unless ($opt{'f'});
            print "s/($szReplaceFontSize)($szFont)(\".*)/$fszReplace\n" if($opt{'v'});
            s/($szReplaceFontSize)($szFont)(".*)/$1$fszReplace$3/gi;

            print "[$_]\n" if ($opt{'v'});
            if (defined $bWriteOut){
                print FO $_."\n";
            }else{
                print $_."\n";
            }

        }elsif (m/^\s*<\s*PageStyle.*objid="$modPageStyle".*/gi){
            my $pageHeight=754; # 754
            my $pageWidth=584;  # 584
            my $newPageHeight=$pageHeight-$tMarg;
            my $newPageWidth=$pageWidth-$lMarg;
            s/headheight="30"/headheight="$tMarg"/;
            s/oddsidemargin="\d{1,}"/oddsidemargin="$lMarg"/;
            s/evensidemargin="\d{1,}"/evensidemargin="$lMarg"/;
            s/textheight="\d{1,}"/textheight="$newPageHeight"/;
            s/textwidth="\d{1,}"/textwidth="$newPageWidth"/;
            s/footheight="\d{1,}"/footheight="0"/;
            s/footspace="\d{1,}"/footspace="0"/;

            if (defined $bWriteOut){
                print FO $_."\n";
            }else{
                print $_."\n";
            }

        }
        if (defined $bWriteOut){
            print FO $_."\n";
        }else{
            print $_."\n";
        }

	}

	close FI;
    close FO if (defined $bWriteOut);
}

sub exploreLRS {
	my $file = shift;
    my $bWriteOut;
	
	return unless -f $file;

    #should need this but just in case
	binmode(STDIN);
	binmode(STDOUT);

	open FI, $file or print "couldn't open $file\n" && return;

    while (<FI>) {
        chomp;
	    if (m/^\s*<\s*TextStyle.*fontsize=.*/gi){
#         print $_;
            my $textId= $_;
           my $fontSize = $_;
           $fontSize =~ s/^\s*<\s*TextStyle.*fontsize="(\d{1,})".*/$1/gi;
           $textId =~ s/^\s*<\s*TextStyle.*objid="(\d{1,})".*/$1/gi;
# my ($textId, $fs) = s/^\s*<\s*TextStyle.*objid\s*=\s*"(\d{1,})".*fontsize="(\d{1,})".*/$2/gi;

             print "TextStyle ObjId=$textId Fontsize = $fontSize\n" 
                                            if (defined $verbose);
           addTextStyle($textId, $fontSize);
        }
        elsif(m/^\s*<\s*PageStyle.*objid=".*/gi){
#           print $_;

           my $pageStyleID = $_;
           $pageStyleID =~ s/^\s*<\s*PageStyle.*objid="(\d{1,})".*/$1/gi;

           addPageStyle($pageStyleID);
        }
	}

	close FI;
    close FO if (defined $bWriteOut);
}
sub addUpPageStyle{
	my $file = shift;
    my $bWriteOut;
	
	return unless -f $file;

    #should need this but just in case
	binmode(STDIN);
	binmode(STDOUT);

	open FI, $file or print "couldn't open $file\n" && return;

    while (<FI>) {
        chomp;
        if(m/^\s*<\s*Page\s*pagestyle\s*=\s*".*/gi){
#           print $_;

           my $pageStyleID = $_;
           $pageStyleID =~ s/^\s*<\s*Page\s*pagestyle\s*=\s*"(\d{1,})".*/$1/gi;

           incrementPageStyle($pageStyleID);
        }
	}

	close FI;
    close FO if (defined $bWriteOut);
}

sub addUpTextStyle{
	my $file = shift;
    my $bWriteOut;
	
	return unless -f $file;

    #should need this but just in case
	binmode(STDIN);
	binmode(STDOUT);

	open FI, $file or print "couldn't open $file\n" && return;

    while (<FI>) {
        chomp;
        if(m/^\s*<\s*TextBlock.*textstyle\s*=\s*".*/gi){
#           print $_;

           my $textID= $_;
           $textID=~ s/^\s*<\s*TextBlock.*textstyle\s*=\s*"(\d{1,})".*/$1/gi;
           print "TextBlock  textstyle=$textID\n" if ($opt{'v'});

           incrementTextStyle($textID);
        }
	}

	close FI;
    close FO if (defined $bWriteOut);
}




sub highestPageStyle{
    my @aPageStyle = keys %gPageStyle;

    return 0 if($#aPageStyle <= -1);

    my $maxCount=0;
    my $highestHash;
    my $bFirst = 1;
    my $idx=0;
    foreach (@aPageStyle){
        if(($bFirst) and ($#aPageStyle > 0)){
            $maxCount = $gPageStyle{$_};
            $highestHash = $_;
            $bFirst = 0;
        }
        else{
            if( $maxCount < $gPageStyle{$_}){
                $maxCount = $gPageStyle{$_};
                $highestHash = $_;
            }
        }
        $idx++;
    }
    return $highestHash;
}

sub highestTextStyle{
    my @aTextStyle = keys %gTextStyle;

    return 0 if($#aTextStyle <= -1);

    my $maxCount=0;
    my $highestHash;
    my $bFirst = 1;
    my $idx=0;
    foreach (@aTextStyle){
        if(($bFirst) and ($#aTextStyle > 0)){
            $maxCount = $gTextStyle{$_}->{'COUNT'};;
            $highestHash = $_;
            $bFirst = 0;
        }
        else{
            if( $maxCount < $gTextStyle{$_}->{'COUNT'}){
                $maxCount = $gTextStyle{$_}->{'COUNT'};
                $highestHash = $_;
            }
        }
        $idx++;
    }
    return $highestHash;
}



sub incrementPageStyle{
    my $value = shift;

    foreach my $pageId (sort keys %gPageStyle){
        if( $pageId eq $value){
            $gPageStyle{$value} = $gPageStyle{$value}+1;
        }
    }
}

sub incrementTextStyle{
    my $objID = shift;

    foreach my $textId (sort keys %gTextStyle){
        if( $textId eq $objID){
            $gTextStyle{$objID}->{'COUNT'} = $gTextStyle{$objID}->{'COUNT'} + 1;
        }
    }
}



sub addPageStyle{
    my $value = shift;
    my $bNewPageStyle = 1;

    foreach my $pageId (sort keys %gPageStyle){
        return if( $pageId eq $value);
    }
            
    $gPageStyle{$value} = 1;
}

sub addTextStyle{
    my $ID = shift;
    my $fontSize = shift;
    my $bNewTextStyle = 1;


    foreach my $textId (sort keys %gTextStyle){
        return if( $textId eq $ID);
    }
            
    $gTextStyle{$ID}->{'FONT_SIZE'} = $fontSize;
    $gTextStyle{$ID}->{'COUNT'} = 1;
}

sub removeTempFiles{
    my $tmpDir = shift; 

    chdir "..";
    opendir (TMPDIR, $tmpDir) or die "Error open dir [".$!."]\n";
    while( my $file = readdir(TMPDIR)){
        next unless -f "$tmpDir/$file";
        unlink("$tmpDir/$file");
    }
    rmdir($tmpDir);

}



sub Help{
	my $this = shift;
	my ($outfile) =  ($0=~ m/^.*[\\|\/](.*)$/s); #only filename.

	print STDERR ":\n";
	print STDERR "  usage: $outfile [options] myBook.lrf\n";
	print STDERR "\n";
	print STDERR ": This application looks for the most commonly used\n";
	print STDERR ": font size(TextStyle) and page layout(PageStyle) to change\n";
	print STDERR ": the default font size and book margin size.\n";
	print STDERR ": \n";
	print STDERR ": The default behavior can be overriden by setting the options\n";
	print STDERR ":  -p for PageStyle and -x for TextStyle then passing in the\n";
	print STDERR ": object ID.\n";
	print STDERR ": To get the TextStyle ID and PageStyle ID use the '-e' switch\n";
	print STDERR ": \n";
	print STDERR ": \t usage: $outfile -f myBook.rlf\n";
	print STDERR ":\n";
	print STDERR ":\n";
	print STDERR "\n";
	print STDERR "\t-h          : this (help) message\n";
	print STDERR "\t-t          : Top margin\n";
	print STDERR "\t-b          : Bottom margin\n";
	print STDERR "\t-l          : Left margin\n";
	print STDERR "\t-r          : Right margin\n";
	print STDERR "\t-a          : Set all margins to the same value\n";
	print STDERR "\t-e          : Explore only\n";
	print STDERR "\t-o          : Output File name\n";
	print STDERR "\t-p          : PageStyle to modify.  Use -e to find the \n";
	print STDERR "\t(-p cont.)  : objectid then pass that number to the -p\n";
	print STDERR "\t(-p cont.)  :      e.g -p 256\n";
	print STDERR "\t-x          : Text ID to change. Use -e to find the text ID.\n";
	print STDERR "\t(-x cont.)  :  Note -x and -f are mutually exlusive.  Use the -s \n";
	print STDERR "\t(-x cont.)  :  to specify the font size \n";
	print STDERR "\t-f          : Changes a Font size from one size to another.\n";
	print STDERR "\t(-f cont.)  :  See ex. below to change fonts size 10pts to 8pts\n";
	print STDERR "\t(-f cont.)  :       -f 100,80\n";
	print STDERR "\t-s          : Font size in points by 10 (use 80 for 8pts).\n";
	print STDERR "\t(-s cont.)  :  Use this switch with the '-x' or without.\n";
	print STDERR "\t(-s cont.)  :  Default size is 80(8pts)n";
	print STDERR "\n";
	print STDERR "  Example: $outfile -a 3  -s 80  myBook.lrf\n";
	print STDERR "\n";
	
	exit;
}

