#pragma once

class Figure {
 public:
    virtual std::string Name() = 0;

    virtual double Perimeter() = 0;

    virtual double Area() = 0;
};

class Rect : public Figure {
 public:
    Rect(int w, int h) : width(w), height(h) {}

    std::string Name() override {
        return "RECT";
    }

    double Perimeter() override {
        return ((width + height) * 2);
    }

    double Area() override {
        return (width * height);
    }

 private:
    double width, height;
};


class Treangle : public Figure {
 public:
    Treangle(int a, int b, int c) : A(a), B(b), C(c) {}

    std::string Name() override {
        return "TREANGLE";
    }

    double Perimeter() override {
        return (A + B + C);
    }

    double Area() override {
        double p = (A + B + C) / 2;
        return sqrt(p * (p - A) * (p - B) * (p - C));
    }

 private:
    double A, B, C;
};


class Circle : public Figure {
 public:
    Circle(int r) : R(r) {}

    std::string Name() override {
        return "CIRCLE";
    }

    double Perimeter() override {
        return 2 * P * R;
    }

    double Area() override {
        return P * R * R;
    }

 private:
    double R;
    double P = 3.14;
};


auto CreateFigure(std::istringstream &is) {
    std::string figure_name;
    is >> figure_name;
    is >> std::ws;

    if (figure_name == "RECT") {
        int a, b;
        is >> a;
        is >> std::ws;
        is >> b;

        std::shared_ptr <Figure> figure;
        {
            std::shared_ptr <Rect> rect = std::make_shared<Rect>(a, b);
            figure = rect;
        }

        return figure;
    } else if (figure_name == "TRIANGLE") {
        int a, b, c;
        is >> a;
        is >> std::ws;
        is >> b;
        is >> std::ws;
        is >> c;

        std::shared_ptr <Figure> figure;
        {
            std::shared_ptr <Treangle> treatangle = std::make_shared<Treangle>(a, b, c);
            figure = treatangle;
        }

        return figure;
    } else if (figure_name == "CIRCLE") {
        int r;
        is >> r;

        std::shared_ptr <Figure> figure;
        {
            std::shared_ptr <Circle> circle = std::make_shared<Circle>(r);
            figure = circle;
        }

        return figure;
    }
}