/*******************************************************************************
* the includes
******************************************************************************/
#include "SeatMassage.h"
#include "LIN_Master.h"
#include "scm_canmatrix-binutil.h"
/*******************************************************************************
* the defines
******************************************************************************/



/*******************************************************************************
* the typedefs
******************************************************************************/
typedef struct 
{
    //坐垫
    uint8_t ZD_R_MINUS:1;
    uint8_t ZD_L0:1;
    uint8_t ZD_L1:1;
    uint8_t ZD_L2:1;
    uint8_t ZD_R2:1;
    uint8_t ZD_R_PLUS:1;
    uint8_t ZD_L_PLUS:1;
    uint8_t ZD_L_MINUS:1;

    uint8_t ZD_R0:1;
    uint8_t ZD_R1:1;
    uint8_t ZD_REV1:1;
    uint8_t ZD_REV2:1;
    uint8_t ZD_REV3:1;
    uint8_t ZD_REV4:1;

    uint8_t ZD_AP:1;
    uint8_t ZD_V2_12V:1;

    //靠背
    uint8_t KB_D_PLUS:1;
    uint8_t KB_U_PLUS:1;
    uint8_t KB_D_MINUS:1;
    uint8_t KB_U_MINUS:1;
    uint8_t KB_L1:1;
    uint8_t KB_L2:1;
    uint8_t KB_L3:1;
    uint8_t KB_L4:1;

    uint8_t KB_R2:1;
    uint8_t KB_R3:1;
    uint8_t KB_R4:1;
    uint8_t KB_L0:1;
    uint8_t KB_R0:1;
    uint8_t KB_R1:1;

    uint8_t KB_REV1:1;
    uint8_t KB_V2_12V:1;
}SM_CTRL_Type;

typedef union 
{
    uint8_t rawdata[4];
    SM_CTRL_Type msg;
}SM_CTRL_Data_Type;

typedef enum
{
    SM_INIT,
    SM_OFF,
    SM_RUN1,
    SM_RUN2,
    SM_RUN3,
    SM_STATE_NUM
}SM_state_Type;


/*******************************************************************************
* the globals
******************************************************************************/
SM_CTRL_Data_Type SM_CTRL_data;
static SM_state_Type SM_state,SM_last_state;
static uint8_t ZD_DATA_L[3]={0},ZD_DATA_R[3]={0},KB_DATA_L[5]={0},KB_DATA_R[5]={0};
static uint8_t SM_TJ_Req[4]={0};
/*******************************************************************************
* the const
******************************************************************************/



/*******************************************************************************
* the functions
******************************************************************************/

static void UpdateLinMsg(SM_CTRL_Data_Type* data)
{
    LIN_UpdateTxData(0,0,data->rawdata[0]);
    LIN_UpdateTxData(0,1,data->rawdata[1]);
    LIN_UpdateTxData(0,2,data->rawdata[2]);
    LIN_UpdateTxData(0,3,data->rawdata[3]);
}

static void SM_OFF_task(void)
{
    SM_CTRL_data.rawdata[0] = 0;
    SM_CTRL_data.rawdata[1] = 0;
    SM_CTRL_data.rawdata[2] = 0;
    SM_CTRL_data.rawdata[3] = 0;
    for (uint8_t i = 0; i < 4; i++)
    {
        if (SM_TJ_Req[i] == SM_TJ_ACT_Plus)
        {
            SM_CTRL_data.msg.ZD_AP = 1;
            break;
        }
    }
    if (SM_TJ_Req[SM_TJ_ZD_L]!=0 || SM_TJ_Req[SM_TJ_ZD_R]!=0 )
    {
        SM_CTRL_data.msg.ZD_V2_12V = 1;
    }
    else
    {
        SM_CTRL_data.msg.ZD_V2_12V = 0;
    }
    if (SM_TJ_Req[SM_TJ_KB_U]!=0 || SM_TJ_Req[SM_TJ_KB_D]!=0 )
    {
        SM_CTRL_data.msg.KB_V2_12V = 1;
    }
    else
    {
        SM_CTRL_data.msg.KB_V2_12V = 0;
    }
    SM_CTRL_data.msg.KB_U_PLUS = (SM_TJ_Req[SM_TJ_KB_U]==SM_TJ_ACT_Plus?1:0);
    SM_CTRL_data.msg.KB_U_MINUS = (SM_TJ_Req[SM_TJ_KB_U]==SM_TJ_ACT_Minus?1:0);
    
    SM_CTRL_data.msg.KB_D_PLUS = (SM_TJ_Req[SM_TJ_KB_D]==SM_TJ_ACT_Plus?1:0);
    SM_CTRL_data.msg.KB_D_MINUS = (SM_TJ_Req[SM_TJ_KB_D]==SM_TJ_ACT_Minus?1:0);

    SM_CTRL_data.msg.ZD_L_PLUS = (SM_TJ_Req[SM_TJ_ZD_L]==SM_TJ_ACT_Plus?1:0);
    SM_CTRL_data.msg.ZD_L_MINUS = (SM_TJ_Req[SM_TJ_ZD_L]==SM_TJ_ACT_Minus?1:0);

    SM_CTRL_data.msg.ZD_R_PLUS = (SM_TJ_Req[SM_TJ_ZD_R]==SM_TJ_ACT_Plus?1:0);
    SM_CTRL_data.msg.ZD_R_MINUS = (SM_TJ_Req[SM_TJ_ZD_R]==SM_TJ_ACT_Minus?1:0);
    
    UpdateLinMsg(&SM_CTRL_data);
    SM_last_state=SM_state;
}
static void SM_RUN1_task(void)//50ms
{
    static uint16_t run_counter;
    static uint8_t runstate,zd_run_state,kb_run_state;
    
    if(SM_last_state!=SM_state)
    {
        runstate = 0;
        run_counter = 0;
        SM_last_state=SM_state;
        zd_run_state = 0;
        kb_run_state = 0;
    }
    run_counter++;
    if (run_counter >= 100)
    {
        run_counter = 0;
        zd_run_state++;
        if (zd_run_state >= 3)
        {
            zd_run_state = 0;
        }
        
        kb_run_state++;
        if (kb_run_state >= 5)
        {
            kb_run_state = 0;
        }
    }
    for (uint8_t i = 0; i < 3; i++)
    {
        if (i == zd_run_state)
        {
            ZD_DATA_L[i] = 1;
            ZD_DATA_R[i] = 1;
        }
        else
        {
            ZD_DATA_L[i] = 0;
            ZD_DATA_R[i] = 0;
        }
    }
    for (uint8_t i = 0; i < 5; i++)
    {
        if (i == kb_run_state)
        {
            KB_DATA_L[i] = 1;
            KB_DATA_R[i] = 1;
        }
        else
        {
            KB_DATA_L[i] = 0;
            KB_DATA_R[i] = 0;
        }
    }
#if 1
    SM_CTRL_data.msg.ZD_L0 = ZD_DATA_L[0];
    SM_CTRL_data.msg.ZD_L1 = ZD_DATA_L[1];
    SM_CTRL_data.msg.ZD_L2 = ZD_DATA_L[2];
    SM_CTRL_data.msg.ZD_R0 = ZD_DATA_R[0];
    SM_CTRL_data.msg.ZD_R1 = ZD_DATA_R[1];
    SM_CTRL_data.msg.ZD_R2 = ZD_DATA_R[2];
#endif
#if 1
    SM_CTRL_data.msg.KB_L0 = KB_DATA_L[0];
    SM_CTRL_data.msg.KB_L1 = KB_DATA_L[1];
    SM_CTRL_data.msg.KB_L2 = KB_DATA_L[2];
    SM_CTRL_data.msg.KB_L3 = KB_DATA_L[3];
    SM_CTRL_data.msg.KB_L4 = KB_DATA_L[4];
    SM_CTRL_data.msg.KB_R0 = KB_DATA_R[0];
    SM_CTRL_data.msg.KB_R1 = KB_DATA_R[1];
    SM_CTRL_data.msg.KB_R2 = KB_DATA_R[2];
    SM_CTRL_data.msg.KB_R3 = KB_DATA_R[3];
    SM_CTRL_data.msg.KB_R4 = KB_DATA_R[4];
    SM_CTRL_data.msg.KB_V2_12V = 1;
#endif
    SM_CTRL_data.msg.ZD_V2_12V = 1;
    SM_CTRL_data.msg.ZD_AP = 1;
    
    UpdateLinMsg(&SM_CTRL_data);
}
static void SM_RUN2_task(void)
{
    static uint16_t run_counter;
    static uint8_t runstate;
    //SM_CTRL_data.msg.V2_12V = 1;
    //SM_CTRL_data.msg.AP = 1;
    UpdateLinMsg(&SM_CTRL_data);
}
static void SM_RUN3_task(void)
{
    static uint16_t run_counter;
    static uint8_t runstate;
    //SM_CTRL_data.msg.V2_12V = 1;
    //SM_CTRL_data.msg.AP = 1;
    UpdateLinMsg(&SM_CTRL_data);
}

void SeatMassage_Init(void)
{
    for (uint8_t i = 0; i < 4; i++)
    {
        SM_CTRL_data.rawdata[i] = 0;
    }
    
    UpdateLinMsg(&SM_CTRL_data);

}

void SeatMassage_task(void)
{
    switch (SM_state)
    {
    case SM_INIT:
        SM_state = SM_OFF;
        break;
    case SM_OFF:
        SM_OFF_task();
        break;
    case SM_RUN1:
        SM_RUN1_task();
        break;
    case SM_RUN2:
        SM_RUN2_task();
        break;
    case SM_RUN3:
        SM_RUN3_task();
        break;
    default:
        SM_state = SM_OFF;
        break;
    }
    if (SM_state > SM_INIT && SM_state < SM_STATE_NUM)
    {
        scm_canmatrix_tx.SCM_STATE.ZY_MSSG_STATE = SM_state-1;
    }
    else
    {
        scm_canmatrix_tx.SCM_STATE.ZY_MSSG_STATE = 0;
    }
    
}

void SeatMassage_ReqRun(uint8_t state)
{
    if (state < 3)
    {
        SM_state = SM_RUN1 + state;
    }
    
}

void SeatMassage_ReqOFF(void)
{
    SM_state = SM_OFF;
}

void SeatMassage_ReqNext(void)
{
    if (SM_state == SM_OFF)
    {
        SM_state = SM_RUN1;
    }
    else
    {
        SM_state = SM_OFF;
    }
}

void SeatMassage_TJ_Req(SM_TJ_ITEM_Type item,SM_TJ_ACT_Type act)
{
    if (item >= SM_TJ_ITEM_NUM || act >= SM_TJ_ACT_NUM)
    {
        return;//error
    }

    SM_TJ_Req[item] = act;
}
