{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE ScopedTypeVariables, RankNTypes, TypeApplications #-}
{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ViewPatterns #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}

module Gpu.Vulkan.ImageView (

	-- * CREATE

	create, null, unsafeRecreate, unsafeRecreate', I, CreateInfo(..),

	-- ** Manage Multiple Image View

	group, create', unsafeDestroy, lookup, Group,
	
	-- * ENUM

	module Gpu.Vulkan.ImageView.Enum

	) where

import Prelude hiding (null, lookup)
import GHC.TypeLits
import Foreign.Storable.PeekPoke
import Control.Exception
import Data.TypeLevel.Maybe qualified as TMaybe
import Data.TypeLevel.ParMaybe qualified as TPMaybe
import Data.TypeLevel.Tuple.Uncurry

import Gpu.Vulkan.ImageView.Type
import Gpu.Vulkan.ImageView.Enum

import qualified Gpu.Vulkan.TypeEnum as T
import qualified Gpu.Vulkan.AllocationCallbacks as AllocationCallbacks
import qualified Gpu.Vulkan.AllocationCallbacks.Type as AllocationCallbacks
import qualified Gpu.Vulkan.Device.Type as Device
import qualified Gpu.Vulkan.Component as Component
import qualified Gpu.Vulkan.Image.Type as Image
import qualified Gpu.Vulkan.Image.Middle as Image.M
import qualified Gpu.Vulkan.ImageView.Middle as M

data CreateInfo n sm si nm ifmt (ivfmt :: T.Format) = CreateInfo {
	forall (n :: Maybe (*)) sm si (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
CreateInfo n sm si nm ifmt ivfmt -> M n
createInfoNext :: TMaybe.M n,
	forall (n :: Maybe (*)) sm si (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
CreateInfo n sm si nm ifmt ivfmt -> CreateFlags
createInfoFlags :: CreateFlags,
	forall (n :: Maybe (*)) sm si (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
CreateInfo n sm si nm ifmt ivfmt -> Binded sm si nm ifmt
createInfoImage :: Image.Binded sm si nm ifmt,
	forall (n :: Maybe (*)) sm si (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
CreateInfo n sm si nm ifmt ivfmt -> Type
createInfoViewType :: Type,
	forall (n :: Maybe (*)) sm si (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
CreateInfo n sm si nm ifmt ivfmt -> Mapping
createInfoComponents :: Component.Mapping,
	forall (n :: Maybe (*)) sm si (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
CreateInfo n sm si nm ifmt ivfmt -> SubresourceRange
createInfoSubresourceRange :: Image.M.SubresourceRange }

createInfoToMiddle :: forall n si sm nm ifmt ivfmt . T.FormatToValue ivfmt =>
	CreateInfo n si sm nm ifmt ivfmt -> M.CreateInfo n
createInfoToMiddle :: forall (n :: Maybe (*)) si sm (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
FormatToValue ivfmt =>
CreateInfo n si sm nm ifmt ivfmt -> CreateInfo n
createInfoToMiddle CreateInfo {
	createInfoNext :: forall (n :: Maybe (*)) sm si (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
CreateInfo n sm si nm ifmt ivfmt -> M n
createInfoNext = M n
mnxt,
	createInfoFlags :: forall (n :: Maybe (*)) sm si (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
CreateInfo n sm si nm ifmt ivfmt -> CreateFlags
createInfoFlags = CreateFlags
flgs,
	createInfoImage :: forall (n :: Maybe (*)) sm si (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
CreateInfo n sm si nm ifmt ivfmt -> Binded sm si nm ifmt
createInfoImage = Image.Binded I
img,
	createInfoViewType :: forall (n :: Maybe (*)) sm si (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
CreateInfo n sm si nm ifmt ivfmt -> Type
createInfoViewType = Type
tp,
	createInfoComponents :: forall (n :: Maybe (*)) sm si (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
CreateInfo n sm si nm ifmt ivfmt -> Mapping
createInfoComponents = Mapping
cps,
	createInfoSubresourceRange :: forall (n :: Maybe (*)) sm si (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
CreateInfo n sm si nm ifmt ivfmt -> SubresourceRange
createInfoSubresourceRange = SubresourceRange
srr } = M.CreateInfo {
	createInfoNext :: M n
M.createInfoNext = M n
mnxt,
	createInfoFlags :: CreateFlags
M.createInfoFlags = CreateFlags
flgs,
	createInfoImage :: I
M.createInfoImage = I
img,
	createInfoViewType :: Type
M.createInfoViewType = Type
tp,
	createInfoFormat :: Format
M.createInfoFormat = Format
fmt,
	createInfoComponents :: Mapping
M.createInfoComponents = Mapping
cps,
	createInfoSubresourceRange :: SubresourceRange
M.createInfoSubresourceRange = SubresourceRange
srr }
	where fmt :: Format
fmt = forall (t :: Format). FormatToValue t => Format
T.formatToValue @ivfmt

create :: (
	WithPoked (TMaybe.M mn), T.FormatToValue ivfmt,
	AllocationCallbacks.ToMiddle mac ) =>
	Device.D sd -> CreateInfo mn sm si nm ifmt ivfmt ->
	TPMaybe.M (U2 AllocationCallbacks.A) mac ->
	(forall s . I nm ivfmt s -> IO a) -> IO a
create :: forall (mn :: Maybe (*)) (ivfmt :: Format) (mac :: Maybe (*, *)) sd
       sm si (nm :: Symbol) (ifmt :: Format) a.
(WithPoked (M mn), FormatToValue ivfmt, ToMiddle mac) =>
D sd
-> CreateInfo mn sm si nm ifmt ivfmt
-> M (U2 A) mac
-> (forall s. I nm ivfmt s -> IO a)
-> IO a
create (Device.D D
d) CreateInfo mn sm si nm ifmt ivfmt
ci (M (U2 A) mac -> M A (Snd mac)
forall (msa :: Maybe (*, *)).
ToMiddle msa =>
M (U2 A) msa -> M A (Snd msa)
AllocationCallbacks.toMiddle -> M A (Snd mac)
mac) forall s. I nm ivfmt s -> IO a
f = IO I -> (I -> IO ()) -> (I -> IO a) -> IO a
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket
	(D -> CreateInfo mn -> M A (Snd mac) -> IO I
forall (mn :: Maybe (*)) (mc :: Maybe (*)).
WithPoked (M mn) =>
D -> CreateInfo mn -> M A mc -> IO I
M.create D
d (CreateInfo mn sm si nm ifmt ivfmt -> CreateInfo mn
forall (n :: Maybe (*)) si sm (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
FormatToValue ivfmt =>
CreateInfo n si sm nm ifmt ivfmt -> CreateInfo n
createInfoToMiddle CreateInfo mn sm si nm ifmt ivfmt
ci) M A (Snd mac)
mac)
	(\I
i -> D -> I -> M A (Snd mac) -> IO ()
forall (md :: Maybe (*)). D -> I -> M A md -> IO ()
M.destroy D
d I
i M A (Snd mac)
mac) (I nm ivfmt Any -> IO a
forall s. I nm ivfmt s -> IO a
f (I nm ivfmt Any -> IO a) -> (I -> I nm ivfmt Any) -> I -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. I -> I nm ivfmt Any
forall (nm :: Symbol) (fmt :: Format) si. I -> I nm fmt si
I)

null :: IO (I nm ivfmt s)
null :: forall (nm :: Symbol) (ivfmt :: Format) s. IO (I nm ivfmt s)
null = I -> I nm ivfmt s
forall (nm :: Symbol) (fmt :: Format) si. I -> I nm fmt si
I (I -> I nm ivfmt s) -> IO I -> IO (I nm ivfmt s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO I
M.null

group ::
	AllocationCallbacks.ToMiddle ma =>
	Device.D sd -> TPMaybe.M (U2 AllocationCallbacks.A) ma ->
	(forall s . Group sd ma s k nm ivfmt -> IO a) -> IO a
group :: forall (ma :: Maybe (*, *)) sd k (nm :: Symbol) (ivfmt :: Format)
       a.
ToMiddle ma =>
D sd
-> M (U2 A) ma
-> (forall s. Group sd ma s k nm ivfmt -> IO a)
-> IO a
group dvc :: D sd
dvc@(Device.D D
d) ma :: M (U2 A) ma
ma@(M (U2 A) ma -> M A (Snd ma)
forall (msa :: Maybe (*, *)).
ToMiddle msa =>
M (U2 A) msa -> M A (Snd msa)
AllocationCallbacks.toMiddle -> M A (Snd ma)
mac) forall s. Group sd ma s k nm ivfmt -> IO a
f =
	D -> M A (Snd ma) -> (forall s. Group s k -> IO a) -> IO a
forall (mc :: Maybe (*)) k a.
D -> M A mc -> (forall s. Group s k -> IO a) -> IO a
M.group D
d M A (Snd ma)
mac ((forall s. Group s k -> IO a) -> IO a)
-> (forall s. Group s k -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ Group sd ma s k nm ivfmt -> IO a
forall s. Group sd ma s k nm ivfmt -> IO a
f (Group sd ma s k nm ivfmt -> IO a)
-> (Group s k -> Group sd ma s k nm ivfmt) -> Group s k -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. D sd -> M (U2 A) ma -> Group s k -> Group sd ma s k nm ivfmt
forall sd (ma :: Maybe (*, *)) s k (nm :: Symbol)
       (ivfmt :: Format).
D sd -> M (U2 A) ma -> Group s k -> Group sd ma s k nm ivfmt
Group D sd
dvc M (U2 A) ma
ma

data Group sd ma s k (nm :: Symbol) (ivfmt :: T.Format) = Group
	(Device.D sd) (TPMaybe.M (U2 AllocationCallbacks.A) ma) (M.Group s k)

create' :: (
	Ord k, WithPoked (TMaybe.M mn), T.FormatToValue ivfmt,
	AllocationCallbacks.ToMiddle ma ) =>
	Group sd ma smng k nm ivfmt -> k ->
	CreateInfo mn sm si nm ifmt ivfmt ->
	IO (Either String (I nm ivfmt smng))
create' :: forall k (mn :: Maybe (*)) (ivfmt :: Format) (ma :: Maybe (*, *))
       sd smng (nm :: Symbol) sm si (ifmt :: Format).
(Ord k, WithPoked (M mn), FormatToValue ivfmt, ToMiddle ma) =>
Group sd ma smng k nm ivfmt
-> k
-> CreateInfo mn sm si nm ifmt ivfmt
-> IO (Either String (I nm ivfmt smng))
create' (Group (Device.D D
d)
	(M (U2 A) ma -> M A (Snd ma)
forall (msa :: Maybe (*, *)).
ToMiddle msa =>
M (U2 A) msa -> M A (Snd msa)
AllocationCallbacks.toMiddle -> M A (Snd ma)
mac) Group smng k
mng) k
k CreateInfo mn sm si nm ifmt ivfmt
ci =
	(I -> I nm ivfmt smng
forall (nm :: Symbol) (fmt :: Format) si. I -> I nm fmt si
I (I -> I nm ivfmt smng)
-> Either String I -> Either String (I nm ivfmt smng)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Either String I -> Either String (I nm ivfmt smng))
-> IO (Either String I) -> IO (Either String (I nm ivfmt smng))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> D
-> Group smng k
-> k
-> CreateInfo mn
-> M A (Snd ma)
-> IO (Either String I)
forall k (mn :: Maybe (*)) sm (mc :: Maybe (*)).
(Ord k, WithPoked (M mn)) =>
D
-> Group sm k
-> k
-> CreateInfo mn
-> M A mc
-> IO (Either String I)
M.create' D
d Group smng k
mng k
k (CreateInfo mn sm si nm ifmt ivfmt -> CreateInfo mn
forall (n :: Maybe (*)) si sm (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
FormatToValue ivfmt =>
CreateInfo n si sm nm ifmt ivfmt -> CreateInfo n
createInfoToMiddle CreateInfo mn sm si nm ifmt ivfmt
ci) M A (Snd ma)
mac

unsafeDestroy :: (Ord k, AllocationCallbacks.ToMiddle ma) =>
	Group sd ma sm k nm ivfmt  -> k -> IO (Either String ())
unsafeDestroy :: forall k (ma :: Maybe (*, *)) sd sm (nm :: Symbol)
       (ivfmt :: Format).
(Ord k, ToMiddle ma) =>
Group sd ma sm k nm ivfmt -> k -> IO (Either String ())
unsafeDestroy (Group (Device.D D
d)
	(M (U2 A) ma -> M A (Snd ma)
forall (msa :: Maybe (*, *)).
ToMiddle msa =>
M (U2 A) msa -> M A (Snd msa)
AllocationCallbacks.toMiddle -> M A (Snd ma)
mac) Group sm k
mng) k
k =
	D -> Group sm k -> k -> M A (Snd ma) -> IO (Either String ())
forall k sm (mc :: Maybe (*)).
Ord k =>
D -> Group sm k -> k -> M A mc -> IO (Either String ())
M.destroy' D
d Group sm k
mng k
k M A (Snd ma)
mac

lookup :: Ord k => Group sd ma smng k nm ivfmt -> k -> IO (Maybe (I nm ivfmt smng))
lookup :: forall k sd (ma :: Maybe (*, *)) smng (nm :: Symbol)
       (ivfmt :: Format).
Ord k =>
Group sd ma smng k nm ivfmt -> k -> IO (Maybe (I nm ivfmt smng))
lookup (Group D sd
_ M (U2 A) ma
_ Group smng k
mng) k
k = (I -> I nm ivfmt smng
forall (nm :: Symbol) (fmt :: Format) si. I -> I nm fmt si
I (I -> I nm ivfmt smng) -> Maybe I -> Maybe (I nm ivfmt smng)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) (Maybe I -> Maybe (I nm ivfmt smng))
-> IO (Maybe I) -> IO (Maybe (I nm ivfmt smng))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Group smng k -> k -> IO (Maybe I)
forall k sm. Ord k => Group sm k -> k -> IO (Maybe I)
M.lookup Group smng k
mng k
k

unsafeRecreate :: (
	WithPoked (TMaybe.M mn), T.FormatToValue ivfmt,
	AllocationCallbacks.ToMiddle mac ) =>
	Device.D sd -> CreateInfo mn sm si nm ifmt ivfmt ->
	TPMaybe.M (U2 AllocationCallbacks.A) mac -> I nm ivfmt siv -> IO ()
unsafeRecreate :: forall (mn :: Maybe (*)) (ivfmt :: Format) (mac :: Maybe (*, *)) sd
       sm si (nm :: Symbol) (ifmt :: Format) siv.
(WithPoked (M mn), FormatToValue ivfmt, ToMiddle mac) =>
D sd
-> CreateInfo mn sm si nm ifmt ivfmt
-> M (U2 A) mac
-> I nm ivfmt siv
-> IO ()
unsafeRecreate (Device.D D
d) CreateInfo mn sm si nm ifmt ivfmt
ci
	(M (U2 A) mac -> M A (Snd mac)
forall (msa :: Maybe (*, *)).
ToMiddle msa =>
M (U2 A) msa -> M A (Snd msa)
AllocationCallbacks.toMiddle -> M A (Snd mac)
mac) (I I
i) =
	D -> CreateInfo mn -> M A (Snd mac) -> M A (Snd mac) -> I -> IO ()
forall (mn :: Maybe (*)) (mc :: Maybe (*)) (md :: Maybe (*)).
WithPoked (M mn) =>
D -> CreateInfo mn -> M A mc -> M A md -> I -> IO ()
M.recreate D
d (CreateInfo mn sm si nm ifmt ivfmt -> CreateInfo mn
forall (n :: Maybe (*)) si sm (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
FormatToValue ivfmt =>
CreateInfo n si sm nm ifmt ivfmt -> CreateInfo n
createInfoToMiddle CreateInfo mn sm si nm ifmt ivfmt
ci) M A (Snd mac)
mac M A (Snd mac)
mac I
i

unsafeRecreate' :: (
	WithPoked (TMaybe.M mn), T.FormatToValue ivfmt,
	AllocationCallbacks.ToMiddle mac ) =>
	Device.D sd -> CreateInfo mn sm si nm ifmt ivfmt ->
	TPMaybe.M (U2 AllocationCallbacks.A) mac -> I nm ivfmt siv -> IO a -> IO ()
unsafeRecreate' :: forall (mn :: Maybe (*)) (ivfmt :: Format) (mac :: Maybe (*, *)) sd
       sm si (nm :: Symbol) (ifmt :: Format) siv a.
(WithPoked (M mn), FormatToValue ivfmt, ToMiddle mac) =>
D sd
-> CreateInfo mn sm si nm ifmt ivfmt
-> M (U2 A) mac
-> I nm ivfmt siv
-> IO a
-> IO ()
unsafeRecreate' (Device.D D
d) CreateInfo mn sm si nm ifmt ivfmt
ci
	(M (U2 A) mac -> M A (Snd mac)
forall (msa :: Maybe (*, *)).
ToMiddle msa =>
M (U2 A) msa -> M A (Snd msa)
AllocationCallbacks.toMiddle -> M A (Snd mac)
mac) (I I
i) =
	D
-> CreateInfo mn
-> M A (Snd mac)
-> M A (Snd mac)
-> I
-> IO a
-> IO ()
forall (mn :: Maybe (*)) (mc :: Maybe (*)) (md :: Maybe (*)) a.
WithPoked (M mn) =>
D -> CreateInfo mn -> M A mc -> M A md -> I -> IO a -> IO ()
M.recreate' D
d (CreateInfo mn sm si nm ifmt ivfmt -> CreateInfo mn
forall (n :: Maybe (*)) si sm (nm :: Symbol) (ifmt :: Format)
       (ivfmt :: Format).
FormatToValue ivfmt =>
CreateInfo n si sm nm ifmt ivfmt -> CreateInfo n
createInfoToMiddle CreateInfo mn sm si nm ifmt ivfmt
ci) M A (Snd mac)
mac M A (Snd mac)
mac I
i