//
// Created by zx on 2019/12/9.
//

#include "PlcData.h"
#include <string.h>

PlcData* PlcData::g_instance=0;

PlcData* PlcData::GetInstance(std::string ip)
{
    if(g_instance==0)
        g_instance=new PlcData(ip);
    return g_instance;

}
void PlcData::UpdateData(stateCode code,int id)
{
    const int length=1;
    int offset=id*length;
    short* data = (short*)malloc(sizeof(short));
    memset(data, 0, sizeof(short));
    switch(code){
        case stateCode::eOk:
            *data = (short)1;
            break;
        case stateCode::eOutOfPlace:
            *data = (short)2;
            break;
        case stateCode::eNoCar:
        default:
            *data = (short)0;
            break;
    }
//    printf("data: %d \n", *data);
    m_lock.lock();
    ////判断越界
    if(offset>=0 && offset+length<=MAX_REGIONS)
        memcpy(m_data+offset,data,length*sizeof(short));
    free(data);
    m_lock.unlock();
}

void PlcData::plcThread(PlcData* p){
    if(p == 0) return;
    if(p->p_plc == 0) return;
    while(!p->m_cond_exit.WaitFor(1)){
        // 显示雷达结果
        std::cout<<"result: [";
        for (int i = 0; i < MAX_REGIONS; ++i) {
            std::cout<<p->m_data[i]<<" ";
        }
        std::cout<<"]"<<std::endl;
        // 写plc
        p->p_plc->WriteShorts(ELE_FENCE_DB_NUM, ELE_FENCE_START_ADDR, MAX_REGIONS, p->m_data);

        usleep(p->m_send_interval_milli * 1000);
    }
}

PlcData::PlcData(std::string ip):
p_send_thread(0)
{
    memset(m_data, 0, MAX_REGIONS* sizeof(short));
    p_plc = new S7PLC();
    if(ip!=""){
        p_plc->connect(ip);
    }
    m_cond_exit.Notify(false);
    p_send_thread = new std::thread(plcThread, this);
}

void PlcData::Release(){
    if(g_instance) {
        g_instance->m_cond_exit.Notify(true);
        if(g_instance->p_plc){
            g_instance->p_plc->disconnect();
            delete g_instance->p_plc;
        }
        delete g_instance;
        g_instance = 0;
    }
}