#! perl -w
#
#  Procedure to generate a Table Of Contents (TOC) for conferences where SPMS values cannot be used or for InDiCo
#
#    v0.1  14. May 2007  volker rw schaa
#    v0.5  17. May 2007  volker rw schaa   put all xml files into xml subdirectory
#    v1.0  28. May 2007  volker rw schaa   
#    v1.1  16. Mar 2009  volker rw schaa   - introduced short tags (as being used for InDiCo (<pages/>, <toc/>, ..) 
#                                          - rewrote code for wrongly given TOC values due to non updated SPMS
#    v1.2  19. Mar 2009  volker rw schaa   - changed wording for first copying XML file, then reading from it to write new one
#    v1.3  02. Jun 2010  volker rw schaa   - page number and TOC entry are written directly, <toc> or <toc/> entries found later  are reported and discarded 
#                                          - whole XML file is read at the beginning for easier line checking
#    v1.4  25. May 2011  volker rw schaa   - while checking page info using "check_existing_pagetoc_info" the next line (<main_class>) got discarded, problem fixed
#
#
 use Carp;
 use File::Basename;
 use Time::HiRes  qw(gettimeofday);
 use Time::localtime;
 use strict;
 no strict 'refs';

 use vars qw ($start_tm $stop_tm $session_arg $conference_spms $session_xml);
 use vars qw ($spms_xml $cp_spms_xml $mtime $tm $fm $ft);
 use vars qw (@lines $lines $actLine $actLineNr $maxLineNr);
 use vars qw ($paper_open $paper_code $paper_info $toc_nr $page_nr);
 use vars qw ($xml_directory $conference_xmlfile $content_directory $paper_directory $raw_paper_directory);
 use vars qw ($paper_not_received_link);
#
# start time
#
$start_tm = gettimeofday;

#
# now read the config file
#
if (open (CONFIG, "<conference.config")) {
    print "\n config file 'conference.config' found!\n";
    while (<CONFIG>) {
        chomp;                  # no newline
        s/(^#|[^&]#).*//;       # no comments
        s/^\s+//;               # no leading white
        s/\s+$//;               # no trailing white
        next unless length;     # anything left?
        my ($var, $value) = split(/\s*=\s*/, $_, 2);
        $$var = $value;
    }
} else {
    croak " no config file 'conference.config' found on line $.\n";
}

#
# read command line argument for config file name (default = config.txt)
#
my $debug_file = "protocol_generate_toc.txt";
open (DBG, ">$debug_file") or die ("Cannot open '$debug_file' -- $!\n");

my $fmt = " %24s = %-40s\n";
print DBG sprintf ("%s\n","-"x68);
print DBG sprintf ($fmt,"conference_xmlfile", $conference_xmlfile);
print DBG sprintf ($fmt,"content_directory", $content_directory);
$paper_directory = uc $paper_directory;
print DBG sprintf ($fmt,"paper_directory", $paper_directory);
print DBG sprintf ($fmt,"raw_paper_directory", $raw_paper_directory);
print DBG sprintf ("%s\n","-"x68);
if (!defined $paper_not_received_link) {
    $paper_not_received_link = 1;
}
if (!defined $xml_directory) {
    $xml_directory = "";
}
print "\n config file '$conference_xmlfile' read\n";

$spms_xml = "$xml_directory$conference_xmlfile";
if (!-e $spms_xml) {
    croak " File ->$spms_xml<- does not exist!\n";
}

$mtime    = (stat($spms_xml))[9];
$tm       = localtime($mtime);

my($filename, $directories, $suffix) = fileparse($spms_xml);
($fm, $ft) = split (/\./, $filename);

$cp_spms_xml = sprintf ("%-s%-s-%04d%02d%02d-%02d%02d%02d.%-s",
                        $xml_directory,
                        $fm, ($tm->year)+1900, ($tm->mon)+1, $tm->mday,
                              $tm->hour, $tm->min, $tm->sec,
                        $ft);

if (-e $cp_spms_xml) {
    croak " Save file ->$cp_spms_xml<- already exist!\n";
}

print     " Input file ->$spms_xml<- will be saved as ->$cp_spms_xml<-\n";
print DBG " Input file ->$spms_xml<- will be saved as ->$cp_spms_xml<-\n";
my $command =  sprintf ("copy %-s %-s", $spms_xml, $cp_spms_xml);
   $command =~ s|\/|\\|g;
system ($command);
#
# now read the copied xml file
#
open (BASE, "<$cp_spms_xml") or croak " Input spms file '$cp_spms_xml' not found on line $.\n";
print     "\n saved input spms file '$cp_spms_xml' will be used as input!\n";
print DBG "\n saved input spms file '$cp_spms_xml' will be used as input!\n";

open (SPMS, ">$spms_xml") or croak " cannot open spms output file ->$spms_xml<- on line $.\n";

$paper_open = 0;
$paper_info = 0;
$toc_nr     = 1;
$page_nr    = 1;

@lines      = <BASE>;  # read complete XML file
close (BASE);
$maxLineNr  = $#lines;
$actLineNr  = -1;

while ($actLineNr < $maxLineNr) {
    $actLineNr++;
    $actLine = $lines[$actLineNr];
    chomp ($actLine);
    #
    # tag <paper code="..." pages="..." toc="..." ...>
    #     <paper>
    #       ---<abstract_id>1665</abstract_id> 
    #       <code>MOAA001</code>
    #       <pages>#</pages> or <pages/>
    #       ---<main_class>07 Accelerator Technology</main_class> 
    #       ---<sub_class>T23 Timing and Synchronization</sub_class> 
    #       <toc>xyz</toc>   or <toc/>
    #       ---<publishable>Yes</publishable> 
    #       ---<presentation type="Oral">Contributed Oral</presentation> 
    #       ---<start_time>1540</start_time> 
    #       ---<duration>20</duration> 
    #       <dot>Green</dot> 
    #       <title>                     <= search for <pages>/<toc>should end here
    #       ---<...>
    #     </paper>
    #
    #
#    print sprintf (":> %5i =%s\n", $actLineNr, $_);
    if ($actLine =~ m|<paper>|) {
        if ($paper_open) {
            croak " opening new paper while paper '$paper_code' is not closed in line $.\n";
        } else {
            $paper_open   =  1;
            $paper_code   = " ";
            print SPMS ("$actLine\n");
        }
        next;
    }
    #
    # tag </paper>
    #
    if ($actLine =~ m|</paper>|) {
        if ($paper_open) {
            $paper_open  = 0;
            $paper_code  = " ";
            $paper_info  = 0;
            $toc_nr     += $page_nr;   # final TOC increment
            print SPMS ("$actLine\n");
        } else {
            croak " closing paper while no paper is open in line $.\n";
        }
        next;
    }
    #
    # tag <code>...</code>
    #
    if ($actLine =~ m|<code>\s*(.*?)</code>|) {
        if ($paper_open) {
            $paper_code = uc $1;
            print SPMS ("$actLine\n");
            print     " ---------------------------------------\n ----- working on: $paper_code\n";
            print DBG " ---------------------------------------\n ----- working on: $paper_code\n";
            get_correct_toc_info ($paper_code);
            check_existing_pagetoc_info ();
        } else {
            croak " defining paper code '$1' while no paper is open (anymore) in line $.\n";
        }
        next;
    }
    #
    # tag "<toc/>"
    #
    if ($actLine =~ m|<toc|) {
        if ($paper_info) {
            if (m|<toc/>|) { 
                print sprintf     (" empty <toc> corrected to  page: %4i\n", $toc_nr);
                print DBG sprintf (" empty <toc> corrected to  page: %4i\n", $toc_nr);
                next;
            }
            if ($actLine =~ /<toc>\s*(.*?)<\/toc>/) {
                print sprintf     (" <toc> entry found with page no: %4i\n", $1);
                print DBG sprintf (" <toc> entry found with page no: %4i\n", $1);
                print sprintf     (" <toc> entry corrected to  page: %4i\n", $toc_nr);
                print DBG sprintf (" <toc> entry corrected to  page: %4i\n", $toc_nr);
                next;
            }
        }
    }
    #
    # tag "<publishable/>" -> "<publishable>yes</publishable>"
    #
    if ($actLine =~ m|<publishable/>|) {
        if ($paper_info) {
            $actLine =~ s|<publishable/>|<publishable>yes</publishable>|;
            print SPMS ("$actLine\n");
            next;
        }
    }
    #
    # tag "<dot/>"  -> "<dot>green</dot>"
    #
    if ($actLine =~ m|<dot/>|) {
        if ($paper_info) {
            $actLine =~ s|<dot/>|<dot>green</dot>|;
            print SPMS ("$actLine\n");
            next;
        }
    }
    #
    # other tags
    #
    print SPMS ("$actLine\n");
}

close (SPMS);
print sprintf (" total number of pages: %4i\n", $toc_nr-1);

#
# stop time
#
$stop_tm = gettimeofday;
print DBG sprintf ("\n\n elapsed time: %.2f [s]\n", $stop_tm-$start_tm);
print sprintf     ("\n\n elapsed time: %.2f [s]\n", $stop_tm-$start_tm);

exit;

#========================================================
sub get_correct_toc_info {

    $paper_info = 1;

    my $command;
    (my $pdffile = "$raw_paper_directory$_[0].pdf") =~ s|\.\.|\.|;
    (my $pdfinfo = "$raw_paper_directory$_[0].info") =~ s|\.\.|\.|;

    print sprintf     (" checking %8s\n", $pdffile);
    print DBG sprintf (" checking %8s\n", $pdffile);
    if (-e $pdffile) {
        if (-z $pdffile) {
            print sprintf     (" %8s ======> empty pdf file\n", $pdffile);
            print DBG sprintf (" %8s ======> empty pdf file\n", $pdffile);
            $page_nr = 0;
            return;
        }
        if (!-e $pdfinfo) {
            $command = sprintf ("pdfinfo -box %s >$pdfinfo", $pdffile);
            system ($command);
        }
        open (KIN, "<$pdfinfo") or die " cannot open '$pdfinfo' -- error: $!\n";
        while (<KIN>) {
            chomp;
            if (m|Pages:\s*(.*?)$|) {
                $page_nr = $1;
                last;
            }
        }
        close (KIN);
        print sprintf     (" %3i pages in %-s\n", $page_nr, $paper_code);
        print DBG sprintf (" %3i pages in %-s\n", $page_nr, $paper_code);
#>        system ("del $pdfinfo");
    } else {
        print sprintf     (" %8s file not found\n", $pdffile);
        print DBG sprintf (" %8s file not found\n", $pdffile);
        $page_nr = 0;
    }
    return;
}

#========================================================
sub check_existing_pagetoc_info {

    print DBG "+ checking page-toc_info\n";
    print DBG "+($actLineNr) -> $lines[$actLineNr]";
    $actLineNr++;
    $actLine = $lines[$actLineNr];
    print DBG "+($actLineNr) -> $actLine\n";
    #
    # tag "<pages>.. or <pages/>"
    #
    if ($actLine =~ m|<pages|) {
        if ($paper_info) {
            print SPMS ("<pages>$page_nr</pages>\n<toc>$toc_nr</toc>\n");
            print     "+++> <toc>$toc_nr</toc>\n";
            print DBG "+++> <toc>$toc_nr</toc>\n";
        }
    } else {
    #
    # restore non-page line to SPMS
    #
        print SPMS ($actLine);
    }
    return;
}
