/****************************************************************************/
/* Copyright 2009 MBARI.                                                    */
/* MBARI Proprietary Information. All rights reserved.                      */
/****************************************************************************/
#include "config.h"
#include "flash_mem.h"
#include "sys_defs.h"

typedef struct
{
    ConfigData config;
    unsigned int checksum;
} ConfigBlock;

unsigned int calcCheckSum(char* buff, int size);

/****************************************************************************/
/*                             Config functions                             */
/****************************************************************************/
int cfgCheck(ConfigData* config)
{
    if ( config->bootFlag != DEFAULT_BOOT_FLAG )
        return -2;

    if ( (config->trigHoldoff < HOLDOFF_LEVEL_MIN) || 
         (config->trigHoldoff > HOLDOFF_LEVEL_MAX) )
         return -3;

    if ( (config->trigDebounce < DEBOUNCE_LEVEL_MIN) || 
         (config->trigDebounce > DEBOUNCE_LEVEL_MAX) )
         return -4;

    if ( (config->stopDelay < STOP_DELAY_MIN) || 
         (config->stopDelay > STOP_DELAY_MAX) )
         return -5;

    if ( (config->startDelay < START_DELAY_MIN) || 
         (config->startDelay > START_DELAY_MAX) )
         return -6;

    if ( (config->triggerWindow < TRIG_WINDOW_MIN) || 
         (config->triggerWindow > TRIG_WINDOW_MAX) )
         return -7;

    if ( (config->timeLapseOn < TIME_LAPSE_ON_MIN) || 
         (config->timeLapseOn > TIME_LAPSE_ON_MAX) )
         return -8;

    if ( (config->timeLapseOff < TIME_LAPSE_OFF_MIN) || 
         (config->timeLapseOff > TIME_LAPSE_OFF_MAX) )
         return -9;

    return 0;
}

int cfgRead(ConfigData* config)
{
    ConfigBlock cb;
    unsigned int cs_calc;

    /* read the configuation struct from memory */
    memRead((char*)&cb, sizeof(cb));

    cs_calc = calcCheckSum((char*)&cb.config, sizeof(ConfigData));

    if ( cs_calc != cb.checksum )
        return -1;
    
    /* assign stored data to the config data struct */
    config->bootFlag = cb.config.bootFlag;

    config->triggerMode = cb.config.triggerMode;
    config->timeLapseMode = cb.config.timeLapseMode;

    config->trigHoldoff = cb.config.trigHoldoff;
    config->trigDebounce = cb.config.trigDebounce;
    
    config->stopDelay = cb.config.stopDelay;
    config->startDelay = cb.config.startDelay;
    
    config->triggerWindow = cb.config.triggerWindow;

    config->timeLapseOn = cb.config.timeLapseOn;
    config->timeLapseOff = cb.config.timeLapseOff;

    return cfgCheck(config);
}

int cfgWrite(ConfigData* config)
{
    ConfigBlock cb;
    
    /* if config params are not in a valid range, don't write it */
    if ( cfgCheck(config) != 0 )
        return -1;

    /* assign stored data to the config data struct */
    cb.config.bootFlag = config->bootFlag;
    
    cb.config.triggerMode = config->triggerMode;
    cb.config.timeLapseMode = config->timeLapseMode;
    
    cb.config.trigHoldoff = config->trigHoldoff;
    cb.config.trigDebounce = config->trigDebounce;
    
    cb.config.stopDelay = config->stopDelay;
    cb.config.startDelay = config->startDelay;

    cb.config.triggerWindow = config->triggerWindow;

    cb.config.timeLapseOn = config->timeLapseOn;
    cb.config.timeLapseOff = config->timeLapseOff;


    /* calc and assign the checksum */
    cb.checksum = calcCheckSum((char*)&cb.config, sizeof(ConfigData));

    /* erase the old config */
    memErase();

    /* write the new config */
    memWrite((char*)&cb, sizeof(cb));
    
    return 0;
}

int cfgSetBootFlag()
{
    ConfigBlock cb;
    
    /* set the boot flag */
    cb.config.bootFlag = ACTIVE_BOOT_FLAG;
    
    cb.config.triggerMode = 0;
    cb.config.timeLapseMode = 0;
    
    cb.config.trigHoldoff = 0;
    cb.config.trigDebounce = 0;
    
    cb.config.stopDelay = 0;
    cb.config.startDelay = 0;
    
    cb.config.triggerWindow = 0;
    
    cb.config.timeLapseOn = 0;
    cb.config.timeLapseOff = 0;

    /* calc and assign the checksum */
    cb.checksum = calcCheckSum((char*)&cb.config, sizeof(ConfigData));

    /* erase the old config */
    memErase();

    /* write the new config */
    memWrite((char*)&cb, sizeof(cb));
    
    return 0;
}


unsigned int calcCheckSum(char* buff, int size)
{
    int i;
    unsigned int cs = 0;

    for (i = 0; i < size; i++)
        cs += buff[i];

    return cs;
}

