-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Flexible generation of identicons
--   
--   Flexible generation of identicons.
@package identicon
@version 0.2.2


-- | Core types and definitions for flexible generation of identicons.
--   Please see the <a>Graphics.Identicon.Primitive</a> module for a
--   collection of building blocks to code layers of your identicon.
--   
--   A basic complete example looks like this:
--   
--   <pre>
--   import Codec.Picture
--   import Data.ByteString (ByteString)
--   import Data.Proxy
--   import Data.Word (Word8)
--   import Graphics.Identicon
--   import Graphics.Identicon.Primitive
--   
--   myImageType :: Proxy (Identicon 4 :+ Consumer 4)
--   myImageType = Proxy
--   
--   myImpl = Identicon :+ a
--     where
--       a :: Word8 -&gt; Word8 -&gt; Word8 -&gt; Word8 -&gt; Layer
--       a r g b n = rsym $ onGrid 6 6 n $
--         circle $ gradientLR (edge . mid) black (PixelRGB8 r g b)
--   
--   myGenerator :: Int -&gt; Int -&gt; ByteString -&gt; Maybe (Image PixelRGB8)
--   myGenerator = renderIdenticon myImageType myImpl
--   </pre>
--   
--   <tt>myGenerator</tt> takes desired width, height, and hash that should
--   have at least 4 bytes in it and returns an identicon corresponding to
--   that hash or <a>Nothing</a> if the hash has less than 4 bytes in it or
--   width/height don't make sense. The identicon has randomly placed
--   circle with gradient filling changing (horizontally) from black to
--   some color and back to black. The circle is mirrored 4 times, and
--   every repetition is rotated by 90°. This identicon consumes 4 bytes
--   and has one layer.
module Graphics.Identicon

-- | <a>Identicon</a> is a type that represents an identicon consisting of
--   zero layers. The type is parametrized over a phantom type <tt>n</tt>
--   which is a natural number on the type level that represents the number
--   of bytes that should be provided to generate this type of identicon.
--   Bytes typically come from some sort of hash that has a fixed size.
data Identicon (n :: Nat)
Identicon :: Identicon

-- | <a>Consumer</a> is a type that represents an entity that consumes
--   bytes that are available for identicon generation. It's parametrized
--   over a phantom type <tt>n</tt> which is a natural number on the type
--   level that represents the number of bytes that this entity consumes.
--   At this moment, a <a>Consumer</a> always adds one <a>Layer</a> to
--   identicon when attached to it. The number of bytes, specified as type
--   parameter of <a>Identicon</a> type must be completely consumed by a
--   collection of consumers attached to it. To attach a consumer to
--   <a>Identicon</a>, you use the <tt>(<a>:+</a>)</tt> type operator, see
--   below.
data Consumer (n :: Nat)

-- | The <tt>(<a>:+</a>)</tt> type operator is used to attach
--   <a>Consumer</a>s to <a>Identicon</a>, thus adding layers to it and
--   exhausting bytes that are available for identicon generation. An
--   example of identicon that can be generated from 16 byte hash is shown
--   below:
--   
--   <pre>
--   type Icon = Identicon 16 :+ Consumer 5 :+ Consumer 5 :+ Consumer 6
--   </pre>
--   
--   The identicon above has three layers.
data a (:+) b
(:+) :: a -> b -> (:+) a b

-- | <a>Layer</a> is the basic building block of an identicon. It's a
--   function that takes the following arguments (in order):
--   
--   <ul>
--   <li>Width of identicon</li>
--   <li>Height of identicon</li>
--   <li>Position on X axis</li>
--   <li>Position on Y axis</li>
--   </ul>
--   
--   …and returns a <a>PixelRGB8</a> value. In this library, an identicon
--   is generated as a “superposition” of several <tt>Layers</tt>.
newtype Layer
Layer :: (Int -> Int -> Int -> Int -> PixelRGB8) -> Layer
[unLayer] :: Layer -> Int -> Int -> Int -> Int -> PixelRGB8

-- | The <a>BytesAvailable</a> type function calculates how many bytes are
--   available for consumption in a given identicon.

-- | The <a>BytesConsumed</a> type function calculates how many bytes are
--   consumed in a given identicon.

-- | The <a>Implementation</a> type function returns the type of the code
--   which can implement the given identicon.

-- | The <a>ToLayer</a> type function calculates type that a
--   layer-producing function should have to consume the given number of
--   bytes <tt>n</tt>.

-- | Identicons that can be rendered as an image implement this class.
class Renderable a
render :: Renderable a => Proxy a -> Implementation a -> Int -> Int -> ByteString -> (ByteString, Int -> Int -> PixelRGB8)

-- | Consume bytes from a strict <a>ByteString</a> and apply them to a
--   function that takes <a>Word8</a> until it produces a <a>Layer</a>.
class ApplyBytes a
applyBytes :: ApplyBytes a => a -> ByteString -> (ByteString, Layer)

-- | Render an identicon. The function returns <a>Nothing</a> if given
--   <a>ByteString</a> is too short or when width or height is lesser than
--   1.
renderIdenticon :: forall a. (Renderable a, KnownNat (BytesAvailable a), BytesAvailable a ~ BytesConsumed a) => Proxy a -> Implementation a -> Int -> Int -> ByteString -> Maybe (Image PixelRGB8)
instance (Graphics.Identicon.Renderable a, Graphics.Identicon.ApplyBytes (Graphics.Identicon.ToLayer n)) => Graphics.Identicon.Renderable (a Graphics.Identicon.:+ Graphics.Identicon.Consumer n)
instance Graphics.Identicon.ApplyBytes Graphics.Identicon.Layer
instance Graphics.Identicon.ApplyBytes f => Graphics.Identicon.ApplyBytes (GHC.Word.Word8 -> f)
instance Graphics.Identicon.Renderable (Graphics.Identicon.Identicon n)
instance Data.Semigroup.Semigroup Graphics.Identicon.Layer
instance GHC.Base.Monoid Graphics.Identicon.Layer


-- | Various primitives and combinators that help you write code for your
--   identicon. Filling functions is where you start. They create color
--   layers that occupy all available space. If you want to limit a layer
--   in size, specify where this smaller part should be, take a look at the
--   “Position, size, and shape” section. It also contains the
--   <a>circle</a> combinator that limits a given filling is such a way
--   that it forms a circle. Finally, we have combinators that add symmetry
--   to layers and other auxiliary functions.
--   
--   As a starting point, here is the function that generates a circle with
--   gradient filling changing from black (on the left hand side) to some
--   color (on the right hand side):
--   
--   <pre>
--   f :: Word8 -&gt; Word8 -&gt; Word8 -&gt; Layer
--   f r g b = circle $ gradientLR id black (PixelRGB8 r g b)
--   </pre>
--   
--   The function consumes 3 bytes from a hash when it's used in identicon.
module Graphics.Identicon.Primitive

-- | Black is a special color, it means absence of light. We give this
--   pixel a name because it's used very frequently in layer coding.
black :: PixelRGB8

-- | Layer filled with a given color.
color :: PixelRGB8 -> Layer

-- | Gradient changing from left to right.
gradientLR :: (Float -> Float) -> PixelRGB8 -> PixelRGB8 -> Layer

-- | Gradient changing from top to bottom.
gradientTB :: (Float -> Float) -> PixelRGB8 -> PixelRGB8 -> Layer

-- | Gradient changing from top left corner to bottom right corner.
gradientTLBR :: (Float -> Float) -> PixelRGB8 -> PixelRGB8 -> Layer

-- | Gradient changing from top right corner to bottom left corner.
gradientTRBL :: (Float -> Float) -> PixelRGB8 -> PixelRGB8 -> Layer

-- | Gradient with one color everywhere and another in the center.
gradientXY :: (Float -> Float) -> PixelRGB8 -> PixelRGB8 -> Layer

-- | A built-in gradient transforming function. It maps continuous floating
--   value changing from 0 to 1 to value changing from 0 to 1 (in the
--   middle) and back to 0.
mid :: Float -> Float

-- | This sharpens gradient transitions.
edge :: Float -> Float

-- | <tt>onGrid w h n l</tt>, given grid that has <tt>w</tt> horizontal
--   discrete positions (of equal length) and <tt>h</tt> vertical
--   positions, it makes given layer <tt>l</tt> occupy cell at index
--   <tt>n</tt>. This approach allows you control position and size at the
--   same time.
--   
--   The index <tt>n</tt> can be greater than maximal index, in this case
--   reminder of division of <tt>n</tt> by <tt>w * h</tt> is used.
onGrid :: Integral a => Int -> Int -> a -> Layer -> Layer

-- | Limit given layer so it forms a circle.
circle :: Layer -> Layer

-- | Add horizontal symmetry to a layer.
hsym :: Layer -> Layer

-- | Add vertical symmetry to a layer.
vsym :: Layer -> Layer

-- | Add horizontal and vertical symmetry to layer. Result is a layer with
--   four mirrored repetitions of the same figure.
hvsym :: Layer -> Layer

-- | Just like <a>hvsym</a>, but every repetition is rotated by 90°. Only
--   works with square layers because for speed it just swaps coordinates.
rsym :: Layer -> Layer

-- | Select one of provided alternatives given a number.
oneof :: Integral n => [a] -> n -> a
