"""
box.py

Rysowanie stożka i podłoża wykorzystywanych w systemie cząsteczek fontanny.

Autor: Mahesh Venkitachalam
"""

import sys, random, math
import OpenGL
from OpenGL.GL import *
import numpy
import glutils

strVS = """
#version 330 core

in vec3 aVert;
uniform mat4 uMVMatrix;
uniform mat4 uPMatrix;
out vec4 vCol;

void main() {
    // zastosowanie transformacji
	gl_Position = uPMatrix * uMVMatrix * vec4(aVert, 1.0); 
    // ustawienie koloru
    vCol = vec4(0.8, 0.0, 0.0, 1.0);
}
"""

strFS = """
#version 330 core

in vec4 vCol;
out vec4 fragColor;

void main() {
    // użycie koloru wierzchołka
    fragColor = vCol;
}
"""


class Box:
    def __init__(self, side):
        self.side = side

        # ładowanie shaderów
        self.program = glutils.loadShaders(strVS, strFS)
        glUseProgram(self.program)
        
        s = side/2.0
        vertices = [
            -s, s, -s, 
             -s, -s, -s,
             s, s, -s,
             s, -s, -s,
             s, s, -s,
             -s, -s, -s,
             
             -s, s, s, 
             -s, -s, s,
             s, s, s,
             s, -s, s,
             s, s, s,
             -s, -s, s,

             -s, -s, s, 
             -s, -s, -s,
             s, -s, s,
             s, -s, -s,
             s, -s, s,
             -s, -s, -s,

             -s, s, s, 
             -s, s, -s,
             s, s, s,
             s, s, -s,
             s, s, s,
             -s, s, -s,

             -s, -s, s, 
             -s, -s, -s,
             -s, s, s,
             -s, s, -s,
             -s, s, s,
             -s, -s, -s,

             s, -s, s, 
             s, -s,-s,
             s, s, s,
             s, s, -s,
             s, s, s,
             s, -s,-s
             ]
                
        # ustawienie obiektu tablicy wierzchołków (VAO)
        self.vao = glGenVertexArrays(1)
        glBindVertexArray(self.vao)
        # ustawienie obiektów VBO
        vertexData = numpy.array(vertices, numpy.float32)
        self.vertexBuffer = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, self.vertexBuffer)
        glBufferData(GL_ARRAY_BUFFER, 4*len(vertexData), vertexData, 
                     GL_STATIC_DRAW)
        # włączenie tablic
        self.vertIndex = glGetAttribLocation(self.program, "aVert")
        glEnableVertexAttribArray(self.vertIndex)
        # ustawienie buforów 
        glBindBuffer(GL_ARRAY_BUFFER, self.vertexBuffer)
        glVertexAttribPointer(self.vertIndex, 3, GL_FLOAT, GL_FALSE, 0, None)
        # usunięcie dowiązania do VAO
        glBindVertexArray(0)

    def render(self, pMatrix, mvMatrix):

        # użycie shadera
        glUseProgram(self.program)
        
        # ustawienie macierzy rzutowania
        glUniformMatrix4fv(glGetUniformLocation(self.program, 'uPMatrix'), 
                           1, GL_FALSE, pMatrix)
        
        # ustawienie macierzy widoku modelu
        glUniformMatrix4fv(glGetUniformLocation(self.program, 'uMVMatrix'), 
                           1, GL_FALSE, mvMatrix)

        # wiązanie VAO
        glBindVertexArray(self.vao)
        # rysowanie
        glDrawArrays(GL_TRIANGLES, 0, 36)
        # usunięcie dowiązania do VAO
        glBindVertexArray(0)

