#ifndef _MAP_LOC_INPUT_HD_MAP_DEFINE_H_
#define _MAP_LOC_INPUT_HD_MAP_DEFINE_H_

////////////////////////////////////////////////////////////////////////////////
// @file : input_hd_map_define.h
// @brief : Define hd map struct, as the input for fusion localization module.
////////////////////////////////////////////////////////////////////////////////

// C & C++ library

// other library
#include "basic_type.h"
#include "hd_map_common_define.h"
#include "jf_shared_data.h"

// project library

namespace jf {

namespace COM = ::jf::common;
namespace HMC = ::jf::hd_map_common;

///////////////////////////////////////////////////////////////////////
// enum define
enum class MarkingCrossing : uint8_t { EDGE_CROSSING_UNDECIEDE = 0, EDGE_CROSSING_NO_CROSSING = 1, EDGE_CROSSING_DOUBLE_CROSSING = 2, EDGE_CROSSING_LEFT_CROSSING = 3, EDGE_CROSSING_RIGHT_CROSSING = 4 };

enum class LinkMarkingSide : uint8_t { LINK_MARKING_SIDE_LEFT = 1, LINK_MARKING_SIDE_RIGHT = 2 };

enum class LaneMarkingSide : uint8_t { LANE_MARKING_SIDE_LEFT = 1, LANE_MARKING_SIDE_LEFT_LEFT = 2, LANE_MARKING_SIDE_RIGHT = 3, LANE_MARKING_SIDE_RIGHT_RIGHT = 4 };

// enum class TrafficSignClass: uint8_t
// {
//   TRAFFIC_SIGN_UNDECIDED    = 0,
//   TRAFFIC_SIGN_WARNING      = 2,       // waring sign
//   TRAFFIC_SIGN_PROHIBIT     = 3,       // no traffic allowed
//   TRAFFIC_SIGN_Instructions = 4,       // 指示
//   Guide        = 5,       // 指引
//   Information  = 6,       // 告知
//   Tourist      = 7,       // 旅游区,
// };

///////////////////////////////////////////////////////////////////////
// struct define
struct IGnssLocationData {
    IGnssLocationData() : heading(0.0), speed(0.0), coefficient(0.0), credible(false), longitude_deviation(0.0), latitude_deviation(0.0), height_deviation(0.0) {}

    COM::TimeStamp timestamp;  // 时间戳
    COM::Point gnss_point;     // lon, lat,
    float32_t heading;         // heading angle
    float32_t speed;           // vehicle speed
    float32_t coefficient;     // Error coefficient, floating-point number above 0,
                               // mainly depends on the accuracy of GNSS,
                               // which is used to judge the availability of GNSS
    bool credible;             // credible
    float64_t gnss_time;
    float32_t longitude_deviation;  // standard deviation of position of longitude in WGS84 coordinate system, m
    float32_t latitude_deviation;   // standard deviation of position of latitude in WGS84 coordinate system, m
    float32_t height_deviation;     // standard deviation of position of height in WGS84 coordinate system, m
};

struct ILinkMarking  // end of namespace object_localization_ros
{
    ILinkMarking() : angle(0.0), dis(0.0), exist_prob(0.0) {}

    LinkMarkingSide pos;        // Location of road edge line, not land edge
    HMC::LaneMarkingType type;  // type
    float32_t angle;
    float64_t dis;         // The distance to the car,
    float64_t exist_prob;  // The existence probability is obtained from the perception result,
                           // and the value range is equal to the feedback value of the perception result
};

struct ILaneMarking {
    ILaneMarking() : angle(0.0), dis(0.0), exist_prob(0.0) {}

    LaneMarkingSide pos;  // Location of road edge line, not land edge
    HMC::LaneMarkingColor lane_marking_color;
    float64_t color_prob;
    HMC::LaneMarkingType cross_type;
    float32_t angle;
    float64_t dis;         // The distance to the car
    float64_t exist_prob;  // The existence probability is obtained from the perception result,
                           // and the value range is equal to the feedback value of the perception result
};

struct ITrafsign {
    ITrafsign() : traffic_sign_class(0), traffic_sign_sub_class(0), speed_limit_value(0) {}

    uint8_t traffic_sign_class;      // Traffic sign frist categories
    uint8_t traffic_sign_sub_class;  // Traffic sign sub categories,
    uint8_t speed_limit_value;       // Speed limit plate, actual value, no enumeration required
    uint8_t traffic_sign_shape;      // Traffic sign shape
    float64_t exist_prob;            // The existence probability is obtained from the perception result,
                                     // and the value range is equal to the feedback value of the perception result
};

struct ITrafsignMap : ITrafsign {
    ITrafsignMap() : lon_dis(0.0), lat_dis(0.0) {}

    double lon_dis;  // Distance in longitude
    double lat_dis;  // Distance in latitude
};

struct IVisionMap {
    IVisionMap() {}

    COM::TimeStamp timestamp;  // time stamp
    MarkingCrossing crossing;
    std::vector<ILinkMarking> left_link_marking;   // left side road boundary, it could be one or more
    std::vector<ILaneMarking> lane_markings;       // Lane marking collection,
                                                   // the left side of the road driving direction is the first,
                                                   // and the right side is stored in turn.
    std::vector<ILinkMarking> right_link_marking;  // right side road boundary, it could be one or more
    std::vector<ITrafsignMap> traffic_signs;       // Tranffic signs
};

struct IGnssFootLocation {
    IGnssFootLocation()
        : change_lanes(false),
          lane_seq_no(0),
          lane_num(0),
          road_type(0),
          special_type(0),
          special_type_begin_dis(0.0),
          special_type_end_dis(0.0),
          left_lane_edge_dis(0.0),
          right_lane_edge_dis(0.0),
          angle_with_lane(0.0),
          in_road_crossing(false),
          foot_prob(0.0),
          horizal_prob(0.0),
          vertical_prob(0.0),
          gnss_time(0.0),
          gnss_heading(0.0),
          gnss_speed(0.0),
          gnss_longitude_deviation(0.0),
          gnss_latitude_deviation(0.0),
          gnss_height_deviation(0.0) {}

    COM::TimeStamp timestamp;            // time stamp
    bool change_lanes;                   // change lane or not
    uint8_t lane_seq_no;                 // Vehicle lane number
    uint8_t lane_num;                    // Total number of lanes
    uint8_t road_type;                   // 0: Not investigate
                                         // 1: Normal road
                                         // 2: Bridge
                                         // 3: Tunnel
                                         // 4: Under elevated bridge
                                         // 5: City valley
    uint8_t special_type;                // type of the special type begin dis and end dis, refer to road type
    float32_t special_type_begin_dis;    // The distance to the begin of special road type, unit: m
    float32_t special_type_end_dis;      // The distance to the end of special road type, unit: m
    float32_t left_lane_edge_dis;        // distance to the left lane edge, unit: m
    float32_t right_lane_edge_dis;       // distance to the right lane edge, unit: m
    float32_t angle_with_lane;           // Angle with the lane edge
    bool in_road_crossing;               // Is it in the road crossing area，
    COM::Point foot_point;               // Perpendicular
    float32_t foot_prob;                 // probability of perpendicular point
    COM::Point vision_horizontal_point;  // visual computing horizontal point
    float32_t horizal_prob;              // probability of horizontal point
    COM::Point vision_vertical_point;    // visual computing vertical point
    float32_t vertical_prob;             // probability of vertical point
    float64_t gnss_time;
    COM::Point gnss_point;               // lon, lat, alt
    float32_t gnss_heading;              // heading angle
    float32_t gnss_speed;                // vehicle speed
    float32_t gnss_longitude_deviation;  // standard deviation of position of longitude in WGS84 coordinate system, m
    float32_t gnss_latitude_deviation;   // standard deviation of position of latitude in WGS84 coordinate system, m
    float32_t gnss_height_deviation;     // standard deviation of position of height in WGS84 coordinate system, m
};

struct ILocalization {
    ILocalization() : roll(0.0), pitch(0.0), heading(0.0), speed(0.0), longitude_accuracy(0.0), latitude_accuracy(0.0) {}

    COM::TimeStamp timestamp;  // time stamp

    COM::Point loc_point;       // localization point
    double roll;                // roll: x
    double pitch;               // pitch: y
    double heading;             // heading: z
    double speed;               // speed
    double longitude_accuracy;  // accuracy on longitude
    double latitude_accuracy;   // accuracy on latitude
    bool gnss_available;
};

struct IMapDrawInfo {
    IMapDrawInfo()
        : heading(0.0),
          pitch(0.0),
          dir_link_geo_id(""),
          inter_point_id(""),
          roll(0.0),
          link_geo_num(0),
          lane_geo_num(0),
          right_lane_boundary_angle(0.0),
          left_lane_boundary_angle(0.0),
          right_lane_boundary_dis(0.0),
          left_lane_boundary_dis(0.0),
          right_lane_boundary_angle_conf(0.0),
          left_lane_boundary_angle_conf(0.0),
          right_lane_boundary_dis_conf(0.0),
          left_lane_boundary_dis_conf(0.0),
          inner_state(0),
          hdm_status(0),
          on_db_road_status(0),
          update_frequency(0),
          accuracy(0.0),
          lateral_accuracy(0.0),
          heading_accuracy(0.0),
          longitudinal_accuracy(0.0),
          speed_accuracy(0.0),
          loc_side(0){};

    COM::TimeStamp timestamp;  // time stamp

    COM::Point cur_point;                      // current point
    float32_t heading;                         // heading
    float32_t pitch;                           // pitch
    std::string dir_link_geo_id;               // linkid
    std::string inter_point_id;                // laneid
    float32_t roll;                            // roll
    COM::Point link_foot_point;                // Perpendicular point on link
    int32_t link_geo_num;                      // 在linkGeo上的投影点所在的shape区间
    COM::Point lane_foot_point;                // Perpendicular point on lane
    int32_t lane_geo_num;                      // 在laneGeo上的投影点所在的shape区间
    float32_t right_lane_boundary_angle;       // angle with the right lane
    float32_t left_lane_boundary_angle;        // angle with the left lane
    float32_t right_lane_boundary_dis;         // distance to the right lane
    float32_t left_lane_boundary_dis;          // distance to the left lane
    float32_t right_lane_boundary_angle_conf;  // confidence of the right_lane_boundary_angle
    float32_t left_lane_boundary_angle_conf;   // confidence of the left_lane_boundary_angle
    float32_t right_lane_boundary_dis_conf;    // confidence of the right_lane_boundary_dis
    float32_t left_lane_boundary_dis_conf;     // confidence of the left_lane_boundary_dis
    uint32_t inner_state;                      // inner state
    uint32_t hdm_status;                       // hdm status
    uint32_t on_db_road_status;                // status on road
    uint32_t update_frequency;                 // frequency of update
    float32_t accuracy;                        // accuracy
    float32_t lateral_accuracy;                // lateral accuracy
    float32_t heading_accuracy;                // heading accuracy
    float32_t longitudinal_accuracy;           // longitudinal accuracy
    float32_t speed_accuracy;                  // speed accuracy
    uint32_t loc_side;                         // loc to the lane(left or right)
};

// for debug info
struct IPoint {
    double x_;
    double y_;
};

struct ILineSection {
    std::vector<IPoint> point_list_;
    uint8_t line_marking_colour_;
    uint8_t line_marking_type_;
    uint8_t line_in_lane_;
};
struct ILane {
    std::vector<ILineSection> line_section_list_;
};

struct IMapDebugInfo {
    std::vector<ILane> lane_list_;
};
// end for debug info

}  // namespace jf

#endif
