module MatrixHelper
    ( perspectiveMatrixb
    , isoMatrix
    ) where
import Geometry.Data

import Linear.Matrix
import Graphics.Rendering.OpenGL (GLfloat)

perspectiveMatrixb 
    :: Float        -- ^ Rotation
    -> Float        -- ^ Zoom
    -> Point2       -- ^ Translation
    -> Point2       -- ^ Window size
    -> Point2       -- ^ View froms
    -> [GLfloat]
perspectiveMatrixb rot zoom (V2 tranx trany) (V2 winx winy) (V2 viewFromx viewFromy) =
    concatMap vToL 
    . vToL
    . lmt 
    $ scaleMat (V2 (2*zoom/winx) (2*zoom/winy))
        !*! rotMatr (-rot)
        !*! transMat (V2 (viewFromx-tranx) (viewFromy-trany))
        !*! perMat 0.4
        !*! transMat (V2 (-viewFromx) (-viewFromy))
        !*! vertScale (negate 0.005)
        !*! vertTrans 20

isoMatrix 
    :: Float        -- ^ Rotation
    -> Float        -- ^ Zoom
    -> Point2       -- ^ Translation
    -> Point2       -- ^ Window size
    -> [GLfloat]
isoMatrix rot zoom (V2 tranx trany) (V2 winx winy) = concatMap vToL 
    . vToL 
    . lmt 
    $ scaleMat (V2 (2*zoom/winx) (2*zoom/winy))
        !*! rotMatr (-rot)
        !*! transMat (V2 (-tranx) (-trany))

lmt :: V4 (V4 a) -> V4 (V4 a)
lmt = Linear.Matrix.transpose

vToL :: V4 a -> [a]
vToL (V4 a b c d) = [a,b,c,d]

perMat :: Float -> V4 (V4 Float)
perMat x = V4 
    (V4 1 0 0 0)
    (V4 0 1 0 0)
    (V4 0 0 1 0)
    (V4 0 0 x 1)

scaleMat :: Point2 -> V4 (V4 Float)
scaleMat (V2 x y) = V4
    (V4 x 0 0 0)
    (V4 0 y 0 0)
    (V4 0 0 1 0) 
    (V4 0 0 0 1)

rotMatr :: Float -> V4 (V4 Float)
rotMatr a = V4
    (V4 (cos a) (sin (-a)) 0 0)
    (V4 (sin a) (cos a)    0 0)
    (V4 0       0          1 0)
    (V4 0       0          0 1)

transMat :: Point2 -> V4 (V4 Float)
transMat (V2 x y) = V4 
    (V4 1 0 0 x)
    (V4 0 1 0 y)
    (V4 0 0 1 0)
    (V4 0 0 0 1)

vertScale :: Float -> V4 (V4 Float)
vertScale s = V4
    (V4 1 0 0 0)
    (V4 0 1 0 0)
    (V4 0 0 s 0)
    (V4 0 0 0 1)

vertTrans :: Float -> V4 (V4 Float)
vertTrans z = V4
    (V4 1 0 0 0)
    (V4 0 1 0 0)
    (V4 0 0 1 (negate z))
    (V4 0 0 0 1)
