{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE ScopedTypeVariables, TypeApplications #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE KindSignatures, TypeOperators #-}
{-# LANGUAGE MultiParamTypeClasses, AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleContexts, FlexibleInstances, UndecidableInstances #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs -fno-warn-redundant-constraints #-}

module Gpu.Vulkan.DescriptorSet.BindingAndArrayElem (

	-- * IMAGE

	BindingAndArrayElemImage(..),
	BindingAndArrayElemImageWithImmutableSampler(..),

	-- * BUFFER VIEW

	BindingAndArrayElemBufferView(..) ) where

import GHC.TypeLits
import Data.Kind
import Data.TypeLevel.List qualified as TList
import Data.TypeLevel.Tuple.MapIndex qualified as TMapIndex

import Gpu.Vulkan.TypeEnum qualified as T
import Gpu.Vulkan.DescriptorSetLayout.Type qualified as Lyt

-- * IMAGE

-- ** Image

class BindingAndArrayElemImage
	(lbts :: [Lyt.BindingType])
	(iargs :: [(Symbol, T.Format)]) (i :: Nat) where
	bindingAndArrayElemImage :: Integral n => n -> n -> (n, n)

instance TList.IsPrefixOf iargs liargs =>
	BindingAndArrayElemImage
		('Lyt.Image (iarg ': liargs) : lbts) (iarg ': iargs) 0 where
	bindingAndArrayElemImage :: forall n. Integral n => n -> n -> (n, n)
bindingAndArrayElemImage n
b n
ae = (n
b, n
ae)

instance {-# OVERLAPPABLE #-}
	BindingAndArrayElemImage
		('Lyt.Image liargs ': lbts) (iarg ': iargs) (i - 1) =>
	BindingAndArrayElemImage
		('Lyt.Image (iarg ': liargs) ': lbts) (iarg ': iargs) i where
	bindingAndArrayElemImage :: forall n. Integral n => n -> n -> (n, n)
bindingAndArrayElemImage n
b n
ae = forall (lbts :: [BindingType]) (iargs :: [(Symbol, Format)])
       (i :: Nat) n.
(BindingAndArrayElemImage lbts iargs i, Integral n) =>
n -> n -> (n, n)
bindingAndArrayElemImage
		@('Lyt.Image liargs ': lbts) @(iarg ': iargs) @(i - 1) n
b (n
ae n -> n -> n
forall a. Num a => a -> a -> a
+ n
1)

instance {-# OVERLAPPABLE #-}
	BindingAndArrayElemImage ('Lyt.Image liargs : lbts) iargs i =>
	BindingAndArrayElemImage
		('Lyt.Image (liarg ': liargs) ': lbts) iargs i where
	bindingAndArrayElemImage :: forall n. Integral n => n -> n -> (n, n)
bindingAndArrayElemImage n
b n
a = forall (lbts :: [BindingType]) (iargs :: [(Symbol, Format)])
       (i :: Nat) n.
(BindingAndArrayElemImage lbts iargs i, Integral n) =>
n -> n -> (n, n)
bindingAndArrayElemImage
		@('Lyt.Image liargs : lbts) @iargs @i n
b (n
a n -> n -> n
forall a. Num a => a -> a -> a
+ n
1)

instance {-# OVERLAPPABLE #-}
	BindingAndArrayElemImage lbts iargs i =>
	BindingAndArrayElemImage (bt ': lbts) iargs i where
	bindingAndArrayElemImage :: forall n. Integral n => n -> n -> (n, n)
bindingAndArrayElemImage n
b n
_ =
		forall (lbts :: [BindingType]) (iargs :: [(Symbol, Format)])
       (i :: Nat) n.
(BindingAndArrayElemImage lbts iargs i, Integral n) =>
n -> n -> (n, n)
bindingAndArrayElemImage @lbts @iargs @i (n
b n -> n -> n
forall a. Num a => a -> a -> a
+ n
1) n
0

-- ** Image With Immutable Sampler

class BindingAndArrayElemImageWithImmutableSampler
	(lbts :: [Lyt.BindingType])
	(iargs :: [(Symbol, T.Format)]) (i :: Nat) where
	bindingAndArrayElemImageWithImmutableSampler :: Integral n => n -> n -> (n, n)

instance TList.IsPrefixOf iargs (TMapIndex.M0'1_3 liargs) =>
	BindingAndArrayElemImageWithImmutableSampler
		('Lyt.ImageSampler ('(nm, fmt, ss) ': liargs) : lbts) ('(nm, fmt) ': iargs) 0 where
	bindingAndArrayElemImageWithImmutableSampler :: forall n. Integral n => n -> n -> (n, n)
bindingAndArrayElemImageWithImmutableSampler n
b n
ae = (n
b, n
ae)

instance {-# OVERLAPPABLE #-}
	BindingAndArrayElemImageWithImmutableSampler
		('Lyt.ImageSampler liargs ': lbts) ('(nm, fmt) ': iargs) (i - 1) =>
	BindingAndArrayElemImageWithImmutableSampler
		('Lyt.ImageSampler ('(nm, fmt, ss) ': liargs) ': lbts) ('(nm, fmt) ': iargs) i where
	bindingAndArrayElemImageWithImmutableSampler :: forall n. Integral n => n -> n -> (n, n)
bindingAndArrayElemImageWithImmutableSampler n
b n
ae =
		forall (lbts :: [BindingType]) (iargs :: [(Symbol, Format)])
       (i :: Nat) n.
(BindingAndArrayElemImageWithImmutableSampler lbts iargs i,
 Integral n) =>
n -> n -> (n, n)
bindingAndArrayElemImageWithImmutableSampler
			@('Lyt.ImageSampler liargs ': lbts) @('(nm, fmt) ': iargs)
			@(i - 1) n
b (n
ae n -> n -> n
forall a. Num a => a -> a -> a
+ n
1)

instance {-# OVERLAPPABLE #-}
	BindingAndArrayElemImageWithImmutableSampler ('Lyt.ImageSampler liargs : lbts) iargs i =>
	BindingAndArrayElemImageWithImmutableSampler
		('Lyt.ImageSampler (liarg ': liargs) ': lbts) iargs i where
	bindingAndArrayElemImageWithImmutableSampler :: forall n. Integral n => n -> n -> (n, n)
bindingAndArrayElemImageWithImmutableSampler n
b n
a = forall (lbts :: [BindingType]) (iargs :: [(Symbol, Format)])
       (i :: Nat) n.
(BindingAndArrayElemImageWithImmutableSampler lbts iargs i,
 Integral n) =>
n -> n -> (n, n)
bindingAndArrayElemImageWithImmutableSampler
		@('Lyt.ImageSampler liargs : lbts) @iargs @i n
b (n
a n -> n -> n
forall a. Num a => a -> a -> a
+ n
1)

instance {-# OVERLAPPABLE #-}
	BindingAndArrayElemImageWithImmutableSampler lbts iargs i =>
	BindingAndArrayElemImageWithImmutableSampler (bt ': lbts) iargs i where
	bindingAndArrayElemImageWithImmutableSampler :: forall n. Integral n => n -> n -> (n, n)
bindingAndArrayElemImageWithImmutableSampler n
b n
_ =
		forall (lbts :: [BindingType]) (iargs :: [(Symbol, Format)])
       (i :: Nat) n.
(BindingAndArrayElemImageWithImmutableSampler lbts iargs i,
 Integral n) =>
n -> n -> (n, n)
bindingAndArrayElemImageWithImmutableSampler @lbts @iargs @i (n
b n -> n -> n
forall a. Num a => a -> a -> a
+ n
1) n
0

-- * BUFFER VIEW

class BindingAndArrayElemBufferView
	(bt :: [Lyt.BindingType]) (bvargs :: [(Symbol, Type)]) (i :: Nat) where
	bindingAndArrayElemBufferView :: Integral n => n -> n -> (n, n)

instance TList.IsPrefixOf bvargs lbvargs => BindingAndArrayElemBufferView
		('Lyt.BufferView (bvarg ': lbvargs) ': lbts)
		(bvarg ': bvargs) 0 where
	bindingAndArrayElemBufferView :: forall n. Integral n => n -> n -> (n, n)
bindingAndArrayElemBufferView n
b n
a = (n
b, n
a)

instance {-# OVERLAPPABLE #-}
	BindingAndArrayElemBufferView
		('Lyt.BufferView lbvargs ': lbts) (bvarg ': bvargs) (i - 1) =>
	BindingAndArrayElemBufferView
		('Lyt.BufferView (bvarg ': lbvargs) ': lbts)
		(bvarg ': bvargs) i where
	bindingAndArrayElemBufferView :: forall n. Integral n => n -> n -> (n, n)
bindingAndArrayElemBufferView n
b n
a = forall (bt :: [BindingType]) (bvargs :: [(Symbol, *)]) (i :: Nat)
       n.
(BindingAndArrayElemBufferView bt bvargs i, Integral n) =>
n -> n -> (n, n)
bindingAndArrayElemBufferView
		@('Lyt.BufferView lbvargs ': lbts) @(bvarg ': bvargs) @(i - 1)
		n
b n
a

instance {-# OVERLAPPABLE #-} BindingAndArrayElemBufferView
	('Lyt.BufferView lbvargs ': lbts) bvargs i =>
	BindingAndArrayElemBufferView
		('Lyt.BufferView (bvarg ': lbvargs) ': lbts) bvargs i where
	bindingAndArrayElemBufferView :: forall n. Integral n => n -> n -> (n, n)
bindingAndArrayElemBufferView n
b n
a = forall (bt :: [BindingType]) (bvargs :: [(Symbol, *)]) (i :: Nat)
       n.
(BindingAndArrayElemBufferView bt bvargs i, Integral n) =>
n -> n -> (n, n)
bindingAndArrayElemBufferView
		@('Lyt.BufferView lbvargs ': lbts) @bvargs @i n
b (n
a n -> n -> n
forall a. Num a => a -> a -> a
+ n
1)

instance {-# OVERLAPPABLE #-} BindingAndArrayElemBufferView lbts bvargs i =>
	BindingAndArrayElemBufferView
		(bt ': lbts) bvargs i where
	bindingAndArrayElemBufferView :: forall n. Integral n => n -> n -> (n, n)
bindingAndArrayElemBufferView n
b n
_a =
		forall (bt :: [BindingType]) (bvargs :: [(Symbol, *)]) (i :: Nat)
       n.
(BindingAndArrayElemBufferView bt bvargs i, Integral n) =>
n -> n -> (n, n)
bindingAndArrayElemBufferView @lbts @bvargs @i (n
b n -> n -> n
forall a. Num a => a -> a -> a
+ n
1) n
0