use std::{borrow::BorrowMut, num::NonZeroU32};

use euclid::Size2D;
use femtovg::Canvas;
use ndarray::{Array2, ArrayView1};
use surfman::{
    Connection, Context, ContextAttributeFlags, ContextAttributes, ContextDescriptor,
    NativeConnection, NativeContext, SurfaceAccess, SurfaceType, Device, GLVersion,
};

pub fn meshgrid<T>(x: ArrayView1<T>, y: ArrayView1<T>) -> (Array2<T>, Array2<T>)
where
    T: Clone,
{
    let shape = (y.len(), x.len());
    println!("shape: {:?}", shape);
    let xx = Array2::from_shape_fn(shape, |(_, j)| x[j].clone());
    let yy = Array2::from_shape_fn(shape, |(i, _)| y[i].clone());
    (xx, yy)
}

pub fn creator() {
    let connection = Connection::new().unwrap();
    let adapter = connection.create_adapter().unwrap();
    let mut device = connection.create_device(&adapter).unwrap();
    let api = device.gl_api();
    let descriptor = device.create_context_descriptor(&ContextAttributes {
        version: GLVersion::new(3, 3),
        flags: ContextAttributeFlags::empty(),
    }).unwrap();

    let mut context = device.create_context(&descriptor, None).unwrap();
    let mut surface = device
        .create_surface(
            &context,
            SurfaceAccess::GPUOnly,
            SurfaceType::Generic {
                size: Size2D::new(500, 500),
            },
        )
        .unwrap();

    let surface_info = device.surface_info(&surface);
    device
        .bind_surface_to_context(&mut context, surface)
        .expect("Failed to bind surface to context");
    device.make_context_current(&context).unwrap();
    use femtovg::renderer::OpenGl;
    static LOAD_FN: fn(&str) -> *const std::ffi::c_void = |s| epoxy::get_proc_addr(s) as *const _;
    let (mut renderer, fbo) = unsafe {
        let renderer = OpenGl::new_from_function(LOAD_FN).expect("Cannot create renderer");
        let fbo =
            glow::NativeFramebuffer(NonZeroU32::new(surface_info.framebuffer_object).unwrap());
        (renderer, fbo)
    };

    renderer.set_screen_target(Some(fbo));
    device.destroy_context(&mut context);
}
