#!/usr/bin/perl -w
# This script (sophomorix-print) is maintained by Rüdiger Beck
# It is Free Software (License GPLv3)
# If you find errors, contact the author
# jeffbeck@web.de  or  jeffbeck@linuxmuster.net

############################################################
# this script uses global variables to store data
# as it goes through the lists it
# A) prints the data to the files (csv files)
# B) saves data in $latex_datablock (later used in latex files using the template)

# modules
use strict;
use Getopt::Long;
use Sophomorix::SophomorixConfig;
use Sophomorix::SophomorixBase qw(
                                 print_line
                                 print_title
                                 ymdhms_to_epoch
                                 ymdhms_to_date
                                 unlock_sophomorix
                                 lock_sophomorix
                                 log_script_start
                                 log_script_end
                                 log_script_exit
                                 backup_auk_file
                                 get_passwd_charlist
                                 get_plain_password
                                 check_options
                                 config_sophomorix_read
                                 result_sophomorix_init
                                 result_sophomorix_add
                                 result_sophomorix_add_summary
                                 result_sophomorix_check_exit
                                 result_sophomorix_print
                                 filelist_fetch
                                 remove_whitespace
                                 json_dump
                                 string_to_latex
                                 recode_utf8_to_ascii
                                 get_lang_from_config
                                 );
use Sophomorix::SophomorixSambaAD qw(
                                 AD_school_create
                                 AD_bind_admin
                                 AD_unbind_admin
                                 AD_user_create
                                 AD_group_create
                                 AD_group_addmember
                                 AD_group_update
                                 AD_get_schoolname
                                 AD_get_name_tokened
                                 AD_dn_fetch_multivalue
                                 AD_get_user
                                 AD_get_printdata
                                 AD_dns_get
                                 AD_get_passwd
                                 AD_object_search
                                    );

Getopt::Long::Configure ("bundling");
use Net::LDAP;
use JSON;
use Data::Dumper;
use File::Basename qw( basename
                       dirname
                     ); 

my @arguments = @ARGV;

my $dev_null="1>/dev/null 2>/dev/null";
my $json=0;

$Conf::log_level=1;

my $help=0;
my $info=0;

my $caller="";
my $caller_copy="";
my $command="latex";

# entries selections
my $user="";
my $class="";
my $project="";
my $back_in_time;# undef

# template options
my $template="";
my $one_per_page=0;
my $nosplit_names=0;
my $pp=0;
my $lang_by_option="";

my $school="";

# Parsen der Optionen
my $testopt=GetOptions(
           "help|h" => \$help,
           "info|i" => \$info,
           "json|j+" => \$json,
           "verbose|v+" => \$Conf::log_level,
           "school|s=s" => \$school,
           "class|c=s" => \$class,
           "project|p=s" => \$project,
           "template=s" => \$template,
           "lang=s" => \$lang_by_option,
           "per-page|pp=i" => \$pp,
           "user|u=s" => \$user,
           "caller=s" => \$caller,
           "caller-copy|callercopy=s" => \$caller_copy,
           "command=s" => \$command,
           "back-in-time|backintime=i" => \$back_in_time,
           "one-per-page" => \$one_per_page,
           "nosplit-names" => \$nosplit_names,
          );


if($Conf::log_level>=3){
   # avoid logging STDOUT,STDERR to /dev/null
   $dev_null="";
}

my %sophomorix_result=&result_sophomorix_init("sophomorix-check");
# Prüfen, ob Optionen erkannt wurden, sonst Abbruch
&check_options($testopt,\%sophomorix_result,$json);

# Reading Configuration
my ($ldap,$root_dse) = &AD_bind_admin(\@arguments,\%sophomorix_result,$json);
my $root_dns=&AD_dns_get($root_dse);
my %sophomorix_config=&config_sophomorix_read($ldap,$root_dse,\%sophomorix_result);
my ($smb_admin_pass)=&AD_get_passwd($DevelConf::sophomorix_file_admin,
                                     $DevelConf::secret_file_sophomorix_file_admin);

if ($school eq ""){
    $school=$DevelConf::name_default_school;
} else {
    if (not exists $sophomorix_config{'SCHOOLS'}{$school}){
        print "\nERROR: $school is not a valid school\n\n";
        exit 88;
    }
}


# --help
if ($help==1) {
   # calculate scriptname
   my @list = split(/\//,$0);
   my $scriptname = pop @list;
   print('
sophomorix-print prints user account data of ONE school to 
  /var/lib/sophomorix/print-data

Options:
  -h  / --help
  -v  / --verbose
  -vv / --verbose --verbose

sophomorix-print looks in ONE school for users (without option in: default-school)
For other schools use the following option:
  -s <schoolname> / --school <schoolname>

The user given by option --caller/--caller-copy must exist!

Choose the way of pdf generation:
  --command latex      (This is the default: *.tex ->latex->dvips->ps2pdf->*.pdf)
  --command pdflatex   (*.tex->pdflatex->*.pdf)

Examples to print a school:
  sophomorix-print  (print the school default-school)
  sophomorix-print --school bsz  (print the school bsz)

Examples to print a class:
  sophomorix-print --class <prefix>-<class>,... --caller bz [--school <schoolname>]
  sophomorix-print --class <prefix>-<class>,... --caller-copy bz [--school <schoolname>]

Examples to print some users:
  sophomorix-print --user <user1>,... --caller bz [--school <schoolname>]
  sophomorix-print --user <user1>,... --caller-copy bz [--school <schoolname>]

Examples to print timely additions:
  sophomorix-print -i [--school <schoolname>] (shows values and dates for <num>)
  sophomorix-print --back-in-time <num> --caller bz [--school <schoolname>]
  sophomorix-print --back-in-time <num> --caller-copy bz [--school <schoolname>]

Changing the LaTeX-template (i.e numer of users per page):
  Changing the number-part in the template filename (Users per page):
  --per-page <num> / --pp <num> 
  Changing the LANG-part in the template filename (LANG of template):
  --lang <XY>

Test your your own template (entries per page is calculated from filename):
  --template  /abs/path/to/datalist-DE-18-template.tex

Configuring custom templates per school:
  A) Save them in /etc/linuxmuster/sophomorix/<school>/latex-templates
  B) They must follow the naming convention <school>.*-<LANG>-<NUM>-template.tex
     * must be datalist at the moment?

Deprecated in sophomorix4 (at the moment):
  -p project / --project project
  --all printing of a school

Please see the sophomorix-print(8) man pages for full documentation
');
   print "\n";
   exit;
}

&log_script_start(\@arguments,\%sophomorix_result,\%sophomorix_config);

system("mkdir -p $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}");

# ===========================================================================
# Calculate output_file_basename and template file
# ===========================================================================
my $output_file_basename="";
my $template_num;

# Setting the abs-path of the template
my $lang=&get_lang_from_config($school,\%sophomorix_config);
# --lang <xy>
if ($lang_by_option ne ""){
    if (exists $sophomorix_config{'LOOKUP'}{'LANG_ALLOWED'}{$lang_by_option}){
        $lang=$lang_by_option;
    } else {
	print "\nERROR: $lang_by_option is not an allowed Lanuage\n\n";
        exit 88;
    }
}
my $template_path_abs=$sophomorix_config{'INI'}{'LATEX'}{'TEMPLATES'}.
                      "/datalist-".
                      $lang.
                      "-";


my $class_filename_part="";
if ($class ne ""){
    $template_num=36;
    my $comma_count=$class=~tr/,//;
    if ($comma_count > 0){
        $class_filename_part="multiclass";
    } else {
        $class_filename_part=$class;
    }
} elsif ($project ne ""){
    $template_num=36;
    $class_filename_part=$project;
} elsif ($user ne ""){
    $template_num=1;
    $class_filename_part="user";
} else {
    $template_num=36;
    $class_filename_part="add";
}

my $caller_filename_part="-unknown";
# vars filled by --caller or --callercopy
my ($firstname_utf8_AD,$lastname_utf8_AD,$adminclass_AD,$existing_AD,$exammode_AD,$role_AD,
    $home_directory_AD,$user_account_control_AD,$toleration_date_AD,$deactivation_date_AD,
    $school_AD,$status_AD,$firstpassword_AD,$unid_AD);

# --caller
if ($caller ne ""){
    ($firstname_utf8_AD,$lastname_utf8_AD,$adminclass_AD,$existing_AD,$exammode_AD,$role_AD,
     $home_directory_AD,$user_account_control_AD,$toleration_date_AD,$deactivation_date_AD,
     $school_AD,$status_AD,$firstpassword_AD,$unid_AD)=
     &AD_get_user({ldap=>$ldap,
                   root_dse=>$root_dse,
                   root_dns=>$root_dns,
                   user=>$caller,
                 });
    if ($existing_AD eq "FALSE"){
        print "\nERROR: User $caller does not exist\n\n";
        exit 88;
    }
    $caller_filename_part="-"."$caller";
}

# --caller-copy
if ($caller_copy ne ""){
    ($firstname_utf8_AD,$lastname_utf8_AD,$adminclass_AD,$existing_AD,$exammode_AD,$role_AD,
     $home_directory_AD,$user_account_control_AD,$toleration_date_AD,$deactivation_date_AD,
     $school_AD,$status_AD,$firstpassword_AD,$unid_AD)=
     &AD_get_user({ldap=>$ldap,
                   root_dse=>$root_dse,
                   root_dns=>$root_dns,
                   user=>$caller_copy,
                 });
    if ($existing_AD eq "FALSE"){
        print "\nERROR: User $caller_copy does not exist\n\n";
        exit 88;
    }
    $caller_filename_part="-"."$caller_copy";
}

# assemble file basename
$output_file_basename="$class_filename_part"."$caller_filename_part";

# template num options
# --one-per-page
if ($one_per_page==1){
    # equal to --pp 1 
    $pp=1;
}
# --per-page <num> / --pp <num>
if ($pp!=0){
   $template_num=$pp;
   &print_title("Number of entries per page: $template_num");
}


# --template  /abs/path/override
if ($template ne ""){
    # this overrides all
    $template_path_abs=$template;
} elsif (-d $sophomorix_config{'SCHOOLS'}{$school}{'TEMPLATES_LATEX_DIR'}){
    # looking for custom templates
    &print_title("Custom templates:  $sophomorix_config{'SCHOOLS'}{$school}{'TEMPLATES_LATEX_DIR'}");
    my $search_string="-".$lang."-".$template_num."-template.tex";
    my $custom_template="";

    print "   * Looking for a custom template *$search_string\n";
    opendir TEMPLATE, $sophomorix_config{'SCHOOLS'}{$school}{'TEMPLATES_LATEX_DIR'};
    foreach my $file (readdir TEMPLATE){        
        if ($file eq "."){next};
        if ($file eq ".."){next};
        print "      * See if $file fits\n";
        if ($school eq $DevelConf::name_default_school){
            if ($file=~m/${search_string}$/){
                print "        * $file will be used as custom template\n";
                $custom_template=$sophomorix_config{'SCHOOLS'}{$school}{'TEMPLATES_LATEX_DIR'}."/".$file;
            }
        } else {
            if ($file=~m/^$school\./ and $file=~m/${search_string}$/){
                print "        * $file will be used as custom template\n";
                $custom_template=$sophomorix_config{'SCHOOLS'}{$school}{'TEMPLATES_LATEX_DIR'}."/".$file;
            }
        }
    }
    closedir(TEMPLATE);

    if ($custom_template ne ""){
        $template_path_abs=$custom_template;
    } else {
        $template_path_abs=$template_path_abs.$template_num."-template.tex";
    }
} else {
    # assemble default template path
    $template_path_abs=$template_path_abs.$template_num."-template.tex";
}

# test existance of template file
if (not -f $template_path_abs){
    print "\nERROR: Template does not exist: $template_path_abs\n\n";
    exit 88;
}

&print_title("Basename of output files: $output_file_basename");
my $template_dirname = dirname($template_path_abs);
my $template_basename = basename($template_path_abs);
&print_title("Template dir:  $template_dirname");
&print_title("Template file: $template_basename");

# ===========================================================================
# Read data from AD
# ===========================================================================
&Sophomorix::SophomorixBase::print_title("Looking for printout data in school $school");
my $ref_AD_printdata=&AD_get_printdata({ldap=>$ldap,
                                      root_dse=>$root_dse,
                                      root_dns=>$root_dns,
                                      users=>"TRUE",
                                      school=>$school,
                                      sophomorix_config=>\%sophomorix_config,
             });


# --info
if ($info==1){
    my $jsoninfo="PRINTDATA";
    my $jsoncomment="Printable Data";
    &json_dump({json => $json,
                jsoninfo => $jsoninfo,
                jsoncomment => $jsoncomment,
                object_name => $school,
                log_level => $Conf::log_level,
                hash_ref => $ref_AD_printdata,
                sophomorix_config => \%sophomorix_config,
               });
    exit;
}



# ===========================================================================
# decide which list to print
# ===========================================================================
my $ref_printlist;
my $latex_datablock="";

if ($class eq "" and $user eq "" and not defined $back_in_time){
    # print one school completely
    &open_output_files($output_file_basename);
    # walk through classes
    if (not exists $ref_AD_printdata->{'LIST_BY_sophomorixSchoolname_sophomorixAdminClass'}{$school}){
        my $error_message="School '".$school."' has no printout data";
	&log_script_exit($error_message,1,1,0,
            \@arguments,\%sophomorix_result,\%sophomorix_config,$json);
    }
    my @classlist = @{ $ref_AD_printdata->{'LIST_BY_sophomorixSchoolname_sophomorixAdminClass'}{$school} };
    @classlist = sort @classlist;
    foreach my $class_item (@classlist){
	print "   * Creating datablock for $class_item\n";
        $ref_printlist=$ref_AD_printdata->{'LIST_BY_sophomorixAdminClass'}{$class_item};
        $latex_datablock=&latex_datablock_from_list($class_item,$ref_printlist);
        &create_csv_files($ref_printlist);
    }

    &latex_from_template_and_datablock();

    &close_output_files($output_file_basename);
    &build_results; 
    &make_output_files_ro;

} elsif ($class ne ""){
    # --class <class1><class2>,...one ore commaseperated class/classes are given
    &open_output_files($output_file_basename);

    # create classlist
    my %classes_seen=();
    my @classlist=();
    my @classlist_option=split(/,/,$class);
    foreach my $class_item (@classlist_option){
        if (exists $classes_seen{$class_item}){
            # seen already, doing nothing
        } elsif (exists $ref_AD_printdata->{'LOOKUP_BY_sophomorixAdminClass'}{$class_item} 
            and not exists $classes_seen{$class_item}){
            print "   * $class_item selected\n";
            push @classlist, $class_item;
            $classes_seen{$class_item}="seen";
        } else {
            my $error_message="Class '".$class_item."' has no printout data in school '".$school."'";
	    &log_script_exit($error_message,1,1,0,
                \@arguments,\%sophomorix_result,\%sophomorix_config,$json);
        }
    }

    @classlist = sort @classlist;

    foreach my $class_item (@classlist){
	print "   * Creating datablock for $class_item\n";
        $ref_printlist=$ref_AD_printdata->{'LIST_BY_sophomorixAdminClass'}{$class_item};
        $latex_datablock=&latex_datablock_from_list($class_item,$ref_printlist);
        &create_csv_files($ref_printlist);
    }
    &latex_from_template_and_datablock();

    &close_output_files($output_file_basename);
    &build_results; 
    &make_output_files_ro;

} elsif ($user ne ""){
    # --user <user1><user2>,... are given
    &open_output_files($output_file_basename);

    # create userlist
    my %printdata=();
    my @users=split(/,/,$user);
    foreach my $username (@users){
        if (exists $ref_AD_printdata->{'LOOKUP_BY_sAMAccountName'}{$username}){
            print "   * $username selected\n";
            push @{ $printdata{'LIST'} }, $ref_AD_printdata->{'LOOKUP_BY_sAMAccountName'}{$username};
        } else {
	    my $error_message="User '".$username."' has no printout data in school '".$school."'";
            &log_script_exit($error_message,1,1,0,
                     \@arguments,\%sophomorix_result,\%sophomorix_config,$json);
        }
    }

    $ref_printlist=$printdata{'LIST'};
    $latex_datablock=&latex_datablock_from_list($class,$ref_printlist);
    &create_csv_files($ref_printlist);

    &latex_from_template_and_datablock();

    &close_output_files($output_file_basename);
    &build_results; 
    &make_output_files_ro;

} elsif (defined $back_in_time) {
    if ($back_in_time > $ref_AD_printdata->{'RESULT'}{'BACK_IN_TIME_MAX'}){
        my $error_message="I Can only go back to: --back-in-time $ref_AD_printdata->{'RESULT'}{'BACK_IN_TIME_MAX'} (see: sophomorix-print -i)";
	&log_script_exit($error_message,1,1,0,
            \@arguments,\%sophomorix_result,\%sophomorix_config,$json);

##        print "\n";
 #       print "ERROR: I Can only go back to:   --back-in-time $ref_AD_printdata->{'RESULT'}{'BACK_IN_TIME_MAX'}\n";
 #       print "  SEE: sophomorix-print -i\n\n";
 #       exit 88;
    }
    &open_output_files($output_file_basename);
    # go for back in time stuff, if nothing else ist given
    my $ymdhms=${ $ref_AD_printdata->{'LISTS'}{'sophomorixCreationDate'} }[$back_in_time];
    my $date=&ymdhms_to_date($ymdhms);
    print " Going Back in time $back_in_time steps to $date ($ymdhms)\n";
    $ref_printlist=$ref_AD_printdata->{'LIST_BY_sophomorixCreationDate'}{$ymdhms};

    $latex_datablock=&latex_datablock_from_list($class,$ref_printlist);
    &create_csv_files($ref_printlist);

    &latex_from_template_and_datablock();
    &close_output_files($output_file_basename);
    &build_results; 
    &make_output_files_ro;

} else {
    print "\nERROR: I don't know what to print\n\n";
    exit 88;
}

 

# ===========================================================================
# copy result, if necessary
# ===========================================================================
# --caller-copy (do the copy stuff)
if ($caller_copy ne ""){
    &print_title("Copying files to user $caller_copy in school $school_AD");
    my $smb_dir_home=$home_directory_AD;
    $smb_dir_home=~s/\\/\//g;
    my ($string1,$rel_path_home)=split(/$school_AD/,$smb_dir_home); # to home
    $rel_path_home=$rel_path_home."/".$sophomorix_config{'INI'}{'LATEX'}{'PRINT_HOME_SUBDIR'};
    my $smbclient_command=$sophomorix_config{'INI'}{'EXECUTABLES'}{'SMBCLIENT'}.
        " -U ".$DevelConf::sophomorix_file_admin."%'******'".
        " //$root_dns/$school_AD ".
        " -c 'md \"$rel_path_home\"; cd \"$rel_path_home\"; lcd \"$sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}\";".
        " prompt; mput $output_file_basename*; exit;'";
    &Sophomorix::SophomorixBase::smb_command($smbclient_command,$smb_admin_pass);
}



&AD_unbind_admin($ldap);
&log_script_end(\@arguments,\%sophomorix_result,\%sophomorix_config,$json);




# ===========================================================================
# Subroutines
# ===========================================================================

sub pdflatex {
    &print_title("pdflatex is creating $output_file_basename.pdf");
    my $pdflatex_command="cd $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}; ".
	                 "$sophomorix_config{'INI'}{'LATEX'}{'BIN_PDFLATEX'} ".$output_file_basename.".tex ".$dev_null;
    print "  * $pdflatex_command\n";
    system($pdflatex_command);
    system($pdflatex_command); # 2x, to create table of contents correctly

    # clean up
    system("rm -f $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.log $dev_null");
    system("rm -f $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.toc $dev_null");
    system("rm -f $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.aux $dev_null");
    system("rm -f $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.out $dev_null");

    &print_title("TEX-RESULT: $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.tex");
    &print_title("PDF-RESULT: $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.pdf");
}



sub latex {
    &print_title("Processing $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.tex");
    &print_title("latex is creating $output_file_basename.dvi");
    # PS aus $output_file_basename.tex erzeugen
    my $latex_command="cd $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}; ".
	              "$sophomorix_config{'INI'}{'LATEX'}{'BIN_LATEX'} ".$output_file_basename.".tex ".$dev_null;
    print "  * $latex_command\n";
    system($latex_command);
    system($latex_command); # 2x, to create table of contents correctly

    &print_title("dvips is creating $output_file_basename.ps");
    my $dvips_command="cd $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}; ".
	              "$sophomorix_config{'INI'}{'LATEX'}{'BIN_DVIPS'} ".$output_file_basename.".dvi ".$dev_null;
    print "  * $dvips_command\n";
    system($dvips_command);

    &print_title("ps2pdf is creating $output_file_basename.pdf");
    my $ps2pdf_command="cd $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}; ".
	              "$sophomorix_config{'INI'}{'LATEX'}{'BIN_PS2PDF'} ".$output_file_basename.".ps ".$dev_null;
    print "  * $ps2pdf_command\n";
    system($ps2pdf_command);

    # clean up
    system("rm -f $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.log $dev_null");
    system("rm -f $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.toc $dev_null");
    system("rm -f $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.aux $dev_null");
    system("rm -f $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.out $dev_null");
    system("rm -f $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.dvi $dev_null");

    &print_title("TEX-RESULT: $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.tex");
    &print_title("PS-RESULT:  $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.ps");
    &print_title("PDF-RESULT: $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/$output_file_basename.pdf");
}



sub build_results {
    if ($command eq "pdflatex"){
        &pdflatex;
    } elsif ($command eq "latex"){
        # higher quality
        &latex;
    } else {
        print "\nI do not know how to process the file ($command ?)\n\n";
    }
}



sub make_output_files_ro {
    system("chmod 400 $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/${output_file_basename}.* $dev_null");
    system("chmod 400 $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/${output_file_basename}-* $dev_null");
    system("chmod 400 $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/${output_file_basename}_* $dev_null");
    system("chown $caller $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/${output_file_basename}.* $dev_null");
    system("chown $caller $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/${output_file_basename}-* $dev_null");
    system("chown $caller $sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/${output_file_basename}_* $dev_null");
}



sub latex_datablock_from_list {
    my ($chead,$ref_printlist) = @_;
    # always APPEND to datablock
    my @list = @{ $ref_printlist };
    @list = sort @list;
    my $dataline_max=&dataline_max_from_template_path(); # max pp entries
    my $dataline_count=0; # counts pp entries
    my $last_count=$#list+1; # number of elements starting with 1,2,...
    foreach my $item (@list){
        my @data=split(/;/,$item);
        my $lastname= &string_to_latex($data[0]);
        my $firstname=&string_to_latex($data[1]);
        my $login=    &string_to_latex($data[2]);
        my $password= &string_to_latex($data[3]);
        my $school=   &string_to_latex($data[4]);
        my $role=     &string_to_latex($data[8]);
	my $workgroup=&string_to_latex($sophomorix_config{'samba'}{'smb.conf'}{'global'}{'workgroup'});
        my $class=&string_to_latex($data[5]);
	my $chead_latex=&string_to_latex($chead);
        $dataline_count++;
        if ($dataline_count==1){
            # first sophomorixdatabox must be preceeded by sophomorixnewpage
            $latex_datablock=$latex_datablock."\\sophomorixnewpage{".$chead_latex."}{}{}{}{}{}{}{}{}%\n";
        }
        $latex_datablock=$latex_datablock."\\sophomorixdatabox{".$lastname."}".
                                          "{".$firstname."}".
                                          "{".$login."}".
                                          "{".$password."}".
                                          "{".$school."}".
                                          "{".$class."}".
                                          "{".$role."}".
                                          "{".$data[9]."}".
                                          "{".$workgroup."}%\n";
        # decide if dataline_count must be reset (page completely full)
	if ($dataline_count==$dataline_max){
            $dataline_count=0;
        }
    }
    # fill up last page
    # $dataline_count==0: counter is reset, page was filled completely
    until ($dataline_count==0 or $dataline_count==$dataline_max){
        $dataline_count++;
        $latex_datablock=$latex_datablock."\\sophomorixdatabox{}{}{}{}{}{}{}{}{}%\n";
    }
    return $latex_datablock;
}



sub dataline_max_from_template_path {
    my $filename = basename($template_path_abs);
    my @strings=split(/-/,$filename);
    my $last_one = pop @strings; # the last
    my $num = pop @strings; # the last but one gives the number
    if (not defined $num){
        print "\nERROR: template max number could not be determined from filname $filename\n\n";
        exit 88;
    } elsif ($num < $sophomorix_config{'INI'}{'LATEX'}{'TEMPLATE_MIN_ITEM'}){
        print "\nERROR: template max number ($num) is not at least $sophomorix_config{'INI'}{'LATEX'}{'TEMPLATE_MIN_ITEM'}\n\n";
        exit 88;
    } elsif ($num > $sophomorix_config{'INI'}{'LATEX'}{'TEMPLATE_MAX_ITEM'} ){
        print "\nERROR: template max number ($num) is larger than $sophomorix_config{'INI'}{'LATEX'}{'TEMPLATE_MAX_ITEM'}\n\n";
        exit 88;
    }
    return $num;
}



sub create_csv_files {
    @{ $ref_printlist } = sort @{ $ref_printlist };
    foreach my $item ( @{ $ref_printlist } ){
        my @data=split(/;/,$item);
        my $csv = "";
        if ($nosplit_names==1) {
            $csv = $data[1] . ";" . $data[0] . ";" . $data[5] . ";" . $data[2] . ";" . $data[3] . ";" . $data[10] . ";";
        } else {
            $csv = $data[1] . " " . $data[0] . ";" . $data[5] . ";" . $data[2] . ";" . $data[3] . ";" . $data[10] . ";";
        }
        print CSV $csv."\l\r";
        print UNIXCSV $csv."\n";
        my $webuntis=$data[5].";".$data[0].";".$data[1].";".$data[2].";".$data[6].", ".$data[7].";".$data[10].";";
        print WEBUNIXCSV $webuntis."\n";
        print WEBCSV $webuntis."\l\r";
	my $examplix=$data[0].", ".$data[1].":---:---:".$data[5]."==".
	             $data[0].", ".$data[1].":---:---:".$data[5];
	print EXAMPLIX $examplix."\n";
    }
}



sub latex_from_template_and_datablock {
    open(TEMPLATE,"<$template_path_abs") || die "Error: $!";
    my $datablockmode="FALSE";
    while (<TEMPLATE>){
        my $line=$_;

        # replacements (use underscore here, from school.conf)
        my $admins_print=&string_to_latex($sophomorix_config{'SCHOOLS'}{$school}{'ADMINS_PRINT'});
        my $schoolstring;
        if ($school eq $DevelConf::name_default_school){
            $schoolstring=&string_to_latex($sophomorix_config{'SCHOOLS'}{$school}{'SCHOOL_LONGNAME'});
        } else {
            $schoolstring=&string_to_latex($sophomorix_config{'SCHOOLS'}{$school}{'SCHOOL_LONGNAME'}."(".$school.")");
        }

        # URLSTART_PRINT
        if (exists $sophomorix_config{'SCHOOLS'}{$school}{'URLSTART_PRINT'} and
            $sophomorix_config{'SCHOOLS'}{$school}{'URLSTART_PRINT'} ne ""
           ){
            my $urlstart_print=&string_to_latex($sophomorix_config{'SCHOOLS'}{$school}{'URLSTART_PRINT'});
            if ($urlstart_print eq "NONE"){
		$urlstart_print=" ";
            }
            $line=~s/\\textcolor\{red\}\{URLSTART\\_PRINT\}/$urlstart_print/;
        }
        # URLSTART_COMMENT_PRINT
        if (exists $sophomorix_config{'SCHOOLS'}{$school}{'URLSTART_COMMENT_PRINT'} and
            $sophomorix_config{'SCHOOLS'}{$school}{'URLSTART_COMMENT_PRINT'} ne ""
           ){
            my $urlstart_comment_print=&string_to_latex($sophomorix_config{'SCHOOLS'}{$school}{'URLSTART_COMMENT_PRINT'});
            if ($urlstart_comment_print eq "NONE"){
		$urlstart_comment_print=" ";
            }
            $line=~s/\\textcolor\{red\}\{URLSTART\\_COMMENT\\_PRINT\}/$urlstart_comment_print/;
        }
        # URLSCHUKO_PRINT
        if (exists $sophomorix_config{'SCHOOLS'}{$school}{'URLSCHUKO_PRINT'} and
            $sophomorix_config{'SCHOOLS'}{$school}{'URLSCHUKO_PRINT'} ne ""
           ){
            my $urlschuko_print=&string_to_latex($sophomorix_config{'SCHOOLS'}{$school}{'URLSCHUKO_PRINT'});
            if ($urlschuko_print eq "NONE"){
		$urlschuko_print=" ";
            }
            $line=~s/\\textcolor\{red\}\{URLSCHUKO\\_PRINT\}/$urlschuko_print/;
        }
        # URLSCHUKO_COMMENT_PRINT
        if (exists $sophomorix_config{'SCHOOLS'}{$school}{'URLSCHUKO_COMMENT_PRINT'} and
            $sophomorix_config{'SCHOOLS'}{$school}{'URLSCHUKO_COMMENT_PRINT'} ne ""
           ){
            my $urlschuko_comment_print=&string_to_latex($sophomorix_config{'SCHOOLS'}{$school}{'URLSCHUKO_COMMENT_PRINT'});
            if ($urlschuko_comment_print eq "NONE"){
		$urlschuko_comment_print=" ";
            }
            $line=~s/\\textcolor\{red\}\{URLSCHUKO\\_COMMENT\\_PRINT\}/$urlschuko_comment_print/;
        }
        # URLMAIL_PRINT
        if (exists $sophomorix_config{'SCHOOLS'}{$school}{'URLMAIL_PRINT'} and
            $sophomorix_config{'SCHOOLS'}{$school}{'URLMAIL_PRINT'} ne ""
           ){
            my $urlmail_print=&string_to_latex($sophomorix_config{'SCHOOLS'}{$school}{'URLMAIL_PRINT'});
            if ($urlmail_print eq "NONE"){
		$urlmail_print=" ";
            }
            $line=~s/\\textcolor\{red\}\{URLMAIL\\_PRINT\}/$urlmail_print/;
        }
        # URLMAIL_COMMENT_PRINT
        if (exists $sophomorix_config{'SCHOOLS'}{$school}{'URLMAIL_COMMENT_PRINT'} and
            $sophomorix_config{'SCHOOLS'}{$school}{'URLMAIL_COMMENT_PRINT'} ne ""
           ){
            my $urlmail_comment_print=&string_to_latex($sophomorix_config{'SCHOOLS'}{$school}{'URLMAIL_COMMENT_PRINT'});
            if ($urlmail_comment_print eq "NONE"){
		$urlmail_comment_print=" ";
            }
            $line=~s/\\textcolor\{red\}\{URLMAIL\\_COMMENT\\_PRINT\}/$urlmail_comment_print/;
        }
        # URLMOODLE_PRINT
        if (exists $sophomorix_config{'SCHOOLS'}{$school}{'URLMOODLE_PRINT'} and
            $sophomorix_config{'SCHOOLS'}{$school}{'URLMOODLE_PRINT'} ne ""
           ){
            my $urlmoodle_print=&string_to_latex($sophomorix_config{'SCHOOLS'}{$school}{'URLMOODLE_PRINT'});
            if ($urlmoodle_print eq "NONE"){
		$urlmoodle_print=" ";
            }
            $line=~s/\\textcolor\{red\}\{URLMOODLE\\_PRINT\}/$urlmoodle_print/;
        }
        # URLMOODLE_COMMENT_PRINT
        if (exists $sophomorix_config{'SCHOOLS'}{$school}{'URLMOODLE_COMMENT_PRINT'} and
            $sophomorix_config{'SCHOOLS'}{$school}{'URLMOODLE_COMMENT_PRINT'} ne ""
           ){
            my $urlmoodle_comment_print=&string_to_latex($sophomorix_config{'SCHOOLS'}{$school}{'URLMOODLE_COMMENT_PRINT'});
            if ($urlmoodle_comment_print eq "NONE"){
		$urlmoodle_comment_print=" ";
            }
            $line=~s/\\textcolor\{red\}\{URLMOODLE\\_COMMENT\\_PRINT\}/$urlmoodle_comment_print/;
        }
 
        # (use hyphen here for template)
	my $filename_footer=&string_to_latex($output_file_basename);
        $line=~s/\\textcolor\{red\}\{SCHOOL-LONGNAME\}/$schoolstring/;
        $line=~s/\\textcolor\{red\}\{FILENAME\}/$filename_footer/;
        $line=~s/\\textcolor\{red\}\{ADMINS-PRINT\}/$admins_print/;


        if ($line=~m/DATABLOCK START/){
            $datablockmode="TRUE";
            print LATEX $line; # print the line to make debugging easier
            print LATEX $latex_datablock;
        } elsif ($line=~m/DATABLOCK END/){
            $datablockmode="FALSE";
        }

        if ($datablockmode eq "FALSE"){
            print LATEX $line;
        }
    }
    close(TEMPLATE);
}



sub open_output_files {
    my $file;
    $file=$sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}."/".${output_file_basename}.".tex";
    open(LATEX,">$file") || die "Error: $!";
    # CSV Windows
    $file=$sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}."/".${output_file_basename}.".csv";
    &print_title("CSV-RESULT: $file");
    open(CSV,">$sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}/${output_file_basename}.csv") || die "Error: $!";
    # CSV Linux
    $file=$sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}."/".${output_file_basename}."-unix.csv";
    &print_title("CSV-UNIX-RESULT: $file");
    open(UNIXCSV,">$file") || die "Error: $!";
    # Webuntis CSV Windows
    $file=$sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}."/".${output_file_basename}."_WebUntis.csv";
    &print_title("WEBUNTIS-RESULT: $file");
    open(WEBCSV,">$file") || die "Error: $!";
    # Webuntis CSV Linux
    $file=$sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}."/".${output_file_basename}."_WebUntis-unix.csv";
    &print_title("WEBUNTIS-UNIX-RESULT: $file");
    open(WEBUNIXCSV,">$file") || die "Error: $!";
    # examplix Linux
    $file=$sophomorix_config{'INI'}{'LATEX'}{'PRINT_PATH'}."/".${output_file_basename}."_examplix.cfg";
    &print_title("EXAMPLIX-RESULT: $file");
    open(EXAMPLIX,">$file") || die "Error: $!";
}



sub close_output_files {
    close(LATEX);
    close(CSV);
    close(UNIXCSV);
    close(WEBCSV);
    close(WEBUNIXCSV);
    close(EXAMPLIX);
}
