{-# LANGUAGE DeriveGeneric #-}
module Script.Types where

import           Data.Binary
import qualified Data.Map     as M
import           GHC.Generics (Generic)

import           Common

type Time = Integer

type Name = String
type Ident = Int

type StaticFrame = M.Map ObjName StaticInfo

data StaticInfo = StaticInfo
  { siBodyID   :: BodyID
  , siIdent    :: Ident
  , siName     :: ObjName
  , siComp     :: Component
  , siLocalPos :: Position
  , siLocalAng :: Angle
  , siWorldPos :: Position
  , siWorldAng :: Angle
  } deriving (Eq, Show, Read)

type Frame = Tree ObjInfo

data ObjInfo = ObjInfo
  { oiComponent :: Component
  , oiName      :: Name
  , oiIdent     :: Ident
  } deriving (Eq, Show, Read, Generic)

instance Binary ObjInfo

data BulletInfo = BulletInfo
  { bltPosition :: Position
  , bltVelocity :: Velocity
  } deriving (Eq, Show, Read, Generic)

instance Binary BulletInfo

data Command
  -- | 文字列を画面上に表示する
  = PutStr String
  -- | ホイール `Wheel` を回転させるために [力積](https://ja.wikipedia.org/wiki/%E5%8A%9B%E7%A9%8D) を加える
  | AddRotImpulse
    { cmdObj     :: ObjName -- ^ 対象のパーツの名前
    , cmdImpulse :: Double -- ^ [力積](https://ja.wikipedia.org/wiki/%E5%8A%9B%E7%A9%8D) (正は反時計周り)
    }
  -- | ジョイント `Joint` を指定の角度に合わせる。
  | SetAngle
    { cmdObj   :: ObjName -- ^ 対象のパーツの名前
    , cmdAngle :: Angle -- ^ 角度 (単位: [ラジアン](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%B8%E3%82%A2%E3%83%B3), デフォルト: 0, 値域: -pi\/2 から pi\/2)
    }
  -- | ジェット `Jet` にオペレーション `JetOperation` を設定する
  | SetJetOperation
    { cmdObj       :: ObjName -- ^ 対象のパーツの名前
    , cmdOperation :: Maybe JetOperation -- ^ 指定するオペレーション。Nothingで無効化。
    }
  -- | 機銃 `Gun` から弾を発射する
  | ShootGun
    { cmdObj :: ObjName -- ^ 対象のパーツの名前
    }
  deriving (Eq, Show, Read, Generic)

instance Binary Command