#pragma once

#include <opencv2/opencv.hpp>
#include <cmath>
#define _USE_MATH_DEFINES
#include <math.h>

using namespace cv;
using namespace std;


class LFRPoint
{
private:
    /* data */
public:
    double x, y;
    LFRPoint(/* args */);
    LFRPoint(double x, double y);
    ~LFRPoint();

    LFRPoint operator-(const LFRPoint& pt){return LFRPoint(x-pt.x, y-pt.y);}
    LFRPoint operator+(const LFRPoint& pt){return LFRPoint(x+pt.x, y+pt.y);}
};

class LFRVector : public LFRPoint
{
private:
    /* data */
public:
    LFRVector(/* args */);
    LFRVector(double x, double y);
    LFRVector(const LFRPoint& pt);
    ~LFRVector();

    double angle(const LFRVector& other) const;
    double dot(const LFRVector& other) const;
    double norm() const;

};

class LFRLine
{
private:
    /* data */

public:
    LFRPoint start;
    LFRVector dir;

    LFRLine(/* args */);
    LFRLine(LFRPoint start, LFRVector dir);
    LFRLine(LFRPoint start, LFRPoint end);
    ~LFRLine();
};

class Calcs{
    private:
    public:
    static int calcAngle(int deltaX, int deltaY);
};

class FrameData
{
public:
    std::vector<std::vector<cv::Point>> contours;
    std::vector<cv::Rect> boundingBoxes;
    std::vector<cv::Point> leftEdges;
    std::vector<cv::Point> middlePoints;
    double angle; //Angle of the contour the robot has to follow to
    int index; //Index of the contour the robot has to follow to

    FrameData(): contours(), boundingBoxes(), leftEdges(), middlePoints() {}
};