use std::ffi::c_void;

use std::ffi::c_char;

use crate::c::vulkan::{constants::{enums::physical_device_type::VkPhysicalDeviceType, flags::{queue::VkQueueFlagBits, sample_count::VkSampleCountFlagBits}}, types::{base::{VkBool32, VkDeviceSize}, image::VkExtent3D, memory::{VkMemoryHeap, VkMemoryType}}};


#[repr(transparent)]
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct VkPhysicalDevice(pub *mut c_void);

#[repr(C)]
pub struct VkPhysicalDeviceProperties {
    pub api_version: u32,
    pub driver_version: u32,
    pub vendor_i_d: u32,
    pub device_i_d: u32,
    pub device_type: VkPhysicalDeviceType,
    pub device_name: c_char,
    pub pipeline_cache_u_u_i_d: u8,
    pub limits: VkPhysicalDeviceLimits,
    pub sparse_properties: VkPhysicalDeviceSparseProperties,
}

#[repr(C)]
pub struct VkPhysicalDeviceSparseProperties {
    pub residency_standard2_d_block_shape: VkBool32,
    pub residency_standard2_d_multisample_block_shape: VkBool32,
    pub residency_standard3_d_block_shape: VkBool32,
    pub residency_aligned_mip_size: VkBool32,
    pub residency_non_resident_strict: VkBool32,
}

#[repr(C)]
pub struct VkPhysicalDeviceFeatures {
    pub robust_buffer_access: VkBool32,
    pub full_draw_index_uint32: VkBool32,
    pub image_cube_array: VkBool32,
    pub independent_blend: VkBool32,
    pub geometry_shader: VkBool32,
    pub tessellation_shader: VkBool32,
    pub sample_rate_shading: VkBool32,
    pub dual_src_blend: VkBool32,
    pub logic_op: VkBool32,
    pub multi_draw_indirect: VkBool32,
    pub draw_indirect_first_instance: VkBool32,
    pub depth_clamp: VkBool32,
    pub depth_bias_clamp: VkBool32,
    pub fill_mode_non_solid: VkBool32,
    pub depth_bounds: VkBool32,
    pub wide_lines: VkBool32,
    pub large_points: VkBool32,
    pub alpha_to_one: VkBool32,
    pub multi_viewport: VkBool32,
    pub sampler_anisotropy: VkBool32,
    pub texture_compression_e_t_c2: VkBool32,
    pub texture_compression_a_s_t_c__l_d_r: VkBool32,
    pub texture_compression_b_c: VkBool32,
    pub occlusion_query_precise: VkBool32,
    pub pipeline_statistics_query: VkBool32,
    pub vertex_pipeline_stores_and_atomics: VkBool32,
    pub fragment_stores_and_atomics: VkBool32,
    pub shader_tessellation_and_geometry_point_size: VkBool32,
    pub shader_image_gather_extended: VkBool32,
    pub shader_storage_image_extended_formats: VkBool32,
    pub shader_storage_image_multisample: VkBool32,
    pub shader_storage_image_read_without_format: VkBool32,
    pub shader_storage_image_write_without_format: VkBool32,
    pub shader_uniform_buffer_array_dynamic_indexing: VkBool32,
    pub shader_sampled_image_array_dynamic_indexing: VkBool32,
    pub shader_storage_buffer_array_dynamic_indexing: VkBool32,
    pub shader_storage_image_array_dynamic_indexing: VkBool32,
    pub shader_clip_distance: VkBool32,
    pub shader_cull_distance: VkBool32,
    pub shader_float64: VkBool32,
    pub shader_int64: VkBool32,
    pub shader_int16: VkBool32,
    pub shader_resource_residency: VkBool32,
    pub shader_resource_min_lod: VkBool32,
    pub sparse_binding: VkBool32,
    pub sparse_residency_buffer: VkBool32,
    pub sparse_residency_image2_d: VkBool32,
    pub sparse_residency_image3_d: VkBool32,
    pub sparse_residency2_samples: VkBool32,
    pub sparse_residency4_samples: VkBool32,
    pub sparse_residency8_samples: VkBool32,
    pub sparse_residency16_samples: VkBool32,
    pub sparse_residency_aliased: VkBool32,
    pub variable_multisample_rate: VkBool32,
    pub inherited_queries: VkBool32,
}

#[repr(C)]
pub struct VkPhysicalDeviceMemoryProperties {
    pub memory_type_count: u32,
    pub memory_types: VkMemoryType,
    pub memory_heap_count: u32,
    pub memory_heaps: VkMemoryHeap,
}

#[repr(C)]
pub struct VkPhysicalDeviceLimits {
    pub max_image_dimension1_d: u32,
    pub max_image_dimension2_d: u32,
    pub max_image_dimension3_d: u32,
    pub max_image_dimension_cube: u32,
    pub max_image_array_layers: u32,
    pub max_texel_buffer_elements: u32,
    pub max_uniform_buffer_range: u32,
    pub max_storage_buffer_range: u32,
    pub max_push_constants_size: u32,
    pub max_memory_allocation_count: u32,
    pub max_sampler_allocation_count: u32,
    pub buffer_image_granularity: VkDeviceSize,
    pub sparse_address_space_size: VkDeviceSize,
    pub max_bound_descriptor_sets: u32,
    pub max_per_stage_descriptor_samplers: u32,
    pub max_per_stage_descriptor_uniform_buffers: u32,
    pub max_per_stage_descriptor_storage_buffers: u32,
    pub max_per_stage_descriptor_sampled_images: u32,
    pub max_per_stage_descriptor_storage_images: u32,
    pub max_per_stage_descriptor_input_attachments: u32,
    pub max_per_stage_resources: u32,
    pub max_descriptor_set_samplers: u32,
    pub max_descriptor_set_uniform_buffers: u32,
    pub max_descriptor_set_uniform_buffers_dynamic: u32,
    pub max_descriptor_set_storage_buffers: u32,
    pub max_descriptor_set_storage_buffers_dynamic: u32,
    pub max_descriptor_set_sampled_images: u32,
    pub max_descriptor_set_storage_images: u32,
    pub max_descriptor_set_input_attachments: u32,
    pub max_vertex_input_attributes: u32,
    pub max_vertex_input_bindings: u32,
    pub max_vertex_input_attribute_offset: u32,
    pub max_vertex_input_binding_stride: u32,
    pub max_vertex_output_components: u32,
    pub max_tessellation_generation_level: u32,
    pub max_tessellation_patch_size: u32,
    pub max_tessellation_control_per_vertex_input_components: u32,
    pub max_tessellation_control_per_vertex_output_components: u32,
    pub max_tessellation_control_per_patch_output_components: u32,
    pub max_tessellation_control_total_output_components: u32,
    pub max_tessellation_evaluation_input_components: u32,
    pub max_tessellation_evaluation_output_components: u32,
    pub max_geometry_shader_invocations: u32,
    pub max_geometry_input_components: u32,
    pub max_geometry_output_components: u32,
    pub max_geometry_output_vertices: u32,
    pub max_geometry_total_output_components: u32,
    pub max_fragment_input_components: u32,
    pub max_fragment_output_attachments: u32,
    pub max_fragment_dual_src_attachments: u32,
    pub max_fragment_combined_output_resources: u32,
    pub max_compute_shared_memory_size: u32,
    pub max_compute_work_group_count: [u32; 3],
    pub max_compute_work_group_invocations: [u32; 3],
    pub max_compute_work_group_size: [u32; 3],
    pub sub_pixel_precision_bits: [u32; 3],
    pub sub_texel_precision_bits: [u32; 3],
    pub mipmap_precision_bits: [u32; 3],
    pub max_draw_indexed_index_value: [u32; 3],
    pub max_draw_indirect_count: [u32; 3],
    pub max_sampler_lod_bias: [f32; 3],
    pub max_sampler_anisotropy: [f32; 3],
    pub max_viewports: [u32; 3],
    pub max_viewport_dimensions: [u32; 2],
    pub viewport_bounds_range: [f32; 2],
    pub viewport_sub_pixel_bits: [u32; 2],
    pub min_memory_map_alignment: [usize; 2],
    pub min_texel_buffer_offset_alignment: [VkDeviceSize; 2],
    pub min_uniform_buffer_offset_alignment: [VkDeviceSize; 2],
    pub min_storage_buffer_offset_alignment: [VkDeviceSize; 2],
    pub min_texel_offset: [i32; 2],
    pub max_texel_offset: [u32; 2],
    pub min_texel_gather_offset: [i32; 2],
    pub max_texel_gather_offset: [u32; 2],
    pub min_interpolation_offset: [f32; 2],
    pub max_interpolation_offset: [f32; 2],
    pub sub_pixel_interpolation_offset_bits: [u32; 2],
    pub max_framebuffer_width: [u32; 2],
    pub max_framebuffer_height: [u32; 2],
    pub max_framebuffer_layers: [u32; 2],
    pub framebuffer_color_sample_counts: [VkSampleCountFlagBits; 2],
    pub framebuffer_depth_sample_counts: [VkSampleCountFlagBits; 2],
    pub framebuffer_stencil_sample_counts: [VkSampleCountFlagBits; 2],
    pub framebuffer_no_attachments_sample_counts: [VkSampleCountFlagBits; 2],
    pub max_color_attachments: [u32; 2],
    pub sampled_image_color_sample_counts: [VkSampleCountFlagBits; 2],
    pub sampled_image_integer_sample_counts: [VkSampleCountFlagBits; 2],
    pub sampled_image_depth_sample_counts: [VkSampleCountFlagBits; 2],
    pub sampled_image_stencil_sample_counts: [VkSampleCountFlagBits; 2],
    pub storage_image_sample_counts: [VkSampleCountFlagBits; 2],
    pub max_sample_mask_words: [u32; 2],
    pub timestamp_compute_and_graphics: [VkBool32; 2],
    pub timestamp_period: [f32; 2],
    pub max_clip_distances: [u32; 2],
    pub max_cull_distances: [u32; 2],
    pub max_combined_clip_and_cull_distances: [u32; 2],
    pub discrete_queue_priorities: [u32; 2],
    pub point_size_range: [f32; 2],
    pub line_width_range: [f32; 2],
    pub point_size_granularity: [f32; 2],
    pub line_width_granularity: [f32; 2],
    pub strict_lines: [VkBool32; 2],
    pub standard_sample_locations: [VkBool32; 2],
    pub optimal_buffer_copy_offset_alignment: [VkDeviceSize; 2],
    pub optimal_buffer_copy_row_pitch_alignment: [VkDeviceSize; 2],
    pub non_coherent_atom_size: [VkDeviceSize; 2],
}

#[repr(C)]
pub struct VkQueueFamilyProperties {
    pub queue_flags: VkQueueFlagBits,
    pub queue_count: u32,
    pub timestamp_valid_bits: u32,
    pub min_image_transfer_granularity: VkExtent3D,
}

