--------------------------------------------------------------------------------
-- |
-- Module      :  Camera
-- Copyright   :  (c) Vladimir Lopatin 2022
-- License     :  BSD-3-Clause
--
-- Maintainer  :  Vladimir Lopatin <madjestic13@gmail.com>
-- Stability   :  provisional
-- Portability :  portable
--
-- A structure for a user-controllable object.
--
--------------------------------------------------------------------------------


{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE Arrows #-}
{-# LANGUAGE LambdaCase #-}

module Graphics.RedViz.Controllable
  ( Controllable (..)
  , Device (..)
  , Keyboard (..)
  , Mouse (..)
  , transform
--  , transform'
  , ypr
  , vel
  , device
  , device'
  , mouse
  , keyboard
  ) where

import Linear.Matrix
import Linear.V3
import Control.Lens hiding (transform)

import Graphics.RedViz.Input.Keyboard
import Graphics.RedViz.Input.Mouse
import Graphics.RedViz.Utils ()

-- import Debug.Trace as DT

data Controllable
  =  Controller
     {
       Controllable -> (Double, Double)
_debug      :: (Double, Double)
     , Controllable -> M44 Double
_transform  :: M44 Double
     , Controllable -> V3 Double
_vel        :: V3 Double  -- velocity
     , Controllable -> V3 Double
_ypr        :: V3 Double  -- yaw/pitch/roll
     , Controllable -> Device
_device     :: Device     -- store as index in the proj file: 0 - keyboard, 1 - mouse, etc.
     }
--   |  Solver
--      {
-- --       _pivot      :: V3 Double
--        _transform  :: M44 Double
--      , _ypr        :: V3 Double  -- yaw/pitch/roll
-- --     , _velocity   :: V3 Double
-- --     , _physC      :: Physics -- TODO : add phys.parms
--      }
  deriving Int -> Controllable -> ShowS
[Controllable] -> ShowS
Controllable -> String
(Int -> Controllable -> ShowS)
-> (Controllable -> String)
-> ([Controllable] -> ShowS)
-> Show Controllable
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Controllable] -> ShowS
$cshowList :: [Controllable] -> ShowS
show :: Controllable -> String
$cshow :: Controllable -> String
showsPrec :: Int -> Controllable -> ShowS
$cshowsPrec :: Int -> Controllable -> ShowS
Show

data Device
  =  Device
     {
       Device -> Keyboard
_keyboard :: Keyboard
     , Device -> Mouse
_mouse    :: Mouse
     } deriving Int -> Device -> ShowS
[Device] -> ShowS
Device -> String
(Int -> Device -> ShowS)
-> (Device -> String) -> ([Device] -> ShowS) -> Show Device
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Device] -> ShowS
$cshowList :: [Device] -> ShowS
show :: Device -> String
$cshow :: Device -> String
showsPrec :: Int -> Device -> ShowS
$cshowsPrec :: Int -> Device -> ShowS
Show

-- transform' :: Lens' Controllable (M44 Double)
-- transform' = lens _transform (\controllable newTransform -> Solver { _transform = newTransform })

device'    :: Lens' Controllable Device
device' :: (Device -> f Device) -> Controllable -> f Controllable
device'    = (Controllable -> Device)
-> (Controllable -> Device -> Controllable)
-> Lens Controllable Controllable Device Device
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens Controllable -> Device
_device (\Controllable
controllable Device
newDevice    -> Controllable
controllable { _device :: Device
_device    = Device
newDevice })

$(makeLenses ''Device)
$(makeLenses ''Controllable)