
#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(unused_mut)]

extern crate cgmath;
extern crate image;
extern crate nalgebra as na;
extern crate rand;
extern crate sfml;
extern crate time;

use sfml::graphics::*;
use sfml::graphics::{
    Color, RenderTarget, RenderWindow,
};
use sfml::system::*;
use sfml::window::{Key, Style};
use sfml::window::mouse::*;
use sfml::window::mouse;

use vulkano::sync;
use std::sync::Arc;
use std::{fs, mem, iter, ptr};
use std::path::PathBuf;
use std::result;

use crate::input::Input;
use crate::slider::Slider;
use crate::timer::Timer;
use na::DimAdd;
use std::time::{SystemTime, Duration};
use std::ffi::CStr;
use std::ptr::write;
use vulkano::buffer::{BufferUsage, CpuAccessibleBuffer, DeviceLocalBuffer, ImmutableBuffer, BufferAccess};
use vulkano::command_buffer::AutoCommandBufferBuilder;
use vulkano::descriptor::descriptor_set::PersistentDescriptorSet;
use vulkano::device::{Device, DeviceExtensions};
use vulkano::instance::{Instance, InstanceExtensions, PhysicalDevice};
use vulkano::pipeline::ComputePipeline;
use vulkano::descriptor::pipeline_layout::PipelineLayoutAbstract;
use vulkano::sync::GpuFuture;
use shaderc::CompileOptions;
use shade_runner::CompileError;
use winit::{EventsLoop, WindowBuilder, WindowEvent, Event, DeviceEvent, VirtualKeyCode, ElementState};
use winit::dpi::LogicalSize;
use vulkano_win::VkSurfaceBuild;
use sprite::Sprite;

mod slider;
mod timer;
mod input;
mod vkprocessor;
mod util;
mod button;
mod vertex_2d;
mod vertex_3d;
mod sprite;

fn main() {

    let instance = {
        let extensions = vulkano_win::required_extensions();
        Instance::new(None, &extensions, None).unwrap()
    };

    let mut events_loop = EventsLoop::new();
    let mut surface = WindowBuilder::new()
        .with_dimensions(LogicalSize::from((800, 800)))
        .build_vk_surface(&events_loop, instance.clone()).unwrap();
    let mut window = surface.window();

    let mut processor = vkprocessor::VkProcessor::new(&instance, &surface);
    processor.compile_kernel(String::from("simple-edge.compute"));
    processor.compile_shaders(String::from("simple_texture"), &surface);
    processor.load_buffers(String::from("background.jpg"));
    processor.create_swapchain(&surface);

    let mut timer = Timer::new();
    let mut frame_future = Box::new(sync::now(processor.device.clone())) as Box<dyn GpuFuture>;

    let step_size: f32 = 0.005;
    let mut elapsed_time: f32;
    let mut delta_time: f32;
    let mut accumulator_time: f32 = 0.0;
    let mut current_time: f32 = timer.elap_time();

    let mut mouse_xy = Vector2i::new(0,0);


    Sprite::new_with_color((0.,0.), (0,0), (0.,0.,0.,0.));


    while let Some(p) = window.get_position() {

        elapsed_time = timer.elap_time();
        delta_time = elapsed_time - current_time;
        current_time = elapsed_time;
        if delta_time > 0.02 {
            delta_time = 0.02;
        }
        accumulator_time += delta_time;

        while (accumulator_time - step_size) >= step_size {
            accumulator_time -= step_size;
        }

        let mut exit = false;
        events_loop.poll_events(|event| {
            match event {
                Event::WindowEvent { event: WindowEvent::CloseRequested, .. } =>
                    {
                        exit = true;
                    },
                Event::WindowEvent { event: WindowEvent::Resized(_), .. } => {
                    processor.recreate_swapchain(&surface);
                },
                Event::DeviceEvent { event: DeviceEvent::Key(keyboard_input), .. } => {

                    match keyboard_input.virtual_keycode.unwrap() {
                        VirtualKeyCode::A => {
                            if keyboard_input.state == ElementState::Pressed {
                                processor.save_edges_image();
                            }
                        }
                        _ => ()
                    }
                },
//                Event::DeviceEvent { event: DeviceEvent::Button(mouse_input), .. } => {
//                    mouse_xy.x
//                },
                _ => ()
            }
        });

        if exit {
            return;
        }


        frame_future = processor.run(&surface, frame_future);
    }
}

































