#!/bin/sh
# Copyright (C) 2007 Daniele Giacomini appunti2@gmail.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
P_PROGRAM_NAME="$0"
P_INPUT_FILE="$1"
P_SPEED_PERCENT="100"
P_CORRECT_PERCENT="100"
P_MAX_COLUMNS="30"
P_DIALOG_WIDTH=$(($P_MAX_COLUMNS+30))
P_DIALOG_HEIGHT=10
#P_DIALOG_TYPE="--inputbox"
P_DIALOG_TYPE="--passwordbox"
P_DIALOG_TEMP=`tempfile`
touch $P_DIALOG_TEMP
#
#
#
filter () {
    #
    # «´» --> «'»   U+00B4 --> U+0027
    # «’» --> «'»   U+2019 --> U+0027
    #
    cat \
    | sed "s/´/'/g" \
    | sed "s/’/'/g" \
    | sed "s/ / /g" \
    | tr "\r" " " \
    | tr "\t" " " \
    | sed "s/  */ /g" \
    | sed "s/^  *//g" \
    | sed "s/  *$//g"
}
#
#
#
input_filter () {
    local INPUT_FILE="$1"
    local FILTERED_FILE="$2"
    #
    # «´» --> «'»   U+00B4 --> U+0027
    # «’» --> «'»   U+2019 --> U+0027
    #
    cat "$INPUT_FILE" \
        | filter \
        | fold -s -w $P_MAX_COLUMNS \
        > $FILTERED_FILE
}
#
#
#
evaluation () {
    local EXPECTED_SPEED="$1"
    local SPEED="$2"
    local CORRECTNESS="$3"
    local EVALUATION_SPEED=""
    local EVALUATION_CORRECT=""
    #
    if [ 0$SPEED -gt 0$EXPECTED_SPEED ]
    then
        SPEED="$EXPECTED_SPEED"
    fi
    #
    EVALUATION_SPEED=$(($SPEED*$P_SPEED_PERCENT/$EXPECTED_SPEED))
    #
    EVALUATION_CORRECT=$(($CORRECTNESS*$P_CORRECT_PERCENT/100))
    #
    echo $(($EVALUATION_SPEED*$EVALUATION_CORRECT/100))
}
#
#
#
report () {
    local INPUT_FILTERED="$1"
    local INPUT_FILE="$2"
    local OUTPUT_FILE="$3"
    local TIME_START="$4"
    local TIME_END="$5"
    local SOURCE_WORDS=""
    local SOURCE_CHARACTERS=""
    local TYPED_LINES=""
    local ERROR_LINES=""
    local ABANDONED_LINES=""
    local CORRECT_LINES=""
    local ERROR=""
    local ABANDONED=""
    local CORRECTNESS=""
    local ELAP_T=""
    local ELAP_H=""
    local ELAP_M=""
    local ELAP_S=""
    local SPEED_WORDS=""
    local SPEED_CHARACTERS=""
    #
    local EVAL_1=""
    local EVAL_2=""
    local EVAL_3=""
    local EVAL_4=""
    local EVAL_5=""
    local EVAL_6=""
    local EVAL_7=""
    #
    local EVAL_W1=""
    local EVAL_W2=""
    local EVAL_W3=""
    local EVAL_W4=""
    local EVAL_W5=""
    local EVAL_W6=""
    local EVAL_W7=""
    #
    local TODAY=`date`
    #
    SOURCE_WORDS=`wc -w $INPUT_FILTERED | sed "s/^\([0-9]*\) .*$/\1/"`
    SOURCE_CHARACTERS=`wc -m $INPUT_FILTERED | sed "s/^\([0-9]*\) .*$/\1/"`
    TYPED_LINES=`wc -l $OUTPUT_FILE | sed "s/^\([0-9]*\) .*$/\1/"`
    ERROR_LINES=`cat $OUTPUT_FILE | grep "^!" | wc -l | sed "s/^\([0-9]*\) .*$/\1/"`
    ABANDONED_LINES=`cat $OUTPUT_FILE | grep "^?" | wc -l | sed "s/^\([0-9]*\) .*$/\1/"`
    CORRECT_LINES=`cat $OUTPUT_FILE | grep -v "^[!?]" | wc -l | sed "s/^\([0-9]*\) .*$/\1/"`
    ERROR=$(($ERROR_LINES*100/$TYPED_LINES))
    ABANDONED=$(($ABANDONED_LINES*100/$TYPED_LINES))
    CORRECTNESS=$((100-$ERROR-$ABANDONED))
    ELAP_T=$(($TIME_END-$TIME_START))
    ELAP_H=$(($ELAP_T/60/60))
    ELAP_M=$((($ELAP_T-($ELAP_H*60*60))/60))
    ELAP_S=$(($ELAP_T-($ELAP_H*60*60)-($ELAP_M*60)))
    ELAP_M=`printf "%02d" "$ELAP_M"`
    ELAP_S=`printf "%02d" "$ELAP_S"`
    SPEED_CHARACTERS=$((($SOURCE_CHARACTERS*60)/$ELAP_T))
    SPEED_WORDS=$((($SOURCE_WORDS*60)/$ELAP_T))
    #
    EVAL_1=`evaluation  50 $SPEED_CHARACTERS $CORRECTNESS`
    EVAL_2=`evaluation 100 $SPEED_CHARACTERS $CORRECTNESS`
    EVAL_3=`evaluation 150 $SPEED_CHARACTERS $CORRECTNESS`
    EVAL_4=`evaluation 200 $SPEED_CHARACTERS $CORRECTNESS`
    EVAL_5=`evaluation 250 $SPEED_CHARACTERS $CORRECTNESS`
    #
    EVAL_W1=`evaluation  20 $SPEED_WORDS $CORRECTNESS`
    EVAL_W2=`evaluation  40 $SPEED_WORDS $CORRECTNESS`
    EVAL_W3=`evaluation  60 $SPEED_WORDS $CORRECTNESS`
    EVAL_W4=`evaluation  80 $SPEED_WORDS $CORRECTNESS`
    EVAL_W5=`evaluation 100 $SPEED_WORDS $CORRECTNESS`
    #
    echo ""                                                     >> $OUTPUT_FILE
    echo "programma utilizzato:                   $P_PROGRAM_NAME" \
                                                                >> $OUTPUT_FILE
    echo "utente:                                 $USER"        >> $OUTPUT_FILE
    echo "data:                                   $TODAY"       >> $OUTPUT_FILE
    echo "file:                                   $INPUT_FILE"  >> $OUTPUT_FILE
    echo "parole contenute nel file originale:    $SOURCE_WORDS" \
                                                                >> $OUTPUT_FILE
    echo "caratteri contenuti nel file originale: $SOURCE_CHARACTERS" \
                                                                >> $OUTPUT_FILE
    echo "righe complessive, digitate o saltate:  $TYPED_LINES" >> $OUTPUT_FILE
    echo "righe errate:                           $ERROR_LINES" >> $OUTPUT_FILE
    echo "righe abbandonate:                      $ABANDONED_LINES" >> $OUTPUT_FILE
    echo "righe corrette:                         $CORRECT_LINES" \
                                                                >> $OUTPUT_FILE
    echo "righe errate:                           $ERROR %"     >> $OUTPUT_FILE
    echo "righe abbandonate:                      $ABANDONED %" >> $OUTPUT_FILE
    echo "righe corrette:                         $CORRECTNESS %" \
                                                                >> $OUTPUT_FILE
    echo "tempo impiegato:                        $ELAP_H:$ELAP_M:$ELAP_S" \
                                                                >> $OUTPUT_FILE
    echo "battute virtuali al minuto:             $SPEED_CHARACTERS" \
                                                                >> $OUTPUT_FILE
    echo "parole virtuali al minuto:              $SPEED_WORDS" >> $OUTPUT_FILE
    echo "indicatore di valutazione  50 battute:  $EVAL_1 %"    >> $OUTPUT_FILE
    echo "indicatore di valutazione 100 battute:  $EVAL_2 %"    >> $OUTPUT_FILE
    echo "indicatore di valutazione 150 battute:  $EVAL_3 %"    >> $OUTPUT_FILE
    echo "indicatore di valutazione 200 battute:  $EVAL_4 %"    >> $OUTPUT_FILE
    echo "indicatore di valutazione 250 battute:  $EVAL_5 %"    >> $OUTPUT_FILE
    echo "indicatore di valutazione  20 parole:   $EVAL_W1 %"   >> $OUTPUT_FILE
    echo "indicatore di valutazione  40 parole:   $EVAL_W2 %"   >> $OUTPUT_FILE
    echo "indicatore di valutazione  60 parole:   $EVAL_W3 %"   >> $OUTPUT_FILE
    echo "indicatore di valutazione  80 parole:   $EVAL_W4 %"   >> $OUTPUT_FILE
    echo "indicatore di valutazione 100 parole:   $EVAL_W5 %"   >> $OUTPUT_FILE
}
#
#
#
print () {
    local OUTPUT_FILE="$1"
    #
    # Enscript is not able to work with UTF-8.
    #
    recode -f UTF-8..Latin1 $OUTPUT_FILE
    #
    # Convert to PostScript.
    #
    cat $OUTPUT_FILE \
        | /usr/bin/enscript -X 88591 -1 -M a4 -f Courier@8.5/9.5 \
          --header "%N - %n - %F %C - p. \$%/\$= - $IPV4" \
          --header-font="Times-Roman@9/12" \
          --margin=72:72:72:72 -o - 2> "/dev/null" \
        > $OUTPUT_FILE.ps
    #
    lpr $OUTPUT_FILE.ps
}
#
#
#
typeit_loop () {
    local ORIGINAL_LINE=""
    local WRITTEN_LINE=""
    local ERROR_LINE=""
    #
    while read ORIGINAL_LINE
    do
        if [ "$ORIGINAL_LINE" = "" ]
        then
            continue
        else
            while [ "$ORIGINAL_LINE" != "$WRITTEN_LINE" ]
            do
                WRITTEN_LINE=""
                if dialog  \
                    --title "typeit" \
                    $P_DIALOG_TYPE \
                    "$ERROR_LINE\n $ORIGINAL_LINE" \
                    $P_DIALOG_HEIGHT $P_DIALOG_WIDTH \
                    "$WRITTEN_LINE" \
                    2> $P_DIALOG_TEMP
                then
                    WRITTEN_LINE=`cat $P_DIALOG_TEMP | filter`
                    echo "" > $P_DIALOG_TEMP
                    #
                    if   [ "$WRITTEN_LINE" = "" ]
                    then
                        ERROR_LINE="?$ORIGINAL_LINE     [riga non inserita]"
                        echo "$ERROR_LINE" 1>&2
                        break
                    elif [ "$ORIGINAL_LINE" = "$WRITTEN_LINE" ]
                    then
                        ERROR_LINE=""
                        echo " $WRITTEN_LINE" 1>&2
                        break
                    else                        
                        ERROR_LINE="!$WRITTEN_LINE      [riga errata]"
                        echo "$ERROR_LINE" 1>&2
                    fi
                else
                    exit
                fi
            done
        fi
    done        
}
#
#
#
menu () {
    local MENU_LIST=""
    #
    for f in *
    do
        if [ -r "$f" ]
        then
            MENU_LIST="$MENU_LIST $f ."
        fi
    done
    #
    if dialog   \
        --clear \
        --title "lectures" \
        --menu "" \
        0 0 0 \
        $MENU_LIST \
        2> $P_DIALOG_TEMP
    then
        P_INPUT_FILE=`cat $P_DIALOG_TEMP`
        echo "" > $P_DIALOG_TEMP
    else
        exit
    fi
}
#
#
#
main () {
    local INPUT_FILTERED
    local TIME_START=""
    local TIME_END=""
    local OUTPUT_FILE=`tempfile`
    touch $OUTPUT_FILE
    local INPUT_FILTERED=`tempfile`
    touch $INPUT_FILTERED
    #
    if [ -r "$P_INPUT_FILE" ]
    then
        true
    else
        menu
    fi
    #
    if [ -f "$P_INPUT_FILE" ] && [ -r "$P_INPUT_FILE" ]
    then
        input_filter "$P_INPUT_FILE" "$INPUT_FILTERED"
        TIME_START=`date +%s`
        typeit_loop < "$INPUT_FILTERED" 2>> $OUTPUT_FILE
        TIME_END=`date +%s`
        report "$INPUT_FILTERED" "$P_INPUT_FILE" "$OUTPUT_FILE" \
               "$TIME_START" "$TIME_END"
        print $OUTPUT_FILE
    else
        echo "Cannot access file \"$P_INPUT_FILE\"!"
    fi
    if [ -f $OUTPUT_FILE ]
    then
        rm $OUTPUT_FILE
    fi
    if [ -f $OUTPUT_FILE.ps ]
    then
        rm $OUTPUT_FILE.ps
    fi
    if [ -f $INPUT_FILTERED ]
    then
        rm $INPUT_FILTERED
    fi
}
#
# Start of program
#
main "$1"
rm $P_DIALOG_TEMP
#
