#!/bin/bash
# console-config/src/lib-scripts/serial-lowlatency-cd24-in.sh
#
#  Copyright: ©2014, Güralp Systems Ltd.
#  Author: Kelly Dunlop <kdunlop@guralp.com>
#  License: GPLv3
#
# Setup the parameters for a serial port configured for low latency CD24.



# Setup the array containing the list of instrument types that the user can select.
declare -a INSTRUMENT_LIST=( high-gain-seismometer 'High gain seismometer' \
                             low-gain-seismometer 'Low gain seismometer' \
                             accelerometer 'Accelerometer seismometer' \
                             infrasound 'Infrasound' \
                             hydrophone 'Hydrophone' \
                             geophone 'Geophone' \
                             temperature 'Thermometer' \
                             wind 'Wind speed' \
                             rainfall 'Rainfall sensor' \
                             pressure 'Pressure sensor' \
                             tilt-meter 'Tilt meter' \
                             humidity 'Hygrometer' \
                             magnetometer 'Magnetometer' \
                             gravimeter 'Gravimeter' \
                             mass-position-seismometer 'Mass position seismometer' \
                             creep-meter 'Creep meter' \
                             electronic-test-point 'Generic electronic test point' \
                             water-current 'Water flow/current sensor' \
                             electric-potential 'Voltmeter/electric potential sensor' \
                             linear-strain 'Strain gauge (linear)' \
                             tide 'Tide meter' \
                             bolometer 'Bolometer' \
                             volumetric-strain 'Strain gauge (volumetric)' \
                             calibration-input 'Calibration input' );



# These are the number of MAIN and MUX channels that are available to configure.
NUM_MAIN_CHANNELS=4
NUM_MUX_CHANNELS=8



# display_ll_cd24_priority 
# priority (default unset -> false)
# $1 is the title text to display
# $2 is the current value
display_ll_cd24_priority() {
    if [ -z "$2" -o "$2" = "false" ]
    then
        dialog --title "$1" \
               --defaultno \
               --yesno "Select yes to run with high priority." \
               0 0
    else
        dialog --title "$1" \
               --yesno "Select yes to run with high priority." \
               0 0
    fi
    return $?
}



# display_ll_cd24_station_name
# station_name (default hostname shortened to 5 chars and capitalised)
# $1 is the title text to display
# $2 is the current value
# $3 is the default value
display_ll_cd24_station_name() {
    local default

    if [ -z "$2" ]
    then
        default="$3"
    else
        default="$2"
    fi

    display_inputbox "$1" "SEED station name. Must be specified. 1-5 characters (A-Z, 0-9)" \
           0 0 "$default"
}



# display_ll_cd24_network_name
# network_name (default "")
# $1 is the title text to display
# $2 is the current value
display_ll_cd24_network_name() {
    display_inputbox "$1" "SEED network name. Optional. 1 or 2 characters (A-Z, 0-9)." \
           0 0 "$2"
}



# display_ll_cd24_location_name
# location_name (default last char of port name)
# $1 is the title text to display
# $2 is the current value
# $3 is the default value
display_ll_cd24_location_name() {
    local default

    if [ -z "$2" ]
    then
        default="$3"
    else
        default="$2"
    fi

    display_inputbox "$1" "SEED location name. Optional. 1 or 2 characters (A-Z, 0-9)." \
           0 0 "$default"
}



# display_ll_cd24_samples_per_second
# samples_per_second (default 200)
# $1 is the title text to display
# $2 is the current value
# $3 is the default value
# values are 50, 100, 200, 500
display_ll_cd24_samples_per_second() {
    local default

    if [ -z "$2" ]
    then
        default="$3"
    else
        default="$2"
    fi

    MENU=( "50" "50" \
           "100" "100" \
           "200" "200" \
           "500" "500" )

    display_menu "$1" "Select number of samples per second to acquire." 0 0 "$default"
}



# display_ll_cd24_high_pass
# high_pass (default 0 -> disabled)
# $1 is the title text to display
# $2 is the current value
display_ll_cd24_high_pass() {
    MENU=( "0" "Disabled" \
           "100" "100s" \
           "300" "300s" \
           "1000" "1000s" )

    display_menu "$1" "Disable high pass filter or choose its corner frequency." \
           0 6 "$2"
}



# display_ll_cd24_link_delay
# link_delay (default unset)
# $1 is the title text to display
# $2 is the current value
display_ll_cd24_link_delay() {
    display_inputbox "$1" "Link delay in seconds, used to estimate real time from data." \
           0 0 "$2"
}



# get_ll_cd24_main_channels
# This is to extract the information from the config file about the main channels setup
# Note this puts the information into 3 arrays.
# $1 is the name of the config file - note it is sectioned.
get_ll_cd24_main_channels() {
    local count=0
    local cfg="$1"
    local name component instrument

    while [ $count -lt ${NUM_MAIN_CHANNELS} ]
    do
        name="main_chan_${count}"

        component="`cf2get ${cfg} ["${name}"] component`"
        cf2true ${cfg} ["${name}"] enabled
        if [ $? -eq 0 ]
        then
            MAIN_ENABLED[$count]="true"
        else
            MAIN_ENABLED[$count]="false"
        fi

        instrument="`cf2get ${cfg} ["${name}"] instrument-type`"

        MAIN_COMP[$count]="${component}"
        MAIN_INST[$count]="${instrument}"

        ((count++))
    done
}



# put_ll_cd24_main_channels
# $1 is the name of the config file.
put_ll_cd24_main_channels() {
    local count=0
    local cfg="$1"

    while [ $count -lt ${NUM_MAIN_CHANNELS} ]
    do
        name="main_chan_${count}"

        cf2set ${cfg} ["${name}"] component=${MAIN_COMP[$count]}

        if [ "${MAIN_ENABLED[$count]}" = "true" ]
        then
            cf2set ${cfg} ["${name}"] enabled="true"
        else
            cf2set ${cfg} ["${name}"] enabled="false"
        fi

        cf2set ${cfg} ["${name}"] instrument-type=${MAIN_INST[$count]}

        ((count++))
    done
}



# get_ll_cd24_mux_channels
# This is to extract the information from the config file about the mux channels setup
# Note this puts the information into 3 arrays.
# $1 is the name of the config file - note it is sectioned.
get_ll_cd24_mux_channels() {
    local count=0
    local cfg="$1"
    local name component instrument

    while [ $count -lt ${NUM_MUX_CHANNELS} ]
    do
        name="mux_chan_${count}"

        component="`cf2get ${cfg} ["${name}"] component`"
        cf2true ${cfg} ["${name}"] enabled
        if [ $? -eq 0 ]
        then
            MUX_ENABLED[$count]="true"
        else
            MUX_ENABLED[$count]="false"
        fi

        instrument="`cf2get ${cfg} ["${name}"] instrument-type`"

        MUX_COMP[$count]="${component}"
        MUX_INST[$count]="${instrument}"

        ((count++))
    done
}



# put_ll_cd24_mux_channels
# This writes out the values for the mux channels.
# $1 is the name of the config file.
put_ll_cd24_mux_channels() {
    local count=0
    local cfg="$1"

    while [ $count -lt ${NUM_MUX_CHANNELS} ]
    do
        name="mux_chan_${count}"

        cf2set ${cfg} ["${name}"] component=${MUX_COMP[$count]}

        if [ "${MUX_ENABLED[$count]}" = "true" ]
        then
            cf2set ${cfg} ["${name}"] enabled="true"
        else
            cf2set ${cfg} ["${name}"] enabled="false"
        fi

        cf2set ${cfg} ["${name}"] instrument-type=${MUX_INST[$count]}

        ((count++))
    done
}



# display_ll_cd24_component
# Displays and allows the user to change the component value for a given channel.
# $1 is the title text to display
# $2 is the question/detail to display
# $3 is the current value to display
# $4 is the default value
display_ll_cd24_component() {
    local default

    if [ -z "$3" ]
    then
        default="$4"
    else
        default="$3"
    fi

    display_inputbox "$1" "$2" 0 0 "$default"
}



# display_ll_cd24_instrument
# Displays and allows the user to change the instrument type for a given channel.
# $1 is the title text to display
# $2 is the question/detail to display
# $3 is the current value to display
# $4 is the default value
display_ll_cd24_instrument() {
    local default

    if [ -z "$3" ]
    then
        default="$4"
    else
        default="$3"
    fi

    dialog --title "$1" \
           --default-item "$default" \
           --menu "$2" \
           0 ${DIALOG_WIDER_DEFAULT} 0 \
           "${INSTRUMENT_LIST[@]}" \
           2> "${DIALOG_RESULTFILE}"
    if [ $? -ne 0 ]
    then
        clear
        echo "Cancelled"
        exit 1
    fi
}



# display_ll_cd24_main_channels
# This displays and potentially changes the values in the 3 arrays for the main channels setup
# above in get_ll_cd24_main_channels().
# $1 is the title text to display
display_ll_cd24_main_channels() {
    local count newcomp newinst result def_component def_enabled

    count=0
    while [ $count -lt ${NUM_MAIN_CHANNELS} ]
    do
        case $count in
        0)  def_component="Z"
            def_enabled="true"
            ;;
        1)  def_component="N"
            def_enabled="true"
            ;;
        2)  def_component="E"
            def_enabled="true"
            ;;
        3)  def_component="X"
            def_enabled="false"
            ;;
        esac

        # component value
        display_ll_cd24_component "$1" "Index ${count} component setting" \
            "${MAIN_COMP[$count]}" "${def_component}"
        newcomp="`cat ${DIALOG_RESULTFILE}`"
        MAIN_COMP[$count]="${newcomp}"

        # enabled ? This is messy but I can't work out another way.
        if [ -z "${MAIN_ENABLED[$count]}" ]
        then
            if [ "${def_enabled}" = "true" ]
            then
                display_yesno "$1" "Index ${count} Is this entry enabled ? " 0 0
            else
                display_yesno "$1" "Index ${count} Is this entry enabled ? " 0 0 --defaultno
            fi
        else
            if [ "${MAIN_ENABLED[$count]}" = "true" ]
            then
                display_yesno "$1" "Index ${count} Is this entry enabled ? " 0 0
            else
                display_yesno "$1" "Index ${count} Is this entry enabled ? " 0 0 --defaultno
            fi
        fi

        result=$?
        if [ ${result} -eq 0 ]    # yes selected
        then
            MAIN_ENABLED[$count]="true"
        else                        # no selected
            MAIN_ENABLED[$count]="false"
        fi

        # Instrument type
        display_ll_cd24_instrument "$1" "Index ${count} choose instrument type" \
            "${MAIN_INST[$count]}" "accelerometer"
        newinst="`cat ${DIALOG_RESULTFILE}`"
        MAIN_INST[$count]="${newinst}"

        ((count++))
    done
}



# display_ll_cd24_mux_channels
# This displays and potentially changes the values in the 3 arrays for the mux channels setup
# above in get_ll_cd24_mux_channels().
# $1 is the title text to display
display_ll_cd24_mux_channels() {
    local count newcomp newinst result def_component def_instrument

    count=0
    while [ $count -lt ${NUM_MUX_CHANNELS} ]
    do
        case $count in
        0)  def_component="Z"
            def_instrument="mass-position-seismometer"
            ;;
        1)  def_component="N"
            def_instrument="mass-position-seismometer"
            ;;
        2)  def_component="E"
            def_instrument="mass-position-seismometer"
            ;;
        3)  def_component="0"
            def_instrument="calibration-input"
            ;;
        4)  def_component="0"
            def_instrument="electronic-test-point"
            ;;
        5)  def_component="1"
            def_instrument="electronic-test-point"
            ;;
        6)  def_component="2"
            def_instrument="electronic-test-point"
            ;;
        7)  def_component="3"
            def_instrument="electronic-test-point"
            ;;
        esac

        # component value
        display_ll_cd24_component "$1" "Index ${count} component setting" \
            "${MUX_COMP[$count]}" "${def_component}"
        newcomp="`cat ${DIALOG_RESULTFILE}`"
        MUX_COMP[$count]="${newcomp}"

        # enabled ? default value for all mux channels is false
        if [ -z "${MUX_ENABLED[$count]}" ]
        then
            display_yesno "$1" "Index ${count} Is this entry enabled ? " 0 0 --defaultno
        else
            if [ "${MUX_ENABLED[$count]}" = "true" ]
            then
                display_yesno "$1" "Index ${count} Is this entry enabled ? " 0 0
            else
                display_yesno "$1" "Index ${count} Is this entry enabled ? " 0 0 --defaultno
            fi
        fi

        result=$?
        if [ ${result} -eq 0 ]    # yes selected
        then
            MUX_ENABLED[$count]="true"
        else                        # no selected
            MUX_ENABLED[$count]="false"
        fi

        # Instrument type
        display_ll_cd24_instrument "$1" "Index ${count} choose instrument type" \
            "${MUX_INST[$count]}" "${def_instrument}"
        newinst="`cat ${DIALOG_RESULTFILE}`"
        MUX_INST[$count]="${newinst}"

        ((count++))
    done
}



# This displays and configures the hostname and port number to listen on
# $1 is the titletext to display
display_ll_cd24_host_and_port() {
    local titletext="$1"

    dialog --title "${titletext}" --form \
        "Enter hostname and port number to listen on" \
        0 0 0 \
        "Hostname (blank for all)" 1 0 "${LLCD_TCP_SERVER_HOSTNAME}" 2 4 54 100 \
        "Port number (blank to disable)" 3 0 "${LLCD_TCP_SERVER_SERVICE}" 4 4 54 100 \
        2> "${DIALOG_RESULTFILE}"
    if [ $? -ne 0 ]
    then
        clear
        echo Cancelled
        exit 1
    fi

    {
        read -r NEW_LLCD_TCP_SERVER_HOSTNAME
        read -r NEW_LLCD_TCP_SERVER_SERVICE
    } < "${DIALOG_RESULTFILE}"
}



# This displays and configures the Main settings for lowlatency cd24 input
# $1 is the titletext to display
ll_cd24_section_main() {
    local titletext="$1"

    # priority (default unset -> false)
    display_ll_cd24_priority "${titletext}" "${LLCD_PRIORITY}" "${DEF_LLCD_PRIORITY}"
    RESULT=$?
    if [ ${RESULT} -eq 0 ]    # yes selected
    then
        NEW_LLCD_PRIORITY="true"
    elif [ ${RESULT} -eq 1 ]    # no selected
    then
        NEW_LLCD_PRIORITY="false"
    fi

    display_ll_cd24_host_and_port "${titletext}"

    # link_delay (default appears to be unset "")
    display_ll_cd24_link_delay "${titletext}" "${LLCD_LINK_DELAY}"
    NEW_LLCD_LINK_DELAY="`cat ${DIALOG_RESULTFILE}`"

    # gdi_socket (default /var/run/gdi-base.default.source)
    display_gdi_socket  "${titletext}" $LLCD_GDI_SOCKET
    newgdiinst="`cat ${DIALOG_RESULTFILE}`"

    # This returns a value in GDI_SOCKET_PATH
    gdi_get_socket_path $newgdiinst
    NEW_LLCD_GDI_SOCKET="${GDI_SOCKET_PATH}"
}



# This displays and configures the Station settings for lowlatency cd24 input
# $1 is the titletext to display
ll_cd24_section_station() {
    local titletext="$1"

    # station_name (default hostname shortened to 5 chars and capitalised)
    display_ll_cd24_station_name "${titletext}" "${LLCD_STATION_NAME}" "${DEF_LLCD_STATION_NAME}"
    NEW_LLCD_STATION_NAME="`cat ${DIALOG_RESULTFILE}`"

    # network_name (default "")
    display_ll_cd24_network_name "${titletext}" "${LLCD_NETWORK_NAME}"
    NEW_LLCD_NETWORK_NAME="`cat ${DIALOG_RESULTFILE}`"

    # location_name (default last char of port name)
    display_ll_cd24_location_name "${titletext}" "${LLCD_LOCATION_NAME}" "${DEF_LLCD_LOCATION_NAME}"
    NEW_LLCD_LOCATION_NAME="`cat ${DIALOG_RESULTFILE}`"
}



# This displays and configures the Main channel settings for lowlatency cd24 input
# $1 is the titletext to display
ll_cd24_section_main_channel_settings() {
    local titletext="$1"

    # samples_per_second (default 200)
    display_ll_cd24_samples_per_second "${titletext}" \
        "${LLCD_SAMPLES_PER_SECOND}" "${DEF_LLCD_SAMPLES_PER_SECOND}"
    NEW_LLCD_SAMPLES_PER_SECOND="`cat ${DIALOG_RESULTFILE}`"

    # high_pass (default 0 -> disabled)
    display_ll_cd24_high_pass "${titletext}" "${LLCD_HIGH_PASS}"
    NEW_LLCD_HIGH_PASS="`cat ${DIALOG_RESULTFILE}`"

    # main channels numbered 0 1 2 3 - this function displays all four channel settings
    display_ll_cd24_main_channels "${titletext}"
}



# This displays and configures the Mulitplexed channel settings for lowlatency cd24 input
# $1 is the titletext to display
ll_cd24_section_mux_channel_settings() {
    local titletext="$1"

    # mux channels numbered 0 1 2 3 4 5 6 7 - this function details all
    display_ll_cd24_mux_channels "${titletext}"
}



# Go through the list of things that the user can change in the low latency CD24 config
# file.
#   $1 - portname
# If something is Cancelled or there is an error then this can exit.
serial_ll_cd24_parameters() {
    local port="$1"
    local new_main_channels=""
    local titletext

    LLCD_CFG_FILE="${SERIAL_CFDIR}/lowlatency-cd24-in/${port}"

    # Initialise the arrays for the main channels
    MAIN_ENABLED=()
    MAIN_COMP=()
    MAIN_INST=()
    # Initialise the arrays for the mux channels
    MUX_ENABLED=()
    MUX_COMP=()
    MUX_INST=()

    # Set default values
    DEF_LLCD_PRIORITY=""
    DEF_LLCD_STATION_NAME="$(hostname | cut -b1-5 | tr a-z A-Z)"
    DEF_LLCD_LOCATION_NAME="${port:${#port}-1:1}"
    DEF_LLCD_SAMPLES_PER_SECOND=200

    # Get current values or set defaults if file doesn't already exist
    if [ -r "${LLCD_CFG_FILE}" ]
    then
        # get the current values for each item
        LLCD_PRIORITY="`cf2get ${LLCD_CFG_FILE} [] priority`"
        if [ ! -z "${LLCD_PRIORITY}" ]
        then
            cf2true ${LLCD_CFG_FILE} [] priority
            if [ $? -eq 0 ]
            then
                LLCD_PRIORITY="true"
            else
                LLCD_PRIORITY="false"
            fi
        fi

        # Get the information about the main channels and arrange it in arrays for use later
        get_ll_cd24_main_channels ${LLCD_CFG_FILE}

        # Get the information about the mux channels and arrange it in arrays for use later
        get_ll_cd24_mux_channels ${LLCD_CFG_FILE}

        LLCD_TCP_SERVER_HOSTNAME="`cf2get ${LLCD_CFG_FILE} [] tcp_server_hostname`"
        LLCD_TCP_SERVER_SERVICE="`cf2get ${LLCD_CFG_FILE} [] tcp_server_service`"
        LLCD_GDI_SOCKET="`cf2get ${LLCD_CFG_FILE} [] gdi_socket`"
        LLCD_SERIAL_BAUD="`cf2get ${LLCD_CFG_FILE} [] serial_baud`"
        LLCD_STATION_NAME="`cf2get ${LLCD_CFG_FILE} [] station_name`"
        LLCD_NETWORK_NAME="`cf2get ${LLCD_CFG_FILE} [] network_name`"
        LLCD_LOCATION_NAME="`cf2get ${LLCD_CFG_FILE} [] location_name`"
        LLCD_SAMPLES_PER_SECOND="`cf2get ${LLCD_CFG_FILE} [] samples_per_second`"
        LLCD_SAMPLE_PACKETISER="`cf2get ${LLCD_CFG_FILE} [] sample_packetiser`"
        LLCD_HIGH_PASS="`cf2get ${LLCD_CFG_FILE} [] high_pass`"
        LLCD_LINK_DELAY="`cf2get ${LLCD_CFG_FILE} [] link_delay`"
    else
        # set empty values for each item
        LLCD_PRIORITY=""
        LLCD_TCP_SERVER_HOSTNAME=""
        LLCD_TCP_SERVER_SERVICE=""
        LLCD_LINK_DELAY=""
        LLCD_GDI_SOCKET=""
        LLCD_STATION_NAME=""
        LLCD_NETWORK_NAME=""
        LLCD_LOCATION_NAME=""
        LLCD_SAMPLES_PER_SECOND=""
        LLCD_HIGH_PASS=""

        LLCD_SAMPLE_PACKETISER=""
        LLCD_SERIAL_BAUD=""
        LLCD_CFG_MAIN_IS_TRIAXIAL="" # TODO what is this ????
    fi

    # Now go through the values giving user a choice
    titletext="${port} low latency CD24 config"

    ll_cd24_section_main "${titletext} - Main settings"

    ll_cd24_section_station "${titletext} - Station settings"

    ll_cd24_section_main_channel_settings "${titletext} - Main ADC channels"

    ll_cd24_section_mux_channel_settings "${titletext} - Multiplexed ADC channels"

    cconf_create_config_file "${LLCD_CFG_FILE}"

    # Now we need to make the updates that have been done here before returning
    cf2set ${LLCD_CFG_FILE} [] priority="${NEW_LLCD_PRIORITY}"
    cf2set ${LLCD_CFG_FILE} [] tcp_server_hostname="${NEW_LLCD_TCP_SERVER_HOSTNAME}"
    cf2set ${LLCD_CFG_FILE} [] tcp_server_service="${NEW_LLCD_TCP_SERVER_SERVICE}"
    cf2set ${LLCD_CFG_FILE} [] link_delay="${NEW_LLCD_LINK_DELAY}"
    cf2set ${LLCD_CFG_FILE} [] gdi_socket="${NEW_LLCD_GDI_SOCKET}"
    cf2set ${LLCD_CFG_FILE} [] station_name="${NEW_LLCD_STATION_NAME}"
    cf2set ${LLCD_CFG_FILE} [] network_name="${NEW_LLCD_NETWORK_NAME}"
    cf2set ${LLCD_CFG_FILE} [] location_name="${NEW_LLCD_LOCATION_NAME}"
    cf2set ${LLCD_CFG_FILE} [] samples_per_second="${NEW_LLCD_SAMPLES_PER_SECOND}"

    # We also need to reset the sample_packetiser value as SPS/10
    sample_packetiser=$[${NEW_LLCD_SAMPLES_PER_SECOND}/10]
    cf2set ${LLCD_CFG_FILE} [] sample_packetiser="${sample_packetiser}"
    cf2set ${LLCD_CFG_FILE} [] high_pass="${NEW_LLCD_HIGH_PASS}"

    # First the main channels
    put_ll_cd24_main_channels ${LLCD_CFG_FILE}

    # Then the mux channels
    put_ll_cd24_mux_channels ${LLCD_CFG_FILE}

    # This is to tell serialmux that the lowlatency channels have been configured and it
    # doesn't need to set the default values.
    cf2set ${LLCD_CFG_FILE} [] _cfg_channels_done="true"

    # Now add the fixed value items if needed
    serial_ll_cd24_add_fixed_values ${LLCD_CFG_FILE} "${portname}" "${devicename}"

    # Now we've finished making changes reset the permission of the config file
    cconf_set_perms_and_group ${LLCD_CFG_FILE} 664 "conf"
}



# vim: ts=4:sw=4:expandtab:syntax=sh
