//
// Created by huli on 2020/9/25.
//
#pragma once

#include "tool/singleton.h"
#include "snap7_communication_base.h"
#include <glog/logging.h>

class Snap7Clamp:public Singleton<Snap7Clamp>, public Snap7_communication_base
{
public:
	//发送db快的标记位, 保证先发数据再发唯一码
	enum Send_database_flag
	{
		E_SEND_UNKNOW					= 0,
		E_SEND_DATA_START              	= 1,    //开始发送数据
		E_SEND_DATA_END              	= 2,    //结束发送数据
		E_SEND_KEY_START				= 3,	//开始发送唯一码
		E_SEND_KEY_END					= 4,	//结束发送唯一码
	};


#pragma pack(push, 1)	//struct按照1个byte对齐
#define CLAMP_SAFETY_HEART_DBNUMBER		9070
#define CLAMP_SAFETY_PLC_DBNUMBER		9070
    struct WheeLData {
        unsigned short wheel_exist;
        float offset;
        float gap;
        unsigned short clamp_completed;

        void info() const {
            if (wheel_exist == 0) {
                return;
            }
            LOG(INFO) << "wheel_exist = " << wheel_exist
                       << ", offset = " << offset
                       << ", gap = " << gap
                       << ", clamp_completed = " << clamp_completed;
        }

        void clear() {
            wheel_exist = false;
            offset = 0;
            gap = 0;
            clamp_completed = 0;
        }
    };

    struct PLCData {
        unsigned short pingpong;

        struct WheeLData wheels[4];

        void info() {
            LOG(INFO) << "pingdong = " << pingpong;
            wheels[0].info();
            wheels[1].info();
            wheels[2].info();
            wheels[3].info();
        }

        void clear() {
            wheels[0].clear();
            wheels[1].clear();
            wheels[2].clear();
            wheels[3].clear();
        }
    };
#pragma pack(pop)		//取消对齐

    // 子类必须把父类设定为友元函数，这样父类才能使用子类的私有构造函数。
	friend class Singleton<Snap7Clamp>;

private:
	// 父类的构造函数必须保护，子类的构造函数必须私有。
    Snap7Clamp();

public:
	//必须关闭拷贝构造和赋值构造，只能通过 get_instance 函数来进行操作唯一的实例。
    Snap7Clamp(const Snap7Clamp& other) = delete;
    Snap7Clamp& operator =(const Snap7Clamp& other) = delete;
	~Snap7Clamp() override;

public://API functions
	//初始化 通信 模块。如下三选一
	Error_manager communication_init();
	//反初始化 通信 模块。
	Error_manager communication_uninit() override;

protected://member functions
	//更新数据
    Error_manager updata_receive_buf() override;
    Error_manager updata_send_buf() override;

protected://member variable
public:
	std::mutex      m_data_lock;						//数据锁

	PLCData         plcData{};
    unsigned short            m_heart;
private:

};
