#!/usr/bin/perl
## creates crossreferences lists in USFm or OSIS. 
# The underlying list of crossreferences come from a 16th century Dutch Bible.

## Licensed under the standard BSD license:

# Copyright (c) 2010 CrossWire Bible Society <http://www.crosswire.org/>
# All rights reserved.
# 
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
# 
#     * Redistributions of source code must retain the above copyright
#        notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in
#       the documentation and/or other materials provided with the
#       distribution.
#     * Neither the name of the CrossWire Bible Society nor the names of
#       its contributors may be used to endorse or promote products
#       derived from this software without specific prior written
#       permission.
# 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

## For general inquiries, comments, suggestions, bug reports, etc. email:
## sword-support@crosswire.org

#########################################################################
    
    use strict;
    use warnings;
    use Text::CSV;
    
    
        
    sub parsekey {
        my $return = `parsekey "$_[0]" "$_[1]"`;
        $return =~ s/\n$//;
        $return;
    } 

    sub vs2osis {

        my $return = `vs2osisref "$_[0]" "$_[1]" $_[2]`;
        $return =~ s/\n$//;
        $return;
    }
                        
    
    my @bookname = ("GEN","EXO","LEV","NUM","DEU",
            "JOS","JDG","RUT","1SA","2SA","1KI",
            "2KI","1CH","2CH","EZR","NEH","EST","JOB",
            "PSA","PRO","ECC","SNG","ISA","JER","LAM",
            "EZK","DAN","HOS","JOL","AMO","OBA","JON",
            "MIC","NAM","HAB","ZEP","HAG","ZEC","MAL",
            "MAT","MRK","LUK","JHN","ACT","ROM","1CO",
            "2CO","GAL","EPH","PHP","COL","1TH","2TH",
            "1TI","2TI","TIT","PHM","HEB","JAS","1PE",
            "2PE","1JN","2JN","3JN","JUD","REV",
    );
            
    my %OSISbook = (
        # taken from usfm2osis.pl 
        "" => "", "GEN" => "Gen", "EXO" => "Exod", "LEV" => "Lev", "NUM" => "Num",
        "DEU" => "Deut", "JOS" => "Josh", "JDG" => "Judg", "RUT" => "Ruth",
        "1SA" => "1Sam", "2SA" => "2Sam", "1KI" => "1Kgs", "2KI" => "2Kgs",
        "1CH" => "1Chr", "2CH" => "2Chr", "EZR" => "Ezra", "NEH" => "Neh",
        "EST" => "Esth", "JOB" => "Job", "PSA" => "Ps", "PRO" => "Prov",
        "ECC" => "Eccl", "SNG" => "Song", "ISA" => "Isa", "JER" => "Jer",
        "LAM" => "Lam", "EZK" => "Ezek", "DAN" => "Dan", "HOS" => "Hos",
        "JOL" => "Joel", "AMO" => "Amos", "OBA" => "Obad", "JON" => "Jonah",
        "MIC" => "Mic", "NAM" => "Nah", "HAB" => "Hab", "ZEP" => "Zeph",
        "HAG" => "Hag", "ZEC" => "Zech", "MAL" => "Mal", "MAT" => "Matt",
        "MRK" => "Mark", "LUK" => "Luke", "JHN" => "John", "ACT" => "Acts",
        "ROM" => "Rom", "1CO" => "1Cor", "2CO" => "2Cor", "GAL" => "Gal",
        "EPH" => "Eph", "PHP" => "Phil", "COL" => "Col", "1TH" => "1Thess",
        "2TH" => "2Thess", "1TI" => "1Tim", "2TI" => "2Tim", "TIT" => "Titus",
        "PHM" => "Phlm", "HEB" => "Heb", "JAS" => "Jas", "1PE" => "1Pet",
        "2PE" => "2Pet", "1JN" => "1John", "2JN" => "2John", "3JN" => "3John",
        "JUD" => "Jude", "REV" => "Rev", "TOB" => "Tob", "JDT" => "Jdt",
        "ESG" => "Esth", "WIS" => "Wis", "SIR" => "Sir", "BAR" => "Bar",
        "LJE" => "EpJer", "S3Y" => "PrAzar", "SUS" => "Sus", "BEL" => "Bel",
        "1MA" => "1Macc", "2MA" => "2Macc", "3MA" => "3Macc", "4MA" => "4Macc",
        "1ES" => "1Esd", "2ES" => "2Esd", "MAN" => "PrMan",
        # Following this is just an uneducated guess
        "PS2" => "Ps151", "ODA" => "Odes", "PSS" => "PssSol", "JSA" => "Josh",
        "JSB" => "Josh", "TBS" => "Tob", "SST" => "Sus", "DNT" => "Dan",
        "BLT" => "Bel", "ADE" => "AddEsth"
    );
    
    my @xref_count = qw( a b c d e f g h i j k l m n 
                        o p q r s t u v w x z);
                        
my $version = "1.0";
my $osisVersion = "2.1.1";

my $date = '$Date: 2010-08-17 05:46:26 +0000 (Tue, 04 Aug 2009) $';
my $rev = '$Rev: 231 $';

my %xrefList;



if (scalar(@ARGV) < 3) {
    print "\t xrefmake.pl 
        \t -- creates a file with localised crossreferences, either in USFM or in OSIS. 
        \n \t It expects as input a csvfile formatted as follows:
        \t A space-separated list of 6 numbers, representing the originating reference and cross reference, each as <book> <chapter> <verse>.
        \t A SWORD locale name.
        \t Either OSIS or USFM to determine the output format
        \t Optionally, the name of a file containing the used canon as a list of book names, each name on a single line. The default canon is that of the KJV. 
        \n \t \b Usage: xrefmake.pl <input CSV filename> <xreflocale> <USFM|OSIS> [canon file name].\n";
    exit (-1);
}
    
    my $file = "$ARGV[0]";
    my $locale = "$ARGV[1]";
    
    my $type = "$ARGV[2]";
    
    if (exists ($ARGV[3])) {
        
        @bookname = `cat $ARGV[3]` or die $!;
        
    }

    my $csv = Text::CSV->new();
    
    my ($ref, $o_ref, $xref, $xrefList, $chapter, $chapter_now, $xref_counter);    
    open (CSV, "<", $file) or die $!;

    if ($type eq "OSIS") {
    
       $o_ref 		= "GEN.1.1";
       $chapter 	= 1;
       $xref_counter 	= 0;
    
       while (<CSV>) {
           
           if ($csv->parse($_)) {
                my @columns = $csv->fields();
                $ref = "$OSISbook{ $bookname[ $columns[0] -1 ] }.$columns[1].$columns[2]";
                $xref = &parsekey( "$OSISbook{ $bookname[ $columns[3] -1 ] }.$columns[4].$columns[5]", $locale );
                $chapter_now = $columns[1];
                
                if ($ref eq $o_ref) {
                    print &vs2osis($xref,$o_ref,$locale); 
                }
                else { 

                    print "</note>\n\$\$\$$ref\n<note n=\"$xref_count[$xref_counter]\" type=\"crossreference\" osisID=\"$ref!crossReference.$xref_count[$xref_counter]\" osisRef=\"$ref\">".&vs2osis($xref,$o_ref,$locale)."; ";
                    $o_ref = $ref;
                    if ($chapter_now == $chapter) {
                        $xref_counter = ($xref_counter + 1) % 26 ;
                    }
                    else {
                        $xref_counter =0;
                        $chapter = $chapter_now;	 
                    }
                }                        
            
            } 
            
            else {
                my $err = $csv->error_input;
                print "Failed to parse line: $err";
            }
        }
    }    
    elsif ($type eq "USFM") {
        my $o_ref = "GEN.0.0";
        $xrefList = "";
        while (<CSV>) {
            if ($csv->parse($_)) {
                my @columns = $csv->fields();
                $ref = "$bookname[ $columns[0] -1 ].$columns[1].$columns[2]";
                $xref = &parsekey( "$OSISbook{ $bookname[ $columns[3] -1 ] }.$columns[4].$columns[5]", $locale );
                if ($ref eq $o_ref) {
                    $xrefList = $xrefList.$xref;
                }
                else {
                    print "$o_ref \\x + \\xo $o_ref \\xr $xrefList \\x*\n";
                    $xrefList = $xref;
                    $o_ref = $ref;
                }                        
            }
            else {
                my $err = $csv->error_input;
                print "Failed to parse line: $err";
            }
        }
    }
    else {
        print "type $type not recognised";
    }    
    print "\n";
    close CSV;
