#include "Cyton_Process.h"
#include "Cyton_SysApi.h"
#include "usart.h"	
#include <string.h>
#include "delay.h"       
#include "led.h"       
#include "key.h"
#include "Timer.h"
#include "ADS129x.h"
#include "Cyton_DataPkg.h"
#include "ESP8266.h"

#include "myQueue.h"

#define CYTON_COLLECTOR_DATA_CACHE_LEN      (123)

static int g_iTimerindex = 0;
static int g_iTotalLen = 0;

typedef struct stCyton_DataCacheInfo {
    uint8_t DataCache[CYTON_COLLECTOR_DATA_CACHE_LEN + 1];
    uint32_t iSendIndex;
    uint32_t iWriteIndex;
    uint32_t iWriteMax;
} CYTON_DATACACHE_INFO_T;

static CYTON_DATACACHE_INFO_T g_stCyton_DataCache;

static void cyton_dataCacheClear()
{
    memset(&g_stCyton_DataCache, 0, sizeof(CYTON_DATACACHE_INFO_T));
}

static void cyton_SetdataCacheMaxByOnePkg(uint8_t aucLen)
{
    g_stCyton_DataCache.iWriteMax = CYTON_COLLECTOR_DATA_CACHE_LEN / aucLen * aucLen;
}

static uint8_t * cyton_getUnsendData(int *iLen)
{
    int iOneBufLen = 0;

    iOneBufLen = Cyton_GetDataPkg_Len();
    if (g_stCyton_DataCache.iWriteIndex != g_stCyton_DataCache.iSendIndex) {
        if (g_stCyton_DataCache.iWriteIndex > g_stCyton_DataCache.iSendIndex) {
            *iLen =  g_stCyton_DataCache.iWriteIndex - g_stCyton_DataCache.iSendIndex;
        } else {
            *iLen = g_stCyton_DataCache.iWriteMax - g_stCyton_DataCache.iSendIndex;
        }

        if (*iLen > 2048) {
            *iLen = 2048 / iOneBufLen * iOneBufLen;
        }

        return &g_stCyton_DataCache.DataCache[g_stCyton_DataCache.iSendIndex];
    }

    return NULL;
}

static void cyton_setSendDataDone(int iLen)
{
    g_stCyton_DataCache.iSendIndex += iLen;
    if (g_stCyton_DataCache.iSendIndex >= g_stCyton_DataCache.iWriteMax) {
        g_stCyton_DataCache.iSendIndex = 0;
    }

    //ESP8266_DEBUG("g_stCyton_DataCache.iSendIndex %d\n", g_stCyton_DataCache.iSendIndex);
}

void CytonProcess_TimerCollCB(int iTIndex)
{
    int iRet = 0;
    uint32_t puiChannel[8];
    g_iTimerindex = iTIndex;

    //ESP8266_DEBUG("CytonProcess_TimerCollCB %d\n", iTIndex);
    iRet = Cyton_DataFormat2Package(&g_stCyton_DataCache.DataCache[g_stCyton_DataCache.iWriteIndex], puiChannel, CYTON_DATA_PKG_CHANNEL8);
    g_stCyton_DataCache.iWriteIndex += iRet;
    if (g_stCyton_DataCache.iWriteIndex >= g_stCyton_DataCache.iWriteMax) {
        g_stCyton_DataCache.iWriteIndex = 0;
    }

    //ESP8266_DEBUG("g_stCyton_DataCache.iWriteIndex %d\n", g_stCyton_DataCache.iWriteIndex);
}

void CytonProcess_TimerCollStart(int iHz)
{
    int iOneBufLen = 0;

    cyton_dataCacheClear();
    iOneBufLen = Cyton_GetDataPkg_Len();
    cyton_SetdataCacheMaxByOnePkg(iOneBufLen);
    CytonSys_CollectorTimerStart(iHz, CytonProcess_TimerCollCB);
}

void CytonProcess_TimerCollStop()
{
    CytonSys_Stop();
}

void CytonProcess_Loop()
{
    int iRet = 0;
    uint32_t puiChannel[8];
    int iFd = -1;
    int iStreamStat = 0;
    uint8_t *pszSendBuf = NULL;
    int iSendBufLen = 0;

    iFd = CytonEsp12_DataGetReportFd();
    iStreamStat = CytonEsp12_StreamStat();

    if (iStreamStat) {
        pszSendBuf = cyton_getUnsendData(&iSendBufLen);
        if (NULL != pszSendBuf) {
            g_iTotalLen += iSendBufLen;
            ESP8266_SendData(pszSendBuf, iSendBufLen);
            // ESP8266_SendData(iFd, pszSendBuf, iSendBufLen, 0);
            ESP8266_DEBUG("Start Report Data iSendBufLen %d\n", iSendBufLen);
            cyton_setSendDataDone(iSendBufLen);
        }

        if (g_iTimerindex % 1000 == 0) {
            ESP8266_DEBUG("Start Report total %d\n", g_iTotalLen);
        }
    }
}