#!/usr/bin/zsh
#
# macronuts - script to calculate macronutrient amounts from given
# percentages. Just run zsh macronuts to get rudimentary help, and
# off you go.

function printCals
{
    local macroNut
    for macroNut in c f p
    do
        echo $(( ${percents[$macroNut]} / 100.0 * totalCal ))
    done
}

function printGrams
{

    local nut calsPerG 
    for nut calsPerG in c 4.0 f 9.0 p 4.0
    do
        echo $(( percents[$nut] / 100.0 * totalCal / calsPerG ))
    done
}

function printTable
{
    local formatHdr='%-10s %8s %8s %8s\n'
    local formatTbl='%-10s %8.0f %8.0f %8.0f\n'
    printf $formatHdr ''       Carbs          Fat            Protein
    printf $formatTbl Percent  ${percents[c]} ${percents[f]} ${percents[p]}
    printf $formatTbl Calories $(printCals)
    printf $formatTbl Grams    $(printGrams)
}

function error
{
    # $1: error message
    echo macronuts: error: $1 1>&2
    echo "usage: macronuts [-c pctCarbs] [-f pctFat] [-p pctProtein] totalCals"
    exit 1
}

function processArgs
{
    while getopts 'c:f:p:' arg
    do
        [[ $OPTARG != <0-100> ]] && 
            error "nutrients must be between 0 and 100"
        percents[$arg]=$OPTARG
    done
    shift $(( OPTIND - 1 ))
    [[ $# -ne 1 ]] && error "incorrect number of arguments"
    totalCal=$1
}

function addPercents
{
    float percent
    for percent in $percents
    do
        (( totalPcts += percent ))
    done
}

function validate
{
    [[ $totalPcts -gt 100 || $totalPcts -lt 0 ]] &&
        error "nutrients must be between 0 and 100."

    integer numberLeft=$(( 3 - ${#percents} ))
    [[ $numberLeft -eq 0 && $totalPcts -ne 100 ]] &&
        error "nutrients must total 100."

    local macroNut
    for macroNut in c f p
    do
        [[ ${+percents[$macroNut]} -eq 0 ]] &&
            (( percents[$macroNut] = (100 - totalPcts) / numberLeft ))
    done
}

###########################################################
### main
###########################################################

typeset -A percents
float totalPcts=0 totalCal

processArgs $@
addPercents
validate
printTable
