use std::sync::Arc;
use crate::canvas::*;
use crate::canvas::managed::handles::{CanvasFontHandle, CanvasImageHandle, CanvasTextureHandle, Handle};
use crate::canvas::canvas_frame::{Drawable, Eventable};
use crate::util::vertex::{VertexType, TextureVertex3D, Vertex3D};
use winit::event::{DeviceEvent, MouseButton, ElementState, Event, WindowEvent};

///
#[derive(Debug, Clone)]
pub struct Sprite {
    verts: VertexType,

    position: (f32, f32),
    size: (f32, f32),
    depth: f32,
    texture_handle: Arc<CanvasTextureHandle>,
}

/// Container class which implements drawable.
impl Sprite {
    fn generate_verts(position: (f32, f32), size: (f32, f32), depth: f32) -> Vec<TextureVertex3D> {
        vec![
            TextureVertex3D {
                v_position: [position.0, position.1, depth],                   // top left
                ti_position: [-0.0, -0.0],
            },
            TextureVertex3D {
                v_position: [position.0, position.1 + size.1, depth],          // bottom left
                ti_position: [-0.0, 1.0],
            },
            TextureVertex3D {
                v_position: [position.0 + size.0, position.1 + size.1, depth], // bottom right
                ti_position: [1.0, 1.0],
            },
            TextureVertex3D {
                v_position: [position.0, position.1, depth],                   // top left
                ti_position: [-0.0, -0.0],
            },
            TextureVertex3D {
                v_position: [position.0 + size.0, position.1 + size.1, depth], // bottom right
                ti_position: [1.0, 1.0],
            },
            TextureVertex3D {
                v_position: [position.0 + size.0, position.1, depth],          // top right
                ti_position: [1.0, -0.0],
            },
        ]
    }

    ///
    pub fn new(position: (f32, f32),
               size: (f32, f32),
               depth: u32,
               texture_handle: Arc<CanvasTextureHandle>) -> Sprite {
        let normalized_depth = (depth as f32 / 255.0);

        Sprite {
            verts: VertexType::TextureType(Sprite::generate_verts(position, size, normalized_depth), texture_handle.clone()),
            position: position,
            size: size,
            depth: normalized_depth,
            texture_handle: texture_handle.clone(),
        }
    }
}

impl Drawable for Sprite {
    fn get(&self) -> Vec<VertexType> {
        vec![
            VertexType::TextureType(
                Sprite::generate_verts(self.position, self.size, self.depth),
                self.texture_handle.clone())
        ]
    }
}

impl<T> Eventable<T> for Sprite {
    fn notify(&mut self, event: &Event<T>) -> () {
        match event {
            Event::WindowEvent { event: WindowEvent::MouseInput { device_id, state, button, modifiers }, .. } => {
                match button {
                    MouseButton::Left => {
                        if *state == ElementState::Pressed {
                            self.position = (self.position.0, self.position.1 + 0.1);
                        }
                    }
                    _ => {}
                }
            }
            _ => {}
        }
    }
}


