module Blubber.Server.Entity where
import Data.Serialize
  (
  Serialize,
  )
import GHC.Generics
  (
  Generic,
  )
import Blubber.Server.Vector
  (
  Vector (Vec),
  (^+^),
  (^-^),
  (^*^),
  (^/^),
  magVec,
  )
data Entity = MkEntity
            {position :: Vector 
            ,mass     :: Double 
            ,entity   :: Blub   
            } deriving (Eq, Generic, Show)
instance Ord Entity where compare e f = compare (mass e) (mass f)
instance Serialize Entity
data Blub = NeutralBlub
          | PlayerBlub
          {velocity  :: Vector
          ,targetPos :: Vector
          } deriving (Eq, Generic, Show)
instance Serialize Blub
radius :: Entity -> Double
radius = sqrt . mass
isNeutral :: Entity -> Bool
isNeutral = n . entity where n NeutralBlub = True
                             n _           = False
intersect :: Entity -> Entity -> Maybe Vector
intersect e f | radius e + radius f > magVec v = Just v
              | otherwise                      = Nothing
  where v = position e ^-^ position f
fite :: (Entity, Entity) -> (Maybe Entity, Maybe Entity)
fite (b, c) = case b `intersect` c of
                Just _ | b > c     -> (Just $ b `blubber` c
                                      ,Nothing)
                       | b < c     -> (Nothing
                                      ,Just $ c `blubber` b)
                       | otherwise -> (Just b, Just c)
                Nothing            -> (Just b, Just c)
blubber :: Entity -> Entity -> Entity
blubber b c | isNeutral b = b
            | otherwise   = b
                          {mass   = mass b + mass c
                          ,entity = (entity b)
                                  {velocity = (velocity (entity b) ^*^ mass b
                                    ^+^ vc ^*^ mass c) ^/^ (mass b + mass c)}
    }
  where vc  | isNeutral c = Vec 0 0
            | otherwise   = velocity (entity c)