#ifndef POLYGON_HPP
#define POLYGON_HPP


#include <iostream>
#include <string>
#include <vector>
#include "vertex.hpp"
#include "matrix.hpp"
#include "coefficients.hpp"
#include "error.hpp"

using namespace std;

class Polygon{
private:
  static Coefficients coefficients;
  size_t length;
  vector<Vertex> vertices;
  unordered_map<Vertex,uint64> indices;
  Matrix B;
  Matrix C;
  Matrix M;
  double fp;
  void compute_B();
  void compute_C();
  void compute_M();
  void compute_fp();
  void add_vertex(const int32& x,const int32& y);
  void add_neighbours(const int32& x,const int32& y);
public:
  static Coefficients& get_coefficients();
  Polygon();
  Polygon(string str);
  size_t size() const;
  size_t graph_size() const;
  Vertex vertex(size_t i) const;
  double get_coeff_B(size_t i,size_t j) const;
  double get_coeff_C(size_t i,size_t j) const;
  double get_coeff_M(size_t i,size_t j) const;
  double get_fp() const;

};

inline
Polygon::Polygon(){
  length=0;
}

inline size_t
Polygon::size() const{
  return length;
}

inline size_t
Polygon::graph_size() const{
  return vertices.size();
}

inline Vertex
Polygon::vertex(size_t i) const{
  return vertices[i];
}

inline Coefficients&
Polygon::get_coefficients(){
  return coefficients;
}

inline double
Polygon::get_fp() const{
  return fp;
}

inline double
Polygon::get_coeff_B(size_t i,size_t j) const{
  return B.get(i,j);
}

inline double
Polygon::get_coeff_C(size_t i,size_t j) const{
  return C.get(i,j);
}

inline double
Polygon::get_coeff_M(size_t i,size_t j) const{
  return M.get(i,j);
}
#endif
