use vulkanalia::prelude::v1_0::*;
use cgmath::{vec3, ElementWise};
use crate::vertex::{self, Facing};
use crate::scene::Scene;
use crate::primitives::drawable::Drawable;

#[derive(Clone, Debug, PartialEq)]
pub struct Quad{
    pub pos1: vertex::Vec3,
    pub pos2: vertex::Vec3,
    pub pos3: vertex::Vec3,
    pub pos4: vertex::Vec3,
    pub raster_pos: cgmath::Vector2<u32>,
    pub size: cgmath::Vector2<u32>,
    pub volume_index: u32,
    pub facing: Facing,
}

impl Drawable for Quad {
    fn draw(& self, topology: &vk::PrimitiveTopology, start_index: usize, scene: &mut Scene) {
        if *topology == vk::PrimitiveTopology::TRIANGLE_LIST {
            // 0 top left far
            scene.rt_vertices.push(vertex::RTVertex::new(
                vec3(self.pos1.x as f32, self.pos1.y as f32, self.pos1.z as f32),
                self.raster_pos + self.size.mul_element_wise(cgmath::Vector2 {x: 0, y: 0}),
                self.volume_index,
                self.facing,
                self.raster_pos,
                self.raster_pos + self.size.mul_element_wise(cgmath::Vector2 {x: 1, y: 1}),
            ));
            // 1 top right far
            scene.rt_vertices.push(vertex::RTVertex::new(
                vec3(self.pos2.x as f32, self.pos2.y as f32, self.pos2.z as f32),
                self.raster_pos + self.size.mul_element_wise(cgmath::Vector2 {x: 0, y: 1}),
                self.volume_index,
                self.facing,
                self.raster_pos,
                self.raster_pos + self.size.mul_element_wise(cgmath::Vector2 {x: 1, y: 1}),
            ));
            // 2 top left near
            scene.rt_vertices.push(vertex::RTVertex::new(
                vec3(self.pos3.x as f32, self.pos3.y as f32, self.pos3.z as f32),
                self.raster_pos + self.size.mul_element_wise(cgmath::Vector2 {x: 1, y: 1}),
                self.volume_index,
                self.facing,
                self.raster_pos,
                self.raster_pos + self.size.mul_element_wise(cgmath::Vector2 {x: 1, y: 1}),
            ));
            // 3 top right near
            scene.rt_vertices.push(vertex::RTVertex::new(
                vec3(self.pos4.x as f32, self.pos4.y as f32, self.pos4.z as f32),
                self.raster_pos + self.size.mul_element_wise(cgmath::Vector2 {x: 1, y: 0}),
                self.volume_index,
                self.facing,
                self.raster_pos,
                self.raster_pos + self.size.mul_element_wise(cgmath::Vector2 {x: 1, y: 1}),
            ));
            
            // change node order while preserving texture coordinates
            if [Facing::Top].contains(&self.facing) {
                scene.indices_rt.push(start_index as u32 + 0);
                scene.indices_rt.push(start_index as u32 + 1);
                scene.indices_rt.push(start_index as u32 + 2);

                scene.indices_rt.push(start_index as u32 + 2);
                scene.indices_rt.push(start_index as u32 + 3);
                scene.indices_rt.push(start_index as u32 + 0);
            } else {
                scene.indices_rt.push(start_index as u32 + 2);
                scene.indices_rt.push(start_index as u32 + 1);
                scene.indices_rt.push(start_index as u32 + 0);

                scene.indices_rt.push(start_index as u32 + 0);
                scene.indices_rt.push(start_index as u32 + 3);
                scene.indices_rt.push(start_index as u32 + 2);
            }       
        }
    }
}