using System;
using System.Drawing;
using System.Windows.Forms;
using OpenTK;
using OpenTK.Graphics.OpenGL;

namespace ComputerGraphicsLab2
{
    public partial class Form1 : Form
    {
        private bool glLoaded = false;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
        }

        private void glControl1_Load(object sender, EventArgs e)
        {
            glLoaded = true;
            
            // Настройка OpenGL
            GL.ClearColor(Color.White);
            GL.Enable(EnableCap.DepthTest);
            
            // Настройка viewport
            GL.Viewport(0, 0, glControl1.Width, glControl1.Height);
            
            // Настройка проекции
            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
            GL.Ortho(-2.0, 2.0, -2.0, 2.0, -1.0, 1.0);
            
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();
            
            // Принудительная перерисовка
            glControl1.Invalidate();
        }

        private void glControl1_Paint(object sender, PaintEventArgs e)
        {
            if (!glLoaded) return;
            
            // Очистка экрана
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            
            // Рисуем прямоугольник для примера
            DrawRectangle();

            // Пример использования функции рисования правильного многоугольника
            // Пример 1: пятиугольник с одним цветом
            DrawRegularPolygon(
                new Vector2(0.0f, 0.0f),  // центр
                0.5f,                     // радиус
                new Vector3(0.0f, 0.5f, 1.0f), // синий цвет
                5,                        // пятиугольник
                BeginMode.Polygon        // режим рисования - контур
            );

            // Пример 2: треугольник с разными цветами вершин
            Vector3[] triangleColors = new Vector3[3];
            triangleColors[0] = new Vector3(1.0f, 0.0f, 0.0f); // красный
            triangleColors[1] = new Vector3(0.0f, 1.0f, 0.0f); // зеленый
            triangleColors[2] = new Vector3(0.0f, 0.0f, 1.0f); // синий

            DrawRegularPolygon(
                new Vector2(-1.0f, -1.0f), // центр
                0.3f,                      // радиус
                triangleColors,            // массив цветов
                3,                         // треугольник
                BeginMode.Polygon          // режим рисования - заполненный
            );
            
            // Отображение результата
            glControl1.SwapBuffers();
        }

        private void DrawRectangle()
        {
            var z = 4.0f;
            var pointsCount = 4;
            var colors = new Vector3[pointsCount];
            var points = new Vector3[pointsCount];

            colors[0] = new Vector3(1.0f, 0.0f, 0.0f);
            colors[1] = new Vector3(0.0f, 1.0f, 0.0f);
            colors[2] = new Vector3(0.0f, 0.0f, 1.0f);
            colors[3] = new Vector3(1.0f, 1.0f, 0.0f);
            
            points[0] = new Vector3(-1.0f, -1.0f, z);
            points[1] = new Vector3(1.0f, -1.0f, z);
            points[2] = new Vector3(1.0f, 1.0f, z);
            points[3] = new Vector3(-1.0f, 1.0f, z);
            
            DrawPolygon(points, colors, pointsCount, BeginMode.LineLoop);
        }

        private void DrawPolygon(Vector3[] points, Vector3[] colors, int n, BeginMode mode)
        {
            GL.Begin(mode);
            for (int i = 0; i < n; i++)
            {
                GL.Color3(colors[i]);
                GL.Vertex2(points[i].X, points[i].Y);
            }
            GL.End();
        }

        /// <summary>
        /// Рисует правильный многоугольник
        /// </summary>
        /// <param name="center">Центр многоугольника</param>
        /// <param name="radius">Радиус описанной окружности</param>
        /// <param name="colors">Цвет или массив цветов вершин</param>
        /// <param name="sides">Количество граней</param>
        /// <param name="mode">Режим рисования (BeginMode)</param>
        public void DrawRegularPolygon(Vector2 center, float radius, object colors, int sides, BeginMode mode)
        {
            if (sides < 3)
                throw new ArgumentException("Количество граней должно быть не менее 3", nameof(sides));

            // Создаем массивы для точек и цветов
            var points = new Vector3[sides];
            var colorArray = new Vector3[sides];

            // Угол между гранями
            float angleStep = 2 * (float)Math.PI / sides;

            // Рассчитываем координаты вершин
            for (int i = 0; i < sides; i++)
            {
                float angle = i * angleStep;
                float x = center.X + radius * (float)Math.Cos(angle);
                float y = center.Y + radius * (float)Math.Sin(angle);
                points[i] = new Vector3(x, y, 0.0f);
            }

            // Обрабатываем параметр цвета
            if (colors is Vector3 singleColor)
            {
                // Если передан один цвет, применяем его ко всем вершинам
                for (int i = 0; i < sides; i++)
                {
                    colorArray[i] = singleColor;
                }
            }
            else if (colors is Vector3[] colorsList)
            {
                // Если передан массив цветов
                if (colorsList.Length < sides)
                    throw new ArgumentException("Количество цветов меньше, чем количество граней", nameof(colors));

                // Копируем цвета в массив
                for (int i = 0; i < sides; i++)
                {
                    colorArray[i] = colorsList[i];
                }
            }
            else
            {
                throw new ArgumentException("Неверный тип параметра цвета. Ожидается Vector3 или Vector3[]", nameof(colors));
            }

            // Рисуем многоугольник
            DrawPolygon(points, colorArray, sides, mode);
        }
    }
}