#!/bin/bash
# -*- coding:utf-8 -*-
# file KLEIDER/web/src/pinw/diagramme
# 2020-08-06 Herbert Schiemann <h.schiemann@herbaer.de>
# Diagramme zur Zahl der Zerlegungsfelder

# Zähler, Variable, Aktionen
declare_vars ()
{
   # Ein Leerzeichen als Wert bedeutet, dass Positionsargumente verarbeitet werden
   _argv="";

   # Suchpfad für rc-Dateien, : - getrennte Liste von Verzeichnispfaden
   # Falls leer, wird die Option --rc nicht speziell behandelt
   g_configpath= ;

   # Zähler
   g_counters="  \
      verbose    \
      overwrite  ";

   # Variable
   g_variables=" \
      srcdir     \
      infile     \
      outprf     " ;

   # Aktionen
   g_actions="  \
      graphs    \
      svg       \
      png       \
      delgraphs \
      delsvg    " ;
  has_actions=0 ;
} # declare_vars

# Default-Werte setzen
set_defaults () {
   local b=$(realpath $0);
   b=${b%/web/src/*};
   no_delgraphs=1;
   no_delsvg=1;
   [[ -n $verbose       ]] || verbose=1;
   [[ -n $overwrite     ]] || overwrite=0;
   [[ -n $srcdir        ]] || srcdir=$b/web/src/pinw;
   [[ -n $infile        ]] || infile=$srcdir/info/detailed_counts;
   [[ -n $outprf        ]] || outprf=${infile%/*}/graph_;
} # set_defaults

# Zeigt eine kurze Hilfe an
show_help ()
{
   local cmd=${0#*/} ;
   set_defaults ;
   cat << .HELP ;
$cmd --version
$cmd --help
$cmd [Option]*
--[no_]verbose         Ablauf nach stdout ausgeben ($verbose)?
--[no_]overwrite       Existierende Dateien überschreiben ($overwrite)?
--srcdir  SRCDIR       Verzeichnis der Skripte
                       ($srcdir)
--infile  INFILE       Eingabedatei
                       ($infile)
--outprf  OUTPRF       Prefix des Pfades der Ausgabedateien
                       ($outprf)
--graphs               XML-Dateien mit den Daten zur Graphik erstellen
--svg                  SVG-Dateien erstellen
--png                  PNG-Dateien erstellen
--delgraph             XML-Dateien mit den Graphikdaten löschen
--delsvg               SVG-Dateien löschen
.HELP
} # show_help

# Zeigt die Version an
show_version ()
{
   cat << .VERSION ;
diagramme 20200806
Website kleider.herbaer.de: Diagramme zur Pinwand-Darstellung
2020-08-06 Herbert Schiemann <h.schiemann@herbaer.de>
GPL Version 2 oder neuer
.VERSION
} # show_version

# Variable und Zähler initialisieren
init_vars () {
   local v;
   declare_vars ;
   for v in $g_counters $g_variables $g_actions; do
      eval "$v=" ;
   done;
} # init_vars

# Argumente verarbeiten
read_args ()
{
   local wd ;
   local lastwd ;
   local var ;
   local ok ;

   has_actions=0 ;
   for wd in "$@"; do
      if [[ "$lastwd" = "--" ]]; then
          _argv="$_argv $wd";
      elif [[ -n "$lastwd" ]]; then
         if [[ "$wd" =~ ^[\ a-zA-Z0-9./_#-]+$ ]]; then
            if [[ "$lastwd" == "rc" && -n "$g_configpath" ]]; then
               if ! read_configuration $wd; then
                  (( verbose )) && echo "Kann Konfiguration $wd nicht lesen" ;
                  exit 10 ;
               fi ;
            else
               ok=0 ;
               for var in $g_variables; do
                  if [[ "$var" == "$lastwd" ]]; then
                     (( ++ok )) ;
                     eval "$var=\"$wd\"" ;
                     break ;
                  fi ;
               done ;
               if (( ! ok )); then
                  (( verbose )) && echo "Unbekannte Option --$lastwd $wd" ;
                  exit 11 ;
               fi ;
            fi ;
         else
            (( verbose )) && echo "Ungültiger Optionswert --$lastwd $wd" ;
            exit 12;
         fi;
         lastwd= ;
      else
         case "$wd" in
            --version )
               show_version ;
               exit 0 ;
               ;;
            --help )
               show_version ;
               show_help ;
               exit 0 ;
               ;;
            -- )
               if [[ -n "$_argv" ]]; then
                  lastwd=--;
                  continue;
               else
                  (( verbose )) && echo "Ungültige Option $wd" ;
                  exit 13 ;
               fi ;
               ;;
            --* )
               if [[ "$wd" =~ ^--[a-z][a-z0-9_]*$ ]]; then
                  lastwd=${wd#--} ;
                  ok=0 ;
                  for var in $g_counters ; do
                     if   [[ "$lastwd" == $var    ]]; then
                        eval "(( ++$lastwd ))" ;
                     elif [[ "$lastwd" == "no_$var" ]]; then
                        eval "${lastwd#no_}=0" ;
                     else
                        continue;
                     fi;
                     (( ++ok )) ;
                     break ;
                  done;
                  if (( !ok )); then
                     for var in $g_actions; do
                        if [[ "$lastwd" == "$var" ]]; then
                           eval "(( ++$var ))" ;
                           (( ++ok ));
                           has_actions=1;
                           break;
                        elif [[ "$lastwd" == "no_$var" ]]; then
                           eval "(( ++no_$var ))" ;
                           (( ++ok ));
                           break;
                        fi;
                     done;
                  fi;
                  (( ok )) && lastwd=;
               else
                  (( verbose )) && echo "Ungültige Option $wd" ;
                  exit 14 ;
               fi ;
               ;;
            * )
               if [[ -n $_argv ]]; then
                   _argv="$_argv $wd";
               else
                   (( verbose )) && echo "Ungültige Option $wd" ;
                   exit 15 ;
               fi;
               ;;
         esac ;
      fi ;
   done ;
   if [[ -n $lastwd && "$lastwd" != "--" ]]; then
      (( verbose )) && echo "Unverarbeitete Option --$lastwd";
      exit 16 ;
   fi ;
} # read_args

# Aktionen ausführen
run_actions ()
{
   local act ;
   for act in $g_actions; do
     eval "(( ! has_actions && ! no_$act || $act )) && process_$act";
   done;
} # run_actions

# Werte der Variablen anzeigen
show_variables ()
{
   local v ;
   for v in $g_counters $g_variables $g_actions $1; do
      eval "echo \"$v = \$$v\"" ;
   done;
} # show_variables

# Können die Eingabedateien gelesen werden?
check_infiles ()
{
   local f ;
   for f in "$@"; do
      if [[ ! -f "$f" ]]; then
         (( verbose )) && echo "$f\" ist keine gewöhnliche Datei";
         return 1;
      fi;
      if [[ ! -s "$f" ]]; then
         (( verbose )) && echo "$f\" ist leer";
         return 1;
      fi;
      if [[ ! -r "$f" ]]; then
         (( verbose )) && echo "Kann Datei \"$f\" nicht lesen";
         return 1;
      fi;
   done;
   return 0;
} # check_infiles

# Können die Ausgabedateien erstellt werden?
check_outfiles ()
{
   local fp ;
   local dir ;
   local verb ;
   (( verbose )) && verb=--verbose ;
   for fp in "$@"; do
      if [[ ! -e $fp ]]; then
         dir=${fp%/*};
         if [[ -n $dir && ! -e $dir ]]; then
            mkdir -p $verb $dir ;
            if [[ ! -d $dir ]]; then
               (( verbose )) && echo "$dir ist kein Verzeichnis";
               return 1;
            fi;
         fi;
      elif [[ -d $fp ]]; then
         (( verbose )) && echo "$fp ist ein Verzeichnis";
         return 1;
      elif (( overwrite )); then
         (( verbose )) && echo "lösche $fp";
         rm $fp;
      else
         (( verbose )) && echo "$fp existiert";
         return 1;
      fi;
      (( verbose )) && echo "$fp";
   done;
   return 0;
} # check_outfiles

# Sind die Dateien ausführbar?
# check_executeable first/path/to/script path/to/second_srcipt ;
check_executeable ()
{
   local f ;
   for f in "$@"; do
      if [[ ! -f "$f" ]]; then
         (( verbose )) && echo "$f\" ist keine gewöhnliche Datei";
         return 1;
      fi;
      if [[ ! -x "$f" ]]; then
         (( verbose )) && echo "$f\" ist keine ausführbare Datei";
         return 1;
      fi;
   done;
   return 0;
} # check_executeable

# XML-Dateien mit den Daten zur Graphik erstellen
process_graphs () {
   (( verbose )) && echo "process_graphs";
   check_executeable $srcdir/diagramme.pl || return;
   check_infiles     $infile              || return;
   $srcdir/diagramme.pl --in $infile --out $outprf\$\{key\}.xml ;
} # process_graphs

# SVG-Dateien erstellen
process_svg () {
   (( verbose )) && echo "process_svg";
   local b;
   check_infiles $srcdir/pd_svg.xslt || return ;
   for f in $outprf*.xml; do
      b=${f%.xml};
      check_outfiles $b.svg  || continue ;
      xsltproc $srcdir/pd_svg.xslt $f > $b.svg;
   done;
} # process_svg

# PNG-Dateien erstellen
process_png () {
   (( verbose )) && echo "process_png";
   local b;
   for f in $outprf*.xml; do
      b=${f%.xml};
      check_infiles  $b.svg || continue
      check_outfiles $b.png || continue;
      convert $b.svg $b.png;
   done;
} # process_png

# XML-Dateien mit den Graphikdaten löschen
process_delgraph () {
   (( verbose )) && echo "process_delgraph";
   local b;
   for f in $outprf*.xml; do
      b=${f%.xml};
      check_infiles  $b.svg || continue
      rm $f;
   done;
} # process_delgraph

# SVG-Dateien löschen
process_delsvg () {
   (( verbose )) && echo "process_delsvg";
   local b;
   for f in $outprf*.svg; do
      b=${f%.svg};
      check_infiles  $b.png || continue
      rm $f;
   done;
} # process_delsvg

# Sicherheit
# export PATH=/bin:/usr/local/bin:/usr/bin ;
IFS=$' \t\n' ;
set -o noclobber ;   # existierende Dateien werden nicht überschrieben
shopt -s extglob nullglob ;
init_vars ;
read_args "$@" ;
set_defaults ;

(( verbose > 1 )) && show_variables ;
run_actions ;
exit 0;

# end of file KLEIDER/web/src/pinw/diagramme
