/*
 * mms_test.c
 *
 *  Created on: May 14, 2024
 *      Author: tm
 */

#include <stdint.h>
#include <stdbool.h>
#include <time.h>

#include "system.h"
#include "main.h"       //externs for global vars / globs

#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 "apf_math.h"
#include "apf_numbr.h"
#include "mms_spec.h"
#include "i2c_pcal64xx.h"
#include "i2c_bme280.h"
#include "i2c_ina260.h"

extern struct tm DS3234_tm;    // DS3234 time of day as struct tm
extern struct tm *tp;          // scratchpad struct tm

extern struct apfRtcTime rtc;

extern int    Zcoefs, Ecoefs, Zeros;

extern char   CalDate[25];
//extern double SwCalTemp;
extern double ZeissCoefs[ZCOEFS];
extern double TcompCoefs[TCOEFS];
extern double FitData[FITVALUES];
extern double ZeroData[260];
//extern double LambdaData[260];
extern double AbsData[260];
extern double AbsFitData[260];
extern double ResidualsData[260];
extern double **EcoefData, **EcoefFile;

// FLOATs Stored in DS3234 NVRAM
float  no3_span, no3_offset;

unsigned short *SpecData, *DarkData, *RefData;

//void IsusAcquireData(FILE * fptr)
void mms_IsusAcquireData(FILE * fptr)
{
#ifdef NOTPORTEDYET
    uchar UART_char;
    ulong loop_ctr;
    float volts, amps;
    float temp, humi, dew_point;


    if (SpecPwrOn(&SpecPort) != TRUE) {
        printf("ERROR, Spectrometer not responding - exiting!\n");
        return;
    }

    if (LampPwrOn() != TRUE) {
        SpecPwrOff(SpecPort);
        printf("ERROR, Fiberlite won't turn on - exiting!\n");
        return;
    }

    printf("\n\n");
    OutputIsusHeader(fptr);

    INA219_ReadVoltageCurrent(&volts, &amps);
    printf("\n  System Batt Voltage = %.3f\n", volts);
    printf("  System Load Current = %.4e\n", amps);

    HIH6130_ReadTempHumidity(&temp, &humi);
    dew_point = calc_dewpoint(humi, temp);
    printf("\n  Housing Temperature = %+06.2fC = %+06.2fF\n", temp,
           CtoF(temp));
    printf("  Housing    Humidity = %5.1f%%  = %5.1fC (DP)\n", humi,
           dew_point);

    printf("\nEntering Acquisition Loop, press S to break.\n");

    SCIRxFlush();
    UART_char = 0;
    loop_ctr = isus_scans_per_dc;

    while (UART_char != (uchar) CAPS_S) {

        if (loop_ctr == isus_scans_per_dc) {
            LampCloseShutter();
            if (ScanSpectra(SpecPort, fptr, 1, DarkData, DARKCURRENT_SCAN)
                != TRUE)
                break;
            LampOpenShutter();
            loop_ctr = 0;
        } else {
            if (ScanSpectra(SpecPort, fptr, 1, SpecData, INTENSITY_SCAN) !=
                TRUE)
                break;
        }
        ++loop_ctr;

        if (SCIRxQueuedCount() != 0) {
            UART_char = toupper((char) SCIRxGetByte(false));
            SCIRxFlush();
        }

    }                           //end while

    LampPwrOff();
    SpecPwrOff(SpecPort);

    if (UART_char == (uchar) CAPS_S)
        printf("Break: Char S Received!\n");
#endif
}

void isusTest_menu_B(void)
{
    uprintf("ran out of code space, comment out isusTest_menu_B mms_test.c"); prn_nl();
#ifdef NOCODE
    int scanret;

    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 ( mms_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();
        }
    }
#endif
}

void isusTest_menu_E(void)
{
    uprintf("ran out of code space, comment out isusTest_menu_E"); prn_nl();

#ifdef NOCODE
    char cmd;
    unsigned short qret = TRUE;
    int j, scanret;
    unsigned short *dataptr;
    unsigned long input_var;

    // CF2 has the user turning on the spec with menu_A, we'll just turn on the spec using mms_open.   TBD on delay between power on and action
    mms_rts(1);   //is this rts = inactive

    mms_uart_init(115200);

    mms_open();     // power on

    delay_msec(10);

// start of CF2 code
    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);
		scanret = mms_scanSpectra((unsigned short) input_var, dataptr, INTENSITY_SCAN, 1, 0);		//print but dont write
        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);
    }
#endif
}


// IsusLampTest() is first ISUS function for Thom dev.
void mms_IsusLampTest(void)
{
    int i;
    unsigned short LampOffDC[256];
    unsigned short LampOnDC[256];
    double mean1;
    float volts, amps;
    float temp, humi, dew_point;
    struct tm *t;
    FIL lamptest = { };

    uprintf("ina219 not, hih6130 not, mms_IsusLampTest in mms_test.c");

    volts = 0.0;
    amps = 0.0;
    temp = 37.2;
    humi = 20.0;

    //INA219_ReadVoltageCurrent(&volts, &amps);


    ina260_system_voltageCurrent(&volts, &amps);

    uprintf("\n  System Batt Voltage = %.3f\n", volts);
    uprintf("  System Load Current = %.4e\n", amps);

    //HIH6130_ReadTempHumidity(&temp, &humi);
    bme280_ReadTempHumidity(&temp, &humi);
    dew_point = bme280_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);
    mms_scanSpectra(1, DarkData, DARKCURRENT_SCAN, 1, 0);       //print, dont write
    mean1 = DataMean;
    // stdev1 = DataStdDev;

//    if (LampPwrOn() != TRUE) {
//        SpecPwrOff(SpecPort);
//        uprintf("ERROR, Fiberlite won't turn on - exiting!\n");
//        return;
//    }

    mms_lampPwrOnUsingSpec( SpecData, TRUE );

    uprintf("Taking Spectra Scan\n");
    //mms_scanSpectra(stdout, 1, SpecData, INTENSITY_SCAN);
	mms_scanSpectra(1, SpecData, INTENSITY_SCAN, 1, 0);		// print but don't write
    // mean2 = DataMean;
    // stdev2 = DataStdDev;

    LampCloseShutter();

    uprintf("Taking DarkCurrent Scans with DU Lamp ON\n");
    //mms_scanSpectra(stdout, 1, LampOnDC, DARKCURRENT_SCAN);
    mms_scanSpectra(1, LampOnDC, DARKCURRENT_SCAN, 1, 0);
    // mean3 = DataMean;
    // stdev3 = DataStdDev;

    mms_lampPwrOff();

    uprintf("Taking DarkCurrent Scan with DU Lamp OFF\n");
    //mms_scanSpectra(stdout, 1, LampOffDC, DARKCURRENT_SCAN);
    mms_scanSpectra(1, LampOffDC, DARKCURRENT_SCAN, 1, 0);

    mms_specPwrOff();

    if (Ecoefs == 256)
        CalcAbs(&ZeroData[0], &SpecData[0], &AbsData[0], mean1, 256);

    t = localtime(&rtc.data_time);
    fRes = f_open(&lamptest, "c:\\isus\\lamptest.dat", FA_CREATE_ALWAYS | FA_WRITE);
    if(fRes == NULL)
    {
        //APFTODO error handler
        uprintf("DBG: lamptest.dat f_open failure, aborting mms_IsusLampTest()"); prn_nl();
        return;
    }

    f_printf(&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);

    f_printf(&lamptest, "#WAVELENGTH,INTENSITY,DARK_CURRENT,ABSORBANCE\n");
    for (i = 0; i < 256; i++) {
        if (Ecoefs != 256)
            AbsData[i + 1] = -1.0;
        f_printf(&lamptest, "%.5f,%hu,%hu,%.5f\n", apfArray.LambdaData[i + 1],
                SpecData[i], DarkData[i], AbsData[i + 1]);
    }
    f_close(&lamptest);

    if (QueryYesNo("\n  Output C:\\ISUS\\LAMPTEST.DAT", FALSE)) {
        DisplayFile();
    }

}
