#pragma once

#include "opencv2/core/core.hpp"

namespace maps {
namespace wiki {
namespace autocart {
/**
* To find orientation of ordered triplet (p, q, r).
* The function returns following values
* 0 --> p, q and r are colinear
* 1 --> Clockwise
* 2 --> Counterclockwise
*/
enum class Orientation {
    Colinear = 0,
    Clockwise = 1,
    CounterClockwise = 2
};
Orientation orientation(const cv::Point &a,
                        const cv::Point &b,
                        const cv::Point &c);

// check is segments [segm1s -- segm1e] and [segm2s -- segm2s] have common points
bool isSegmentIntersect(const cv::Point &segm1s,
                        const cv::Point &segm1e,
                        const cv::Point &segm2s,
                        const cv::Point &segm2e);

// calculate angle of triplet (v1, c, v2)
double calcAngle(const cv::Point &v1,
                 const cv::Point &c,
                 const cv::Point &v2);

// search projection of point pt on the segment [segms -- segme]
// return false, if the point is projected outside of segment
bool projectPointOnSegment(const cv::Point &pt,
                           const cv::Point &segms,
                           const cv::Point &segme,
                           cv::Point &result);

bool projectPointOnSegment(const cv::Point2d &pt,
                           const cv::Point2d &segms,
                           const cv::Point2d &segme,
                           cv::Point2d &result);

//calculate distance between two segments
double segmentsDistance(const cv::Point2d &segm1s,
                        const cv::Point2d &segm1e,
                        const cv::Point2d &segm2s,
                        const cv::Point2d &segm2e);

// check polygon orientation clockwise or counter clockwise. Y-axis is from top to down
bool isClockwise(const std::vector<cv::Point> &polygon);

// make rectangle from base point, angle and length of two edges
void makeRectangle(const cv::Point &base,
                   double angle,
                   double edgeLen0,
                   double edgeLen1,
                   int orient,
                   std::vector<cv::Point> &polygon);
} //namespace autocart
} //namespace wiki
} //namespace maps
