/*******************************************************************
 *
 *  File: main.cpp
 *
 *  Description: Example of using Innomatix Coprocessor Support functionality
 *
 *  Copyright 2015 Innomatix, LLC., All Rights Reserved
 *
 *  THIS DOCUMENT AND ITS CONTENTS ARE INTELLECTUAL PROPERTY
 *  OF INNOMATIX, LLC.  ANY DUPLICATION IN PART OR WHOLE
 *  WITHOUT PRIOR WRITTEN CONSENT IS STRICTLY PROHIBITED.
 *
 *******************************************************************/
#include "mbed.h"
#include "Timer.h"
#include "RemoteDataStoreAPI.h"

// Name of the data bins we'll use
char PCopVersBinName[] = "CoprocVersion";
char PCopStatusBinName[] = "CoprocStatus";
char VehiclePowerBinName[] = "VehiclePower";
char PowerStatusBinName[] = "PowerStatus";

// Data bin identifiers returned from GetDataBinInfo()
unsigned int  VersBin = BinId_None;
unsigned int  StatusBin = BinId_None;
unsigned int  PowerValueBin = BinId_None;
unsigned int  PowerStatusBin = BinId_None;


/*************************************************************************/
unsigned int GetDBinInfo( const char * name )
{
    unsigned int id = BinId_None;
    RdsResults_e result = rdsNoConnection;
    BinInfoStruct_t info;

    printf( "RemoteDataStore getting info for databin %s...", name );
    fflush( NULL );


    result = GetDataBinInfo( name, &info );
    if( rdsSuccess == result )
    {
        // We only care about the databin ID for this example
        // Check RemoteDataStoreAPI.h for info on other fields
        id = info.BinId;
        printf( "SUCCESS, ID is %d\r\n", id );
    }else
    {
        printf( "FAILED (%d)\r\n", result );
    }
    return( id );
}

/*************************************************************************/
RdsResults_e ExampleInit()
{
    RdsResults_e result = rdsNoConnection;

    result = DataStoreInit( "usb", 0 );
    printf( "Innomatix RemoteDataStore API initialization: %s\r\n", (rdsSuccess == result ? "INITIALIZED" : "FAILED") );

    if( rdsSuccess == result )
    {
        VersBin = GetDBinInfo( PCopVersBinName );
        StatusBin = GetDBinInfo( PCopStatusBinName );

        PowerValueBin = GetDBinInfo( VehiclePowerBinName );
        PowerStatusBin = GetDBinInfo( PowerStatusBinName );
    }
    return( result );
}

/*************************************************************************/
/*************************************************************************/
int DoExample( char *zVersion )
{
    RdsResults_e result = rdsNoConnection;
    int delay_msec = 10 * 1000;

    DigitalOut led1( LED1 );

    double PowerValue = 0.0;
    double PowerThreshold = 13.0;
    unsigned int Timestamp = 0;
    unsigned int PrevTimestamp = 0;

    // Init the Support Library subsystems we'll use for this example
    result = ExampleInit();
    if( rdsSuccess == result )
    {
        /*-----------------------------------------------*/
        // Update the DAP informational data bins
        PutString( StatusBin, "Starting PCop Example" );
        PutString( VersBin, zVersion );

        /*-----------------------------------------------*/
        // Use the Remote DataStore's special "debug" API
        // The DAP will update a pre-determined data bin with the string.
        // Typically the debug data bin is shown on the diagnostic display
        // and is included in the data stream to the host.
        PutDebug( "Entering example loop" );

        while( 1 )
        {
            // Get a value from the VehiclePower data bin
            result = GetDouble( PowerValueBin, &PowerValue, &Timestamp);

            // Check the timestamp to see if the value has been updated since
            // last time we checked.  Only test/publish if it has.
            if( Timestamp != PrevTimestamp )
            {
                // Apply a threshold
                int status = (PowerValue >= PowerThreshold ? 1 : 0);

                // Publish the results back to the PowerOkay data bin
                PutUnsignedInteger( PowerStatusBin, status );
                led1 = status;

                // Save the timestamp so we know if it is updated
                PrevTimestamp = Timestamp;
            }

            // Wait for the next go-around
            wait_ms( delay_msec );
        }



        /*-----------------------------------------------*/
        DataStoreClose();
    }
    return( 0 );
}

