#ifndef __EVENT_HPP__
#define __EVENT_HPP__
#include <memory>
enum EVENT_STATUS
{
    ///事件开始
    ES_START = 0,
    ///呼救已处理状态
    ES_DEAL_HELP = 1,
    ///事件结束
    ES_END = 100
};


enum OBJECT_TYPE
{
    ///矿井
    OT_MINE = 1,
    ///区域
    OT_AREA = 2,
    ///分站
    OT_DEVICE_READER = 4,
    ///标识卡，包括人员、车辆、自组网等
    OT_CARD = 9,
};

enum EVENT_TYPE{ // 事件类型
    ET_AREA_OVER_COUNT_PERSON = 3,	// 区域人员超员
    ET_AREA_OVER_COUNT_VEHICLE = 4,	// 区域车辆超员
	ET_READER_ERROR = 6,
    ET_CARD_LOW_POWER_SERIOUS = 12, // 电量极低

    ET_CARD_AREA_OVER_TIME_PERSON = 15, // 人员区域超时
    ET_CARD_AREA_OVER_TIME_VEHICLE = 16, // 车辆区域超时
    ET_CARD_OVER_SPEED = 21, // 车辆超速
    ET_CARD_HELP = 24, // 人员呼救

    CARD_EVENT_COUNT_MAX,
};

class Event;
struct event_tool
{
	template <class UnaryPredicate>
	void handle_event(OBJECT_TYPE ot,EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,Unarypredicate p)
	{
		handle_event(ot,et,id,limit_value,cur_value,p());
	}
	void handle_event(OBJECT_TYPE ot,EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,bool f);
	static event_tool * instance();
private:
	event_tool()
	{
		make_event_object();
	}
	void make_event_object();
	std::map<OBJECT_TYPE,std::shared_ptr<Event>>  m_map;
};

struct event_list:single_base<event_list,uint64_t,std::shared_ptr<ya_event>>
{
public:
    static uint64_t to_list_id(EVENT_TYPE ev_type, OBJECT_TYPE obj_type,uint64_t obj_id)
    {
        return (static_cast<uint64_t>(ev_type)<<48)|(static_cast<uint64_t>(obj_type)<<40)|obj_id;
    }

    void load_his_data_from_db();

    ~event_list(){}

    static std::string ev_to_json(std::shared_ptr<ya_event> ev_ptr)
    {
        std::vector<std::shared_ptr<ya_event>> evs;
        evs.push_back(ev_ptr);
        return evs_to_json(evs);
    }

    static std::string evs_to_json(std::vector<std::shared_ptr<ya_event>> arr)
    {
        rapidjson::Document doc(rapidjson::kObjectType);
        rapidjson::Value data(rapidjson::kArrayType);
        rapidjson::Document::AllocatorType& allocator=doc.GetAllocator();

        auto it=arr.begin();
        for(;it!=arr.end();++it)
        {
            if((*it)->m_is_display)
            {
                ev_to_node(*it, allocator, data);
            }
        }

        doc.AddMember(JSON_ROOT_KEY_CMD,JSON_CMD_VALUE_EVENT, allocator);
        doc.AddMember(JSON_ROOT_KEY_VERSION,INTERFACE_VERSION, allocator);
        doc.AddMember(JSON_ROOT_KEY_DATA,data, allocator);

        rapidjson::StringBuffer sb;
        rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(sb);
        doc.Accept(writer);

        return sb.GetString();
    }

private:
    static void ev_to_node(std::shared_ptr<ya_event> ev_ptr,
                           rapidjson::Document::AllocatorType& allocator,
                           rapidjson::Value& out_data)
    {
        rapidjson::Value ev(rapidjson::kObjectType);

        ev.AddMember(JSON_KEY_EVENT_EVENT_ID,ev_ptr->get_id(), allocator);
        ev.AddMember(JSON_KEY_EVENT_STATUS,ev_ptr->m_status, allocator);

        ev.AddMember(JSON_KEY_EVENT_TYPE_ID,ev_ptr->m_ev_type, allocator);
        ev.AddMember(JSON_KEY_EVENT_OBJ_TYPE_ID,ev_ptr->m_obj_type, allocator);

        tool_json::add_member(ev, JSON_KEY_EVENT_OBJ_ID, ev_ptr->m_obj_id, allocator);
        ev.AddMember(JSON_KEY_EVENT_MAP_ID,ev_ptr->m_map_id, allocator);
        ev.AddMember(JSON_KEY_EVENT_AREA_ID,ev_ptr->m_area_id, allocator);
        ev.AddMember(JSON_KEY_EVENT_X,ev_ptr->x, allocator);
        ev.AddMember(JSON_KEY_EVENT_Y,ev_ptr->y, allocator);

        ev.AddMember(JSON_KEY_EVENT_LIMIT_VALUE,ev_ptr->m_limit_value, allocator);
        ev.AddMember(JSON_KEY_EVENT_CUR_VALUE,ev_ptr->m_cur_value, allocator);
        ev.AddMember(JSON_KEY_EVENT_CUR_TIME,tool_time::to_ms(ev_ptr->m_cur_time), allocator);

        ev.AddMember(JSON_KEY_EVENT_LANDMARK_ID,ev_ptr->m_landmarkid, allocator);
        ev.AddMember(JSON_KEY_EVENT_LANDMARK_DIRECTION,ev_ptr->m_landmarkdirect, allocator);
        ev.AddMember(JSON_KEY_EVENT_LANDMARK_DISTANCE,ev_ptr->m_landmarkdist, allocator);

        out_data.PushBack(ev, allocator);
    }

};
#endif
