    module Graphics.Gloss.Data.ViewPort
            ( ViewPort(..)
            , viewPortInit
            , applyViewPortToPicture
            , invertViewPort )
    where
    import Graphics.Gloss.Data.Picture
    import qualified Graphics.Gloss.Data.Point.Arithmetic as Pt

    -- | The 'ViewPort' represents the global transformation applied to the displayed picture.
    --      When the user pans, zooms, or rotates the display then this changes the 'ViewPort'.
    data ViewPort
            = ViewPort {
            -- | Global translation.
              ViewPort -> (Float, Float)
    viewPortTranslate     :: !(Float, Float)

            -- | Global rotation (in degrees).
            , ViewPort -> Float
    viewPortRotate        :: !Float

            -- | Global scaling (of both x and y coordinates).
            , ViewPort -> Float
    viewPortScale         :: !Float
            }

    -- | The initial state of the viewport.
    viewPortInit :: ViewPort
    viewPortInit :: ViewPort
    viewPortInit
            = ViewPort
            { viewPortTranslate :: (Float, Float)
    viewPortTranslate     = (Float
    0, Float
    0)
            , viewPortRotate :: Float
    viewPortRotate        = Float
    0
            , viewPortScale :: Float
    viewPortScale         = Float
    1
            }

    -- | Translates, rotates, and scales an image according to the 'ViewPort'.
    applyViewPortToPicture :: ViewPort  -> Picture -> Picture
    applyViewPortToPicture :: ViewPort -> Picture -> Picture
    applyViewPortToPicture
            ViewPort { viewPortScale :: ViewPort -> Float
    viewPortScale        = Float
    vscale
                     , viewPortTranslate :: ViewPort -> (Float, Float)
    viewPortTranslate    = (Float
    transX, Float
    transY)
                     , viewPortRotate :: ViewPort -> Float
    viewPortRotate       = Float
    vrotate }
            = Float -> Float -> Picture -> Picture
    Scale Float
    vscale Float
    vscale (Picture -> Picture) -> (Picture -> Picture) -> Picture -> Picture
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Float -> Picture -> Picture
    Rotate Float
    vrotate (Picture -> Picture) -> (Picture -> Picture) -> Picture -> Picture
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Float -> Float -> Picture -> Picture
    Translate Float
    transX Float
    transY

    -- | Takes a point using screen coordinates, and uses the `ViewPort` to convert
    --   it to Picture coordinates. This is the inverse of `applyViewPortToPicture`
    --   for points.
    invertViewPort :: ViewPort -> Point -> Point
    invertViewPort :: ViewPort -> (Float, Float) -> (Float, Float)
    invertViewPort
            ViewPort { viewPortScale :: ViewPort -> Float
    viewPortScale        = Float
    vscale
                     , viewPortTranslate :: ViewPort -> (Float, Float)
    viewPortTranslate    = (Float, Float)
    vtrans
                     , viewPortRotate :: ViewPort -> Float
    viewPortRotate       = Float
    vrotate }
            (Float, Float)
    pos
            = Float -> (Float, Float) -> (Float, Float)
    rotateV (Float -> Float
    degToRad Float
    vrotate) (Float -> (Float, Float) -> (Float, Float)
    mulSV (Float
    1 Float -> Float -> Float
    forall a. Fractional a => a -> a -> a
    / Float
    vscale) (Float, Float)
    pos) (Float, Float) -> (Float, Float) -> (Float, Float)
    Pt.- (Float, Float)
    vtrans

    -- | Convert degrees to radians
    degToRad :: Float -> Float
    degToRad :: Float -> Float
    degToRad Float
    d      = Float
    d Float -> Float -> Float
    forall a. Num a => a -> a -> a
    * Float
    forall a. Floating a => a
    pi Float -> Float -> Float
    forall a. Fractional a => a -> a -> a
    / Float
    180
    {-# INLINE degToRad #-}

    -- | Multiply a vector by a scalar.
    mulSV :: Float -> Vector -> Vector
    mulSV :: Float -> (Float, Float) -> (Float, Float)
    mulSV Float
    s (Float
    x, Float
    y)
            = (Float
    s Float -> Float -> Float
    forall a. Num a => a -> a -> a
    * Float
    x, Float
    s Float -> Float -> Float
    forall a. Num a => a -> a -> a
    * Float
    y)
    {-# INLINE mulSV #-}

    -- | Rotate a vector by an angle (in radians). +ve angle is counter-clockwise.
    rotateV :: Float -> Vector -> Vector
    rotateV :: Float -> (Float, Float) -> (Float, Float)
    rotateV Float
    r (Float
    x, Float
    y)
     =      (  Float
    x Float -> Float -> Float
    forall a. Num a => a -> a -> a
    * Float -> Float
    forall a. Floating a => a -> a
    cos Float
    r Float -> Float -> Float
    forall a. Num a => a -> a -> a
    - Float
    y Float -> Float -> Float
    forall a. Num a => a -> a -> a
    * Float -> Float
    forall a. Floating a => a -> a
    sin Float
    r
            ,  Float
    x Float -> Float -> Float
    forall a. Num a => a -> a -> a
    * Float -> Float
    forall a. Floating a => a -> a
    sin Float
    r Float -> Float -> Float
    forall a. Num a => a -> a -> a
    + Float
    y Float -> Float -> Float
    forall a. Num a => a -> a -> a
    * Float -> Float
    forall a. Floating a => a -> a
    cos Float
    r)
    {-# INLINE rotateV #-}