/*
 * mms_test.c
 *
 *  Created on: May 14, 2024
 *      Author: tm
 */

#include <stdint.h>
#include <stdbool.h>
#include <time.h>

#include "system.h"
#include "string.h"
#include "uartstdio.h"
#include "user_io.h"
#include "uart3.h"
#include "serial.h"
#include "sample.h"
#include "config.h"
#include "apf.h"
#include "test.h"

#include "apf.h"
#include "apf_util.h"
#include "mms_spec.h"
#include "i2c_pcal64xx.h"

extern struct tm DS3234_tm;    // DS3234 time of day as struct tm
extern struct tm *tp;          // scratchpad struct tm

extern struct apfGlobals apf;
extern struct apfRtcTime rtc;

extern char  logfname[64];
extern FILE  *dat_file;
extern FILE  *err_file;

int    Zcoefs, Ecoefs, Zeros;

char   CalDate[25];
double SwCalTemp;
double ZeissCoefs[ZCOEFS];
double TcompCoefs[TCOEFS];
double FitData[FITVALUES];
double ZeroData[260];
double LambdaData[260];
double AbsData[260];
double AbsFitData[260];
double ResidualsData[260];
double **EcoefData, **EcoefFile;
unsigned long  isus_lamp_elp;               // value comes from DS1683

// FLOATs Stored in DS3234 NVRAM
float  no3_span, no3_offset;

unsigned short *SpecData, *DarkData, *RefData;


void isusTest_menu_B(void)
{
    char cmd;
    unsigned short qret = TRUE;
    int i, j, scanret;
    unsigned short *dataptr;
    unsigned long input_var;


    if (apf.isus_lamp_pwr == TRUE) {
        if (mms_lampPwrOff() == TRUE)
            uprintf("\n  Lamp was powered OFF.\n");
        if (RefPwrOff() == TRUE)
            uprintf("\n  RefCh was powered OFF.\n");
        //break;
    } else {
        //if ( LampPwrOnUsingSpec( SpecPort, SpecData, TRUE ) == TRUE )
        if ( LampPwrOnUsingSpec( SpecData, TRUE ) == TRUE )
            uprintf("\n  Lamp was powered ON.\n");
        else {
            uprintf("\n  Could not power Lamp.\n");
            //add time to verify/fix problem!
            if (QueryYesNo("\n  Power Lamp OFF? ", TRUE)){
                mms_lampPwrOff();
                //break;
            }
        }
    }
    input_var = 0;
    QueryNum
        ("\n  Select Lamp:\n  [1] Dueterium\n  [2] Tungsten\n  [3] Both\n  Enter>",
         "%lu", "%lu", &input_var);
    if (input_var != 0) {
        if (input_var == 1) {
            uprintf("\n  Dueterium Enabled\n");
        } else if (input_var == 2) {
            /* DISABLE THE DEUTERIUM LAMP */
            pcal6416_write_port_bit(PCAL6416A_OUT_PORT0, LAMP_DU_ENABLE, LOW);
            delay_msec(100);
            uprintf("\n  Dueterium Disabled\n");

            /* ENABLE THE TUNGSTEN */
            pcal6416_write_port_bit(PCAL6416A_OUT_PORT0,
                                  LAMP_W_ENABLE, HIGH);
            delay_msec(100);
            uprintf("\n  Tungsten Enabled\n");
        } else if (input_var == 3) {
            /* ENABLE THE DEUTERIUM LAMP */
            pcal6416_write_port_bit(PCAL6416A_OUT_PORT0, LAMP_DU_ENABLE, HIGH);
            delay_msec(100);

            /* ENABLE THE TUNGSTEN */
            pcal6416_write_port_bit(PCAL6416A_OUT_PORT0, LAMP_W_ENABLE, HIGH);
            delay_msec(100);
            uprintf("\n  Both Dueterium & Tungsten Enabled\n");
        } else {
            RangeError(1L, 3L);
            mms_lampPwrOff();
        }
    }
}

void isusTest_menu_E(void)
{
    char cmd;
    unsigned short qret = TRUE;
    int i, j, scanret;
    unsigned short *dataptr;
    unsigned long input_var;


    input_var = 3;
    QueryNum("  Enter # of readings", "%lu", "%lu", &input_var);
    if ((input_var > 0) && (input_var <= 25))
    {
        uprintf("\n");
        if (apf.isus_spec_pwr != (uint8_t) TRUE)
        {
            uprintf ("\n  Spectrometer is not powered, exiting!\n");
            return;     //break;
        }
        // dynamically allocate array */
        dataptr =
            calloc((size_t) (256 * input_var),
                   sizeof(unsigned short));
        if (dataptr == NULL)
        {
            uprintf("CAN'T allocate memory\n");
            return;     //break;
        }
        // collect spectra
        scanret = mms_scanSpectra( FNULL, (unsigned short) input_var, dataptr, INTENSITY_SCAN);
        if (scanret != TRUE)
        {
            uprintf("Scan ERROR, ret = %d\n", scanret);
            free(dataptr);
            return; //break;
        }
        // print formatted (row-column) data, start at lower wavelengths and work up
        for (i = 0; i < 256; i++)
        {
            for (j = 0; j < input_var; j++)
            {
                if (j == 0)
                    uprintf("%.5lf,", LambdaData[i + 1]);
                if (j == (input_var - 1))
                    uprintf("%hu\n", dataptr[i + (256 * j)]);
                else
                    uprintf("%hu,", dataptr[i + (256 * j)]);
                fflush(stdout);
            }
        }
        // deallocate array
        free(dataptr);
    }
}


void IsusLampTest(void)
{
    int i;
    unsigned short LampOffDC[256];
    unsigned short LampOnDC[256];
    double mean1, mean2, mean3;
    double stdev1, stdev2, stdev3;
    float volts, amps;
    float temp, humi, dew_point;
    struct tm *t;
    FILE *lamptest;

    uprintf("ina219 not, hih6130 not, IsusLampTest in mms_test.c");

    volts = 0.0;
    amps = 0.0;
    temp = 37.2;
    humi = 20.0;

    //INA219_ReadVoltageCurrent(&volts, &amps);
    uprintf("\n  System Batt Voltage = %.3f\n", volts);
    uprintf("  System Load Current = %.4e\n", amps);

    //HIH6130_ReadTempHumidity(&temp, &humi);
    //dew_point = calc_dewpoint(humi, temp);
    uprintf("\n  Housing Temperature = %+06.2fC = %+06.2fF\n", temp,
           CtoF(temp));
    uprintf("  Housing    Humidity = %5.1f%%  = %5.1fC (DP)\n", humi,
           dew_point);

    if (apf.isus_lamp_pwr == TRUE)
    {
        mms_lampPwrOff();
        uprintf("\nLamp was turned off for inital DarkCurrent.\n");
        delay_sec(1);           //wait a sec...
    }

    if (apf.isus_spec_pwr == FALSE)
    {
        if (mms_specPwrOn() == TRUE)
            uprintf("\n  Spec needed to be powered ON.\n");
        else
        {
            uprintf("\n  Spec couldn't be powered ON - exiting!\n");
            mms_specPwrOff();
            return;
        }
    }

    delay_msec(500);

    uprintf("Taking DarkCurrent Scan with DU Lamp OFF\n");
    mms_scanSpectra(stdout, 1, DarkData, DARKCURRENT_SCAN);
    mean1 = DataMean;
    stdev1 = DataStdDev;

//    if (LampPwrOn() != TRUE) {
//        SpecPwrOff(SpecPort);
//        uprintf("ERROR, Fiberlite won't turn on - exiting!\n");
//        return;
//    }

    LampPwrOnUsingSpec( SpecData, TRUE );

    uprintf("Taking Spectra Scan\n");
    mms_scanSpectra(stdout, 1, SpecData, INTENSITY_SCAN);
    mean2 = DataMean;
    stdev2 = DataStdDev;

    LampCloseShutter();

    uprintf("Taking DarkCurrent Scans with DU Lamp ON\n");
    mms_scanSpectra(stdout, 1, LampOnDC, DARKCURRENT_SCAN);
    mean3 = DataMean;
    stdev3 = DataStdDev;

    mms_lampPwrOff();

    uprintf("Taking DarkCurrent Scan with DU Lamp OFF\n");
    mms_scanSpectra(stdout, 1, LampOffDC, DARKCURRENT_SCAN);

    mms_specPwrOff();

    if (Ecoefs == 256)
        CalcAbs(&ZeroData[0], &SpecData[0], &AbsData[0], mean1, 256);

    t = localtime(&rtc.data_time);
    lamptest = fopen("c:\\isus\\lamptest.dat", "w");

    fprintf(lamptest, "#%02d/%02d/%02d %02d:%02d:%02d\n", t->tm_mon + 1,
            t->tm_mday, t->tm_year + 1900, t->tm_hour, t->tm_min,
            t->tm_sec);

    fprintf(lamptest, "#WAVELENGTH,INTENSITY,DARK_CURRENT,ABSORBANCE\n");
    for (i = 0; i < 256; i++) {
        if (Ecoefs != 256)
            AbsData[i + 1] = -1.0;
        fprintf(lamptest, "%.5f,%hu,%hu,%.5f\n", LambdaData[i + 1],
                SpecData[i], DarkData[i], AbsData[i + 1]);
    }
    fclose(lamptest);

    if (QueryYesNo("\n  Output C:\\ISUS\\LAMPTEST.DAT", FALSE)) {
        DisplayFile();
    }

}
