#!/bin/bash

# pdfDruck Version 3.1 vom 07.03.21 abends
# Autor Frank Frater, info@baum-pflege.de, GNU GPL
# Menüs Druckerauswahl ergänzt um Infos; andere Optionen raus genommen
# Wird über die Dolphin / Konqueror / ...  *.pdf - Kontextmenü  ->  pdf - Druck aufgerufen
# Soll pdfs direkt drucken, bei Bedarf auch 2 Dokumentseiten auf 1 Druckseite
# Es werden einfach die übergebenen Parameter an den lp - Befehl übergeben

# Für den Broschürendruck wird es komplizierter, da müssen die Seiten umgerechnet werden,
# um dann beidseitig mit 2 Dokumentseiten pro Druckseite gedruckt zu werden.

# Druckerauswahl: Es wird der PrNr - te Drucker in der Liste aus /etc/printcap gewählt
PrNr=0
PrName=$(sed -n -e '/^#/!p' /etc/printcap | sed -n $PrNr's/\(.*\)|.*/\1/p')

# Standard-Ausgabe umleiten in Logdatei
WorkDir="${0%/*}"/                # von Pfad/Name dieses lfd. Scriptes rechts Namen weg und / dazu
Log=pdfDruck.log
exec > "$WorkDir""$Log" 2>&1

# Log starten
echo "pdf - Druck  -  Log" ; echo
echo "`date`" ; echo

echo "Parameter:"
echo "Klick auf \$1: "$1 ; InPdf=${1##*/}
echo "Dateiname:     "$InPdf
ComeFrom=$PWD"/"                        # nachher gibts ein cd, deshalb abspeichern
echo "in Dir  \$PWD: "$ComeFrom ; echo
echo "ein-/doppelseitig \$2: "$2 ; Sides=$2 ; Bro=$2
echo "Seiten pro Blatt  \$3: "$3 ; NumberUp=$3
echo ; echo "Ich bin   \$0: "$0
echo "WorkDir     : "$WorkDir
echo "Drucker:      "$PrName

if [ -z $PrName ] ; then                # Drucker nicht vorhanden (-z: String leer)?
    Sides=det
    #kdialog --geometry=350x300+200+180 --error "Drucker nicht vorhanden.\nPrinterNr in Zeile 12 zeigt auf einen leeren String in /etc/printcap.\nSo ist kein Drucker ansprechbar. Bitte kontrollieren, ich breche ab."
    echo ; echo "PrinterNr in Zeile 12 zeigt auf einen leeren String in /etc/printcap."
    echo "\$Sides=det gesetzt für Druckerauswahl-Menü."
    #echo "So ist kein Drucker ansprechbar. Bitte kontrollieren, ich breche ab." ; exit
    #kate "$WorkDir""$Log" & exit
fi

# Funktion setzen: Führende Nullen dazu bauen, damit pdftk nachher keine Unordnung macht
nulldazu() {
StrLen=$(expr length $PgBro)
    if [ $StrLen -lt 3 ] ; then
        PgBro=0$PgBro
    fi
}

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

# Detaiauswahl / Drucker?

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

auswahldialog() {
    echo ; echo "Druckerauswahl - KDialog"
    PrList=($(sed -n -e '/^#/!p' /etc/printcap | sed -n 's/\(.*\)|.*/\1/p')) ; echo ${PrList[@]}
    PrNrTot=${#PrList[*]} ; echo "Das sind $PrNrTot Drucker."
    PrTmp=$(kdialog --title "pdf-Druck" --geometry 400x240+500+400 --combobox "Drucker auswählen\n(Auswahl Druckmodus folgt)\n\npdf-Druck Standarddrucker derzeit:\n\n                           $PrName" "${PrList[@]}")
    back=$?
    if [ $back = 1 ] ; then                   # Abbruch gewählt
    echo "-Abbruch-" ; exit
    fi
    if [[ -z $PrTmp ]] ; then               # Leeres Feld ausgewählt
    echo "Leere Auswahl."
    if [ $i -eq 1 ] ; then                  # i wird unten hochgezählt; beim zweiten mal Abbruch
        kdialog --title "pdf-Druck" --geometry 300x200+500+400 --msgbox "Zweimal leeres Feld ausgewählt.\nWenn das ein Versehen war,\nbitte nochmal starten."
        exit
    fi
fi
}

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


if [ $Sides = det ] ; then                  # wenn weitere Optionen bei Kontextmenü gewählt
    i=0
    auswahldialog                           # Auswahldialog Drucker
    if [[ -z $PrTmp ]] ; then               # wenn leeres Feld gewählt
        ((i++)) ; auswahldialog             # dann nochmal zur Auswahl; i rauf, für Abbruch nach 2 mal
    fi
    echo "gewählter Drucker: "$PrTmp

    # Soll das der neue Standarddrucker werden?
    if ! [ $PrTmp = $PrName ] ; then        # Frage nur, wenns nicht eh schon Standarddrucker ist
        StdDr=$(kdialog --title "pdf-Druck" --yesno "Standarddrucker momentan:  $PrName\nSoll  $PrTmp  neuer Standarddrucker\nfür PDF-Druck werden?") ; back=$? ; echo "Antwort Standarddrucker?: $back"
        if [ $back = 0 ] ; then             # soll Standarddrucker werden
            NrNr=$(grep "#" /etc/printcap | wc -l)                      # Anzahl der # -Zeilen am Anfang
            PrNr=$(grep -n "$PrTmp" /etc/printcap | cut -d':' -f 1)     # Zeilennummer des Druckers
            echo "Anzahl Rauten: -$NrNr- Druckerzeilennummer: -$PrNr-"
            PrNr=$(($PrNr-$NrNr)) ; echo "Druckernummer ist: $PrNr"
            # Mit sed die Druckernummer in diesem Script am Anfang ändern
            sed -i '1,15s/PrNr=.*/PrNr='$PrNr'/' $0
            echo "Neuer Standarddrucker Nr. $PrNr, $PrTmp."
        fi                                  # soll nicht Standarddrucker werden
    fi                                      # if obs eh schon Standarddrucker ist
    PrName=$PrTmp                           # schliesslich die Auswahl übernehmen

#################################################################### Nun abfragen, was wir denn tun wollen...
echo "Abfrage kdialog was nun zu tun ist..."

Sides0=$(kdialog --title "pdf-Druck" --radiolist "Wie wollen wir drucken?" "one-sided;1" "einseitig" off "two-sided-long-edge;1" "beidseitig" off "one-sided;2" "einseitig 2 auf 1 Seite" off "two-sided-short-edge;2" "beidseitig 2 auf 1 Seite" off "bro;2" "Broschüre" on) ; back=$?

if [ $back = 1 ] ; then                     # Abbruch
    echo "-Abbruch-" ; exit
fi

echo "... gewählt: $Sides0"
Sides=$(cut -d';' -f 1 <<< $Sides0) ; NumberUp=$(cut -d';' -f 2 <<< $Sides0)
Bro=$Sides                                  # damit am Ende tmp geleert wird
echo "Ergo Sides: $Sides und NumberUp: $NumberUp"

fi                                          # andere_Optionen ($Sides=det)
# Vorangegangenes: Details / Druckerauswahl im Kontextmenü gewählt
# ab hier also weiter im eigentlich normalen Programm
#####################################################################

# Broschürendruck?

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

if [ $Sides = bro ] ; then                    # Broschürendruck

echo ; echo "Broschürendruck." ; echo "--------------------"

# temporäres ArbeitsDir erstellen, falls es das schon gibt muss es leer sein
TmpDir=$WorkDir"tmp" ; echo "TmpDir ist: "$TmpDir

if ! [ -d $TmpDir ] ; then
    mkdir $TmpDir
elif [ "$(ls -A $TmpDir)" ] ; then
     echo "Temporäres Arbeitsverzeichnis $TmpDir ist nicht leer."
     echo "Bitte kontrollieren, ich breche hier ab."
     kdialog --geometry=250x180+200+200 --error "Temporäres Arbeitsverzeichnis $TmpDir ist nicht leer.\nBitte kontrollieren, ich breche hier ab." ; exit
fi

# ausgewählte PDF in Einzelseiten zerlegen und diese in tmp abspeichern
pdftk "$InPdf" burst output $TmpDir/ff
# doc-data.txt wird mit erstellt, die stört mich
rm $TmpDir/*.txt
echo "Datei zerlegen: $InPdf in Einzelseiten" ; echo "abgelegt in $TmpDir." ; echo


cd "$WorkDir"tmp                # das ist jetzt einfacher
touch ff_0000.pdf               # will bei der Nummerierungs-Durcharbeitung mit 1 anfangen,
SinPgs=(*.pdf)                  # das Array "SINglePaGeS" braucht deshalb den Dummy ff_0000.pdf

echo "Die Einzelseiten sind (incl. Dummy ff_0000.pdf):" ; echo ${SinPgs[@]} ; echo

NumSinPgs=${#SinPgs[*]} ; ((NumSinPgs--))           # Die Seitenzahl ist für den loop nachher
echo "Das O-Dokument hat - $NumSinPgs - Seiten"     # eins abziehen für den Dummy ~0000.pdf

# Wir brauchen die Gesamtseitenzahl der zu druckenden Broschüre für die Seitenumrechnung,
# einschließlich eventueller Leerseiten. Ist also immer ein Faktor von 4.
# Die Formel: (INT((Seitenzahl-1)/4)+1)*4 , wobei Seitenzahl vom O-Dokument, also NumSinPgs ist

TotBroPgs=$(( (( (( $NumSinPgs - 1 )) / 4 + 1 )) * 4 ))
echo "Die Broschüre wird - $TotBroPgs - Seiten haben (incl. evtl. leere S. am Ende)"

# Wir brauchen die Mitte der Broschüre
Median=$(( $TotBroPgs / 2 ))
echo "Mitte der Broschüre Seite - $Median -"

echo ; echo "--------- Seitenzahlen umrechnen ------------" ; echo
# Zunächst die Seiten von 1 bis Broschürenmitte. Die Formel ist
# (Seite+1)+(INT((Seite-1)/2)*2) , wobei Seite sich auf das O-Dokument bezieht

echo "--- Seiten 1 bis $Median:"

for (( i=1 ; i<=$Median ; i++ )) ; do
    PgBro=$(( (( $i + 1 )) + (( (( $i - 1 )) / 2 )) * 2 ))
    nulldazu ; nulldazu # führende Nullen dazu, Funktion oben
    echo "$i -> $PgBro: mv ${SinPgs[$i]} $PgBro.pdf"
    mv ${SinPgs[$i]} $PgBro.pdf
done

# Dann der Teil ab Mitte. Formel: (((neueSeite) * 2) + MOD neueSeite;2 ) - ( 2 * MOD neueSeite;2 )
# wobei neueSeite = GesamtseitenzahlBro - SeiteO-Dok + 1 - zählt vom Ende bis zur Mitte rückwärts hoch

((Median++))                                                 # für die Schleife als start
echo ; echo "--- Seiten $Median bis $NumSinPgs:"

for (( i=$Median ; i<=$NumSinPgs ; i++ )) ; do
    NewPage=$(( $TotBroPgs - $i + 1 )) ; Mod=$(( $NewPage % 2 ))
    z1=$(( (( $NewPage * 2 )) + $Mod )) ; PgBro=$(( $z1 - $Mod * 2 ))
    nulldazu ; nulldazu # führende Nullen dazu, Funktion oben
    echo "$i -> $PgBro: mv ${SinPgs[$i]} $PgBro.pdf"
    mv ${SinPgs[$i]} $PgBro.pdf
done

# Neues pdf aus den Einzelseiten zimmern
echo ; echo "Broschüren-pdf erstellen:"
# Falls O-Dokument nicht ein Vielfaches von 4 Seiten hatte, fehlen jetzt einzelne Seiten
# irgendwo, da sie ja nicht mehr am Ende der Broschüre landen. Also entsprechende
# leere pdf-Seiten einfügen
echo "Benötigte leere Seiten einfügen:"
for (( i=1 ; i<=$TotBroPgs ; i++ )) ; do        # PgBro als Schleifenvariable geht nicht, weil
    PgBro=$i ; nulldazu ; nulldazu              # die Bash führende Nullen als Oktalzahl wertet
    if ! [ -f $PgBro.pdf ] ; then               # wenn eine Seitennummer fehlt (wurde oben nicht
        cp ../pdf_leer.pdf $PgBro.pdf           # errechnet) -> leere pdf einfügen
        echo "Leeres Seitendokument - $PgBro.pdf - eingefügt."
    fi
done
echo

rm ff_0000.pdf                                      # der Dummy darf jetzt raus

InPdf=${InPdf%.*}_brosch.pdf                        # Name gleich zum ggf. nachher speichern setzen

pdftk *.pdf cat output $WorkDir"tmp/$InPdf"         # wird in /tmp zusammengebaut
echo "Datei: $InPdf  erstellt in $WorkDir""tmp."

Sides="two-sided-short-edge" ; NumberUp=2           # drucken vorbereiten

if [ $3 = save ] ; then                             # wenn speichern gewählt
    mv "$WorkDir""tmp/$InPdf" "$ComeFrom$InPdf"     # Broschüren-pdf zum Ort des Klicks verschieben
    echo ; echo "$InPdf gespeichert nach $ComeFrom$InPdf."
    echo "Temporäres löschen..." ; rm "$WorkDir"tmp/*    # und Inhalt von /tmp löschen
    echo ; echo "----- fertig." ; exit
fi

# Jetzt noch den Pfad zum drucken korrekt einstellen
ComeFrom="$WorkDir"tmp/
echo ; echo "----- Broschüre: fertig. Ab zum Druck."

fi                                                          # Broschürendruck


##############################################################################
#
# -----------------------  Druckteil ----------------------------------
# Wir gehen davon aus, daß die .desktop-Datei korrekte Werte liefert,
# deshalb keine weiteren Prüfungen
##############################################################################

echo ; echo "-------------------" ; echo "gedruckt wird:" ; echo
echo "lp -o sides=$Sides -o number-up=$NumberUp $ComeFrom$InPdf -d $PrName"
lp -o sides=$Sides -o number-up=$NumberUp "$ComeFrom""$InPdf" -d "$PrName"

if [ $Bro = bro ] ; then
    echo ; echo "... und zuletzt noch Temporäres löschen. fettisch"
    rm "$WorkDir"tmp/*
fi
exit


