#ifndef __MESSAGE_HPP__
#define __MESSAGE_HPP__
#include <stdint.h>
#include <time.h>
#include "worker.h"
#include "protocol.h"

struct zistream;

/*
 * tdoa协议之分站数据
 * */
struct message_site{
    uint16_t m_time_stamp;      // 分站时间戳
    time_t   m_site_time;       // 分站时间
    uint32_t m_site_id;         // 分站号
    uint8_t  m_status;          // 状态
    uint8_t  m_reverse;         // 保留
    uint8_t  m_power_status;    // 电源状态

    message_site():m_time_stamp(0), m_site_time(0), m_site_id(0), m_status(0), m_reverse(0), m_power_status(0)
    {}

    void clear()
    {
        m_time_stamp = m_site_time = m_site_id = m_status = m_reverse = m_power_status = 0;
    }
};

/*
 * tdoa协议之卡数据,支持以下三种数据协议:
 * 1.tdoa实时定位数据协议;
 * 2.扩展tdoa实时定位数据协议;
 * 3.扩展tdoa实时定位数据协议(带惯导数据);
 * */
struct message_tdoa_card{
	uint8_t  m_type;                // 卡类型
	uint32_t m_id;                  // 卡id
	uint16_t m_time_stamp;          // 卡报文时间戳
	uint8_t  m_battery_status;      //  电池状态
	uint8_t  m_call_info;           // 0x80-呼救,0x01-一般呼叫,0x02-紧急呼叫
	int8_t  m_rav;                 // 角速度
	uint8_t  m_acc;                 // 加速度
    uint64_t m_loc_stamp;           // 定位时间戳
	uint8_t  m_ant_id;              // 天线号
	uint16_t m_sync_num;            // 同步序列号 
	int16_t  m_rssi;                // 脉冲信道响应值
    int16_t  m_strength;            // 信号强度
    int16_t  m_rxpacc;              // 接收信号功率

    // 以下参数用于tdoa带惯导数据输出
    int16_t m_acc_data[3];          // 加速度三轴数据,0-x,1-y,2-z
    int16_t m_rav_data[3];          // 角速度三轴数据,0-x,1-y,2-z
    uint8_t m_walk_steps;           // 行进步数
    uint8_t m_jump_counts;          // 跳跃次数
    uint8_t m_hang_time;            // 滞空时间
    uint8_t m_hang_height;          // 滞空高度

    message_tdoa_card():m_type(0), m_id(0), m_time_stamp(0), m_battery_status(0), m_call_info(0), m_rav(0), m_acc(0), m_loc_stamp(0), m_ant_id(0), m_sync_num(0), m_rssi(0), m_strength(0), m_rxpacc(0), m_walk_steps(0), m_jump_counts(0), m_hang_time(0), m_hang_height(0)
    {
        m_acc_data[0] = m_acc_data[1] = m_acc_data[2] = 0;
        m_rav_data[0] = m_rav_data[1] = m_rav_data[2] = 0;
    }

    int64_t get_long_id()const
    {
        return (((int64_t)m_type) << 32) | m_id;
    }

    void clear()
    {
        m_type = m_id = m_time_stamp = m_battery_status =
        m_call_info = m_rav = m_acc = m_loc_stamp = m_ant_id =
        m_sync_num = m_rssi = m_strength = m_rxpacc = m_walk_steps =
        m_jump_counts = m_hang_time = m_hang_height = 0;
    }
};

/*
 * tdoa消息虚基类,主要定义子类重载的方法
 *
 * */
struct message_loc{
    virtual void zero_this() = 0;
    virtual void load(zistream& is, uint16_t& cmd) = 0;
    virtual int64_t long_id()const = 0;
};

struct message_tdoa_locinfo:task{
    message_site m_site_msg;
    message_tdoa_card m_card_msg;

    uint64_t m_interpolation;
    uint8_t  m_loc_type;
    uint8_t  m_loc_dimension;

    virtual void zero_this();
    virtual void load(zistream& is, uint16_t& cmd);
    virtual int64_t long_id()const
    {
        return m_card_msg.get_long_id();
    }
};

//	分站传上来的卡定位数据,包括tof,tdoa
struct message_locinfo:task
{
	uint64_t m_time_stamp;		// 分站时间戳
	time_t   m_site_time;		// 分站时间
	uint64_t m_tof;				// 卡tof值
	uint32_t m_site_id;			// 分站号
	uint32_t m_card_type;		// 卡类型
	uint32_t m_card_id;			// 卡id
	uint16_t m_card_ct;			// 卡报文时间戳
	uint8_t  m_batty_status;	//  电池状态
	uint8_t  m_callinfo;		// 0x80-呼救,0x01-一般呼叫,0x02-紧急呼叫
	int8_t  m_rav;				// 角速度
	uint8_t  m_acc;				// 加速度
	uint8_t  m_ant_id;			// 天线号
	uint16_t m_sync_ct;			// 同步序列号,对于pdoa应用,用来保存是否使用原始定位算法参数 
	int16_t  m_rssi;			// 信号功率强度

    //优化协议
    float m_distance;

    uint8_t m_loc_type;     // 数据类型,tof,tdoa,pdoa
    
	void zero_this();
    void load(zistream&is,bool tdoa);
    void set_rav(uint8_t rav){m_rav=rav;}
    static std::vector<task*> load_opt(zistream&is);
    static task* clone(message_locinfo* ml);

	int64_t long_id()const 
	{
		return (((int64_t)m_card_type)<<32)|m_card_id;
	}
};

//tdoa分站同步数据
struct message_tdoasync:task
{
	uint32_t m_local_site_id;       // 本地分站号
	uint32_t m_parent_site_id;      // 上一级分站号
	uint16_t m_local_ant_id;        // 分站分站天线号
	uint16_t m_parent_ant_id;       // 上一级分站天线号
	uint16_t m_sync_num;            // 同步序列号
	uint16_t m_local_level;         // 分站本地层级
	uint64_t m_recv_time;           // 接收时间
	uint64_t m_send_time;           // 发送时间
    uint64_t m_root_site_id;        // 本次同步root节点分站号
    uint16_t m_root_ant_id;         // 本次同步root节点天线号

	void zero_this();
    void load(zistream&is);
};

// pdoa分站数据
struct message_pdoa_locinfo: public message_locinfo{
    uint8_t m_loc_type;
    uint8_t m_loc_dimension;
    float m_poa[3];
    
    void zero_this();
    void load(zistream& is);
};

struct message_light: task{
    uint32_t m_light_id;
    uint8_t  m_type;
    uint16_t m_stamp;
    uint64_t m_recv_time;
    uint8_t  m_status;

    message_light(): m_light_id(0), m_type(0), m_stamp(0), m_recv_time(0), m_status(0)
    {}

    message_light(const uint32_t& lid, const uint16_t& type, const uint8_t& stamp, const uint64_t& rtime): m_status(0)
    {}
};


#endif