using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tao.OpenGl;
using Tao.Platform.Windows;

namespace Ornek2020
{
    public partial class Form1 : Form
    {
        OBJLoader Model;
        //Texture ModelTextures;

        float[] ambientLight    = { 0.2f, 0.2f, 0.2f, 1.0f };
        float[] diffuseLight    = { 0.5f, 0.5f, 0.5f, 1.0f };
        float[] specularLight   = { 1.0f, 1.0f, 1.0f, 1.0f };
        float[] specularLight2  = { 1.0f, 1.0f, 1.0f, 1.0f };
        float[] blueDiffuse     = { 0.0f, 0.0f, 0.3f, 1.0f };

        float[] lightpos0 = { 0.0f, 100.0f, 100.0f, 1.0f };
        float[] lightpos1 = { 0.0f, 100.0f, 0.0f, 1.0f };
        float[] lightpos2 = { 100.0f, 0.0f, 0.0f, 1.0f };
        float[] lightpos3 = { -100.0f, 0.0f, 0.0f, 1.0f };

        float step = 5f;
        float rotx, roty, rotz, posz = 0;

        public Form1()
        {
            InitializeComponent();
            OpenGlControl.InitializeContexts();
 
            // OpenGL ilk işlemler
            Gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
 
            float fAspect = 1.0f;

            // Reset coordinate system
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glLoadIdentity();

            // Produce the perspective projection
            Glu.gluPerspective(45.0f, fAspect, 1.0, 1000.0);

            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();

            Gl.glHint(Gl.GL_PERSPECTIVE_CORRECTION_HINT, Gl.GL_NICEST);// Really Nice Perspective Calculations

            // Objemiz yüklenir
            Model = new OBJLoader();
            Model.MessageBox = LabelMessage;
            Model.LoadOBJ("Toyota_Prius_LBW.obj"); //tree_obj.obj, uydu.obj, Toyota_Prius_LBW.obj
            posz = Model.OBJposz;

            //ModelTextures = new Texture();
            //ModelTextures.LoadGlTexture("brickwall.bmp", 0);

            Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, ambientLight);
            Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, diffuseLight);
            Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_SPECULAR, specularLight);
            Gl.glLighti(Gl.GL_LIGHT0, Gl.GL_SHININESS, 127);
            Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, lightpos0);

            Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_AMBIENT, ambientLight);
            Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_DIFFUSE, diffuseLight);
            Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_SPECULAR, specularLight);
            Gl.glLighti(Gl.GL_LIGHT1, Gl.GL_SHININESS, 127);
            Gl.glLightfv(Gl.GL_LIGHT1, Gl.GL_POSITION, lightpos1);

            Gl.glEnable(Gl.GL_LIGHTING);
            Gl.glEnable(Gl.GL_LIGHT0);
            Gl.glEnable(Gl.GL_LIGHT1);
            Gl.glEnable(Gl.GL_DEPTH_TEST);
            Gl.glEnable(Gl.GL_NORMALIZE);

            Gl.glCullFace(Gl.GL_BACK); 
            Gl.glEnable(Gl.GL_CULL_FACE);

            //Gl.glEnable(Gl.GL_POLYGON_SMOOTH);
            Gl.glHint(Gl.GL_POLYGON_SMOOTH_HINT, Gl.GL_NICEST);
            Gl.glShadeModel(Gl.GL_SMOOTH);
            Gl.glDisable(Gl.GL_BLEND);
        }

        private void MyKeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyCode)
            {
                case (Keys.A):
                    roty += step; break;
                case (Keys.D):
                    roty -= step; break;
                case (Keys.W):
                    rotx += step; break;
                case (Keys.S):
                    rotx -= step; break;
            }
            rotx = rotx % 360;
            roty = roty % 360;
            OpenGlControl.Refresh();
        }

        private void MyPreviewKwyDown(object sender, PreviewKeyDownEventArgs e)
        {
            switch (e.KeyData)
            {
                case (Keys.Up):
                    posz++; break;
                case (Keys.Down):
                    posz--; break;
                case (Keys.Left):
                    rotz += step; break;
                case (Keys.Right):
                    rotz -= step; break;
                default:
                    break;
            }
            rotz = rotz % 360;
            OpenGlControl.Refresh();
        }

        private void MyPaint(object sender, PaintEventArgs e)
        {
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);    // clear screen
            Gl.glEnable(Gl.GL_CULL_FACE);
            Gl.glLoadIdentity();

            Gl.glPushMatrix();
            Gl.glTranslatef(0, 0, posz);
            Gl.glRotatef(rotx, 1, 0, 0);
            Gl.glRotatef(roty, 0, 1, 0);
            Gl.glRotatef(rotz, 0, 0, 1);

            Model.ShowOBJ();
            Gl.glPopMatrix();
        }
     }
}
