# ======= 8< ======= FileApiGroupTest.sh =============================== 

#!/bin/bash

# Tries to read as many integer values as possible upto maxNumbers 
# from file fileName into the given array numbers. 
# Returns the number of the actually read numbers. May cause an exception. 
# (generated by Structorizer 3.32-33) 

# Copyright (C) 2020-03-21 Kay Gürtzig 
# License: GPLv3-link 
# GNU General Public License (V 3) 
# https://www.gnu.org/licenses/gpl.html 
# http://www.gnu.de/documents/gpl.de.html 

# TODO The exported algorithms made use of the Structorizer File API. 
#      Unfortunately there are no comparable constructs in shell 
#      syntax for automatic conversion. 
#      The respective lines are marked with a TODO File API comment. 
#      You might try something like "echo value >> filename" for output 
#      or "while ... do ... read var ... done < filename" for input. 

function finally87f383f()
{
    exitCode=$?
    arg1=$1
    # TODO File API: Replace the "fileClose" call by an appropriate shell construct 
    fileClose(fileNo)
    if [ "$arg1" = trapped ]
    then
        exit ${exitCode}
    fi
}

# Draws a bar chart from the array "values" of size nValues. 
# Turtleizer must be activated and will scale the chart into a square of 
# 500 x 500 pixels 
# Note: The function is not robust against empty array or totally equal values. 
function drawBarChart() {
    declare -n values=$1
    local nValues=$2

    # TODO: Check and revise the syntax of all expressions! 

    # Used range of the Turtleizer screen 
    const xSize <- 500
    const ySize <- 500
    kMin <- 0
    kMax <- 0

    for (( k=1; k<=nValues-1; k++ ))
    do

        if values[k] > values[kMax]
        then
            kMax <- k
        elif values[k] < values[kMin]
        then
            kMin <- k
        fi

    done

    valMin <- values[kMin]
    valMax <- values[kMax]
    yScale <- valMax * 1.0 / (ySize - 1)
    yAxis <- ySize - 1

    if valMin < 0
    then

        if valMax > 0
        then
            yAxis <- valMax * ySize * 1.0 / (valMax - valMin)
            yScale <- (valMax - valMin) * 1.0 / (ySize - 1)
        else
            yAxis <- 1
            yScale <- valMin * 1.0 / (ySize - 1)
        fi

    fi

    # draw coordinate axes 
    gotoXY(1, ySize - 1)
    forward(ySize -1) # color = ffffff
    penUp()
    backward(yAxis) # color = ffffff
    right(90)
    penDown()
    forward(xSize -1) # color = ffffff
    penUp()
    backward(xSize-1) # color = ffffff
    stripeWidth <- xSize / nValues

    for (( k=0; k<=nValues-1; k++ ))
    do
        stripeHeight <- values[k] * 1.0 / yScale

        case k mod 3 in

            0)
                setPenColor(255,0,0)
            ;;

            1)
                setPenColor(0, 255,0)
            ;;

            2)
                setPenColor(0, 0, 255)
            ;;
        esac

        fd(1) # color = ffffff
        left(90)
        penDown()
        fd(stripeHeight) # color = ffffff
        right(90)
        fd(stripeWidth - 1) # color = ffffff
        right(90)
        forward(stripeHeight) # color = ffffff
        left(90)
        penUp()
    done

}
# = = = = 8< = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 

function readNumbers() {
    local fileName=$1
    declare -n numbers=$2
    declare -i maxNumbers=$3

    # TODO: Check and revise the syntax of all expressions! 

    nNumbers <- 0
    # TODO File API: Replace the "fileOpen" call by an appropriate shell construct 
    fileNo <- fileOpen(fileName)

    if fileNo <= 0
    then
        # throw "File could not be opened!" 
        return 42
    fi

    trap87f383f=$( trap -p EXIT )
    if [ -z "$trap87f383f" ] ; then trap87f383f="-"; else trap87f383f=${trap87f383f:8}; trap87f383f=${trap87f383f% *}; fi
    if [ "${trap87f383f:0:1}" = "'" ] ; then trap87f383f=${trap87f383f:1} ; trap87f383f=${trap87f383f%\'*}; fi
    trap "finally87f383f trapped" EXIT
    { # try

        # TODO File API: Replace the "fileEOF" call by an appropriate shell construct 
        while not fileEOF(fileNo) and nNumbers < maxNumbers
        do
            # TODO File API: Replace the "fileReadInt" call by an appropriate shell construct 
            number <- fileReadInt(fileNo) &&
            numbers[nNumbers] <- number &&
            nNumbers <- nNumbers + 1 &&
            true
        done &&

        true
    } || { # catch error
        # throw 
        return 42
    }
    trap "${trap87f383f}" EXIT
    { # finally
        finally87f383f okay
    }
    return nNumbers
}

# ======= 8< =========================================================== 

#!/bin/bash
. FileApiGroupTest.sh

# Computes the sum and average of the numbers read from a user-specified 
# text file (which might have been created via generateRandomNumberFile(4)). 
#  
# This program is part of an arrangement used to test group code export (issue 
# #828) with FileAPI dependency. 
# The input check loop has been disabled (replaced by a simple unchecked input 
# instruction) in order to test the effect of indirect FileAPI dependency (only the 
# called subroutine directly requires FileAPI now). 
# (generated by Structorizer 3.32-33) 

# Copyright (C) 2020-03-21 Kay Gürtzig 
# License: GPLv3-link 
# GNU General Public License (V 3) 
# https://www.gnu.org/licenses/gpl.html 
# http://www.gnu.de/documents/gpl.de.html 

function finally87f383f()
{
    exitCode=$?
    arg1=$1
    fileClose(fileNo)
    if [ "$arg1" = trapped ]
    then
        exit ${exitCode}
    fi
}

# = = = = 8< = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 

# TODO: Check and revise the syntax of all expressions! 

fileNo <- 1000
# Disable this if you enable the loop below! 
echo -n "Name/path of the number file" ; read file_name
#  
# If you enable this loop, then the preceding input instruction is to be disabled 
# and the fileClose instruction in the alternative below is to be enabled. 
# NOTE: Represents a REPEAT UNTIL loop, see conditional break at the end. 
# while : 
# do 
#     echo -n "Name/path of the number file" ; read file_name 
#     fileNo <- fileOpen(file_name) 
#     not (fileNo > 0 or file_name = "") || break 
# done 
#  

if fileNo > 0
then
    # This should be enabled if the input check loop above gets enabled. 
#     fileClose(fileNo) 
    values <- {}
    nValues <- 0
    { # try
        nValues <- readNumbers(file_name, values, 1000) &&
        true
    } || { # catch failure
        echo failure
        exit  -7
    }
    sum <- 0.0

    for (( k=0; k<=nValues-1; k++ ))
    do
        sum <- sum + values[k]
    done

    echo "sum = ", sum
    echo "average = ", sum / nValues
fi

# ======= 8< =========================================================== 

#!/bin/bash
. FileApiGroupTest.sh

# Reads a random number file and draws a histogram accotrding to the 
# user specifications 
# (generated by Structorizer 3.32-33) 

# Copyright (C) 2020-03-21 Kay Gürtzig 
# License: GPLv3-link 
# GNU General Public License (V 3) 
# https://www.gnu.org/licenses/gpl.html 
# http://www.gnu.de/documents/gpl.de.html 

# TODO The exported algorithms made use of the Structorizer File API. 
#      Unfortunately there are no comparable constructs in shell 
#      syntax for automatic conversion. 
#      The respective lines are marked with a TODO File API comment. 
#      You might try something like "echo value >> filename" for output 
#      or "while ... do ... read var ... done < filename" for input. 

function finally87f383f()
{
    exitCode=$?
    arg1=$1
    # TODO File API: Replace the "fileClose" call by an appropriate shell construct 
    fileClose(fileNo)
    if [ "$arg1" = trapped ]
    then
        exit ${exitCode}
    fi
}

# Draws a bar chart from the array "values" of size nValues. 
# Turtleizer must be activated and will scale the chart into a square of 
# 500 x 500 pixels 
# Note: The function is not robust against empty array or totally equal values. 
function drawBarChart() {
    declare -n values=$1
    local nValues=$2

    # TODO: Check and revise the syntax of all expressions! 

    # Used range of the Turtleizer screen 
    const xSize <- 500
    const ySize <- 500
    kMin <- 0
    kMax <- 0

    for (( k=1; k<=nValues-1; k++ ))
    do

        if values[k] > values[kMax]
        then
            kMax <- k
        elif values[k] < values[kMin]
        then
            kMin <- k
        fi

    done

    valMin <- values[kMin]
    valMax <- values[kMax]
    yScale <- valMax * 1.0 / (ySize - 1)
    yAxis <- ySize - 1

    if valMin < 0
    then

        if valMax > 0
        then
            yAxis <- valMax * ySize * 1.0 / (valMax - valMin)
            yScale <- (valMax - valMin) * 1.0 / (ySize - 1)
        else
            yAxis <- 1
            yScale <- valMin * 1.0 / (ySize - 1)
        fi

    fi

    # draw coordinate axes 
    gotoXY(1, ySize - 1)
    forward(ySize -1) # color = ffffff
    penUp()
    backward(yAxis) # color = ffffff
    right(90)
    penDown()
    forward(xSize -1) # color = ffffff
    penUp()
    backward(xSize-1) # color = ffffff
    stripeWidth <- xSize / nValues

    for (( k=0; k<=nValues-1; k++ ))
    do
        stripeHeight <- values[k] * 1.0 / yScale

        case k mod 3 in

            0)
                setPenColor(255,0,0)
            ;;

            1)
                setPenColor(0, 255,0)
            ;;

            2)
                setPenColor(0, 0, 255)
            ;;
        esac

        fd(1) # color = ffffff
        left(90)
        penDown()
        fd(stripeHeight) # color = ffffff
        right(90)
        fd(stripeWidth - 1) # color = ffffff
        right(90)
        forward(stripeHeight) # color = ffffff
        left(90)
        penUp()
    done

}
# = = = = 8< = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 

# TODO: Check and revise the syntax of all expressions! 

fileNo <- -10

# NOTE: Represents a REPEAT UNTIL loop, see conditional break at the end. 
while :
do
    echo -n "Name/path of the number file" ; read file_name
    # TODO File API: Replace the "fileOpen" call by an appropriate shell construct 
    fileNo <- fileOpen(file_name)
    not (fileNo > 0 or file_name = "") || break
done

if fileNo > 0
then
    # TODO File API: Replace the "fileClose" call by an appropriate shell construct 
    fileClose(fileNo)
    echo -n "number of intervals" ; read nIntervals

    # Initialize the interval counters 
    for (( k=0; k<=nIntervals-1; k++ ))
    do
        count[k] <- 0
    done

    # Index of the most populated interval 
    kMaxCount <- 0
    numberArray <- {}
    nObtained <- 0
    { # try
        nObtained <- readNumbers(file_name, numberArray, 10000) &&
        true
    } || { # catch failure
        echo failure
    }

    if nObtained > 0
    then
        min <- numberArray[0]
        max <- numberArray[0]

        for (( i=1; i<=nObtained-1; i++ ))
        do

            if numberArray[i] < min
            then
                min <- numberArray[i]
            elif numberArray[i] > max
            then
                max <- numberArray[i]
            fi

        done

        # Interval width 
        width <- (max - min) * 1.0 / nIntervals

        for (( i=0; i<=nObtained - 1; i++ ))
        do
            value <- numberArray[i]
            k <- 1

            while k < nIntervals and value > min + k * width
            do
                k <- k + 1
            done

            count[k-1] <- count[k-1] + 1

            if count[k-1] > count[kMaxCount]
            then
                kMaxCount <- k-1
            fi

        done

        drawBarChart(count, nIntervals)
        echo "Interval with max count: ", kMaxCount, " (", count[kMaxCount], ")"

        for (( k=0; k<=nIntervals-1; k++ ))
        do
            echo count[k], " numbers in interval ", k, " (", min + k * width, " ... ", min + (k+1) * width, ")"
        done

    else
        echo "No numbers read."
    fi

fi

