#include <iostream>
#include <vector>

using namespace std;

class Point{
    int x, y;

    public:

    Point(int _x = 0, int _y = 0){
        cout << "Constructor " << this << " initialized.\n";
        this->x = _x; this->y = _y;
    }

    void set_coordinates(){
        int _x, _y;
        cout << " input x y coordinates with space: "; cin >> _x >> _y;
        this->x = _x; this->y = _y;
    }

    int get_x(){ return this->x; }
    int get_y(){ return this->y; }

    ~Point(){
        cout << "Destructor " << this << " initialized.\n";
    }
};
 
enum class e_types {
    rect,
    square,
    rhombus,
    trapezoid,
    same_shape,
    parallelogram
};
 
e_types get_typeof_shape(Point& a, Point& b, Point& c, Point& d) {
 
    int AB, BC,
        CD, DA,
        AC, BD;

    AB = ((a.get_x() - b.get_x()) * (a.get_x() - b.get_x()) + (a.get_y() - b.get_y()) * (a.get_y() - b.get_y()));
    BC = ((b.get_x() - c.get_x()) * (b.get_x() - c.get_x()) + (b.get_y() - c.get_y()) * (b.get_y() - c.get_y()));
    CD = ((c.get_x() - d.get_x()) * (c.get_x() - d.get_x()) + (c.get_y() - d.get_y()) * (c.get_y() - d.get_y()));
    DA = ((d.get_x() - a.get_x()) * (d.get_x() - a.get_x()) + (d.get_y() - a.get_y()) * (d.get_y() - a.get_y()));
    AC = ((a.get_x() - c.get_x()) * (a.get_x() - c.get_x()) + (a.get_y() - c.get_y()) * (a.get_y() - c.get_y()));
    BD = ((b.get_x() - d.get_x()) * (b.get_x() - d.get_x()) + (b.get_y() - d.get_y()) * (b.get_y() - d.get_y()));
 
    if (AB == CD && BC == DA) {
        if (AB == BC) {
            if (AC == BD) {
                return e_types::square;
            }
            else {
                return e_types::rhombus;
            }
        }
        else
            if (AC == BD) {
                return e_types::rect;
            }
            else {
                return e_types::parallelogram;
            }
    }
    else
 
        if (((a.get_x() - b.get_x()) * (c.get_y() - d.get_y()) == (a.get_y() - b.get_y()) * (c.get_x() - d.get_x())) || 
            ((a.get_x() - d.get_x()) * (b.get_y() - c.get_y()) == (a.get_y() - d.get_y()) * (b.get_x() - c.get_x())))
            return e_types::trapezoid;
        else
            return e_types::same_shape;
}

int main() {
    e_types *result;
    result = new e_types;

    int x[4], y[4];
    for (int i = 0; i < 4; i++){ cout << i+1 << " point -" << " input x y coordinates with space: "; cin >> x[i] >> y[i]; }
    cout << "\n";

    Point first_point = Point(x[0], y[0]);
    Point second_point = Point(x[1], y[1]);
    Point third_point = Point(x[2], y[2]);
    Point fourth_point = Point(x[3], y[3]);

    *result = get_typeof_shape(first_point, second_point, third_point, fourth_point);

    cout << "\nDefined type of shape: ";
    switch (*result)
    {
    case e_types::same_shape:
        std::cout << "arbitrary quadrangle" << std::endl;
        break;
    case e_types::rect:
        std::cout << "rect" << std::endl; //прямоугол
        break;
    case e_types::rhombus:
        std::cout << "rhombus" << std::endl;//ромб
        break;
    case e_types::square:
        std::cout << "square" << std::endl;
        break;
    case e_types::trapezoid:
        std::cout << "trapezoid" << std::endl;//трапеция
        break;
    case e_types::parallelogram:
        std::cout << "parallelogram" << std::endl;//parallelogram
        break;
    }

    delete result;

    cout << "\n";
}