#define _USE_MATH_DEFINES
#include <math.h>
#include "figures.h"
#include <iostream>
#include <vector>
#include <ostream>

//Длина отрезка ab
double length(Figure::Point a, Figure::Point b){
	return sqrt(double((a.x-b.x) * (a.x-b.x) + (a.y-b.y)*(a.y-b.y)));
}

Circle::Circle(Point center, int rad, int color): 
 Figure(color), //вызываем конструктор базового класса
 center(center), rad(rad) //инициализация полей
 {}

double Circle::place() const {
    #ifdef _DEBUG
	  std::cerr << "In Circle::place()\n";
    #endif
	return M_PI * rad * rad;
}

double Circle::perimetr() const {
    #ifdef _DEBUG
	  std::cerr << "In Circle::perimetr()\n";
    #endif
	return 2 * M_PI * rad;
}

void Circle::output() const{
	std::cout << "<" << "Cricle: " << "x=" << center.x << ", " << "y=" << center.y << ", " <<  "r=" << rad << ", " << "color=" << color << ">" << std::endl;
}


//===================================================

Triangle::Triangle(Point p1, Point p2, Point p3, int color):
  Figure(color), 
  p1(p1), p2(p2), p3(p3) 
  {}

double Triangle::place() const {
	#ifdef _DEBUG
	  std::cerr << "In Triangle::place()\n";
    #endif
	double ans = 0.5 * ( (p1.x-p3.x)*(p2.y-p3.y)-(p2.x-p3.x)*(p1.y-p3.y) );
	if (ans < 0) {
		ans = -ans;
	}
	return ans;
}

double Triangle::perimetr() const {
	#ifdef _DEBUG
	  std::cerr << "In Triangle::perimetr()\n";
    #endif
	return length(p1,p2) + length(p2,p3) + length(p1,p3);
}

void Triangle::output() const{
	std::cout << "<" << "Triangle:" << "x1="<< p1.x << ", " <<"y1=" << p1.y << ", " << "x2="<< p2.x << ", " <<"y2=" << p2.y << ", " << "x3="<< p3.x << ", " <<"y3=" << p3.y << ">" << std::endl;
	 
	
}




//===================================================
Polygon::Polygon(std::vector<Point> vPolygon, int color):
	Figure(color),
	vPolygon(vPolygon)
	{}

double Polygon::place() const {
	#ifdef _DEBUG
	  std::cerr << "In Polygon::place()\n";
    #endif
	double s = 0.0;
	for (int i = 0; i<vPolygon.size()-1; i++)
	{
		s += (vPolygon[i+1].y + vPolygon[i].y)*(vPolygon[i+1].x-vPolygon[i].x)/2;
	}
	if (s<0) {
		s = -s;
	}
	return s;
}

double Polygon::perimetr() const {
	#ifdef _DEBUG
	  std::cerr << "In Polygon::perimetr()\n";
    #endif
	double p = 0.0;
	for (int i = 0; i<vPolygon.size()-1; i++){
		p += length(vPolygon[i+1], vPolygon[i]);
	}
	return p;

}

void Polygon::output() const{
	std::cout<<"Polygon:";
	for (int i=0; i < vPolygon.size()-1;i++){
		std::cout<<"x"<<i+1<<"="<<vPolygon[i].x<<", "<<"y"<<i+1<<"="<<vPolygon[i].y<<", ";
	}
	std::cout<<"color="<<color<<">"<<std::endl;

}

std::ostream & operator << (std::ostream & os, const Figure &f){
	f.output();
	return os;
}
