# LANGUAGE DisambiguateRecordFields #
# LANGUAGE DeriveGeneric #
  | Module defines all components of high - level data type description of PDB model .
module Bio.PDB.Structure(String,
                         vdot, vnorm, vproj, vperpend, vperpends, vdihedral, (*|), (|*),
                         Structure(..), Model(..), Chain(..), Residue(..), Atom(..))

where

import GHC.Generics(Generic)
import Prelude hiding(String)
import Bio.PDB.EventParser.PDBEvents(String, V3(..)) -- extract to a separate module?
import Control.DeepSeq
import Data . Derive . NFData
import Bio.PDB.Structure.List as L
import Bio.PDB.Structure.Vector

  | Structure holds all data parsed from a single PDB entry
data Structure = Structure { -- remarks :: [Map String String]
                             models    :: L.List Model
                           } deriving (Eq, Show, Generic)

instance NFData Structure where
  rnf m = rnf (models m) `seq` ()

- Using DERIVE would be so much simpler , but also more difficult to get working on GHC-7.4 ( for now ) 
 deriving instance NFData Structure 
 deriving instance NFData Model 
 deriving instance NFData Chain 
 deriving instance NFData Residue 
 deriving instance NFData Atom 
 -
deriving instance NFData Structure
deriving instance NFData Model
deriving instance NFData Chain
deriving instance NFData Residue
deriving instance NFData Atom
--}

-- | PDB entry may contain multiple models, with slight differences in coordinates etc.
data Model     = Model     { modelId   :: !Int,
                             chains    :: L.List Chain
                           } deriving (Eq, Show, Generic)

instance NFData Model where
  rnf m = modelId m `seq` rnf (chains m) `seq` ()

-- | Single linear polymer chain of protein, or nucleic acids
data Chain     = Chain     { chainId   :: !Char,
                             residues  :: L.List Residue
                           } deriving (Eq, Show, Generic)

instance NFData Chain where
  rnf m = chainId m `seq` rnf (residues m) `seq` ()

-- | Residue groups all atoms assigned to the same aminoacid or nucleic acid base within a polymer chain.
data Residue   = Residue   { resName   :: !String,
                             resSeq    :: !Int,
                             atoms     :: L.List Atom,

                             insCode   :: !Char
  ss : : SSType
                           } deriving (Eq, Show, Generic)

instance NFData Residue where
  rnf r = rnf (atoms r) `seq` ()
  TODO : 
 data SSType = SSHelix   HelixType | 
               SSStrand StrandType StrandSense 
 
data SSType = SSHelix  HelixType |
              SSStrand StrandType StrandSense
 -}
-- TODO: LINKs (default and added)

-- | Single atom position
-- | NOTE: disordered atoms are now reported as multiplicates
data Atom      = Atom      { atName    :: !String,
                             atSerial  :: !Int,
                             coord     :: !(V3 Double),

                             bFactor   :: !Double,
                             occupancy :: !Double,
                             element   :: !String,
                             segid     :: !String,
                             charge    :: !String,
                             hetatm    :: !Bool
                           } deriving (Eq, Show, Generic)

-- constructor is strict in all arguments...
instance NFData Atom where
  rnf (Atom {}) = ()

 extract to a separate module?
 remarks :: [Map String String]
}
 | PDB entry may contain multiple models, with slight differences in coordinates etc.
 | Single linear polymer chain of protein, or nucleic acids
 | Residue groups all atoms assigned to the same aminoacid or nucleic acid base within a polymer chain.
 TODO: LINKs (default and added)
 | Single atom position
 | NOTE: disordered atoms are now reported as multiplicates
 constructor is strict in all arguments...
# LANGUAGE DisambiguateRecordFields #
# LANGUAGE DeriveGeneric #
  | Module defines all components of high - level data type description of PDB model .
module Bio.PDB.Structure(String,
                         vdot, vnorm, vproj, vperpend, vperpends, vdihedral, (*|), (|*),
                         Structure(..), Model(..), Chain(..), Residue(..), Atom(..))

where

import GHC.Generics(Generic)
import Prelude hiding(String)
import Control.DeepSeq
import Data . Derive . NFData
import Bio.PDB.Structure.List as L
import Bio.PDB.Structure.Vector

  | Structure holds all data parsed from a single PDB entry
                             models    :: L.List Model
                           } deriving (Eq, Show, Generic)

instance NFData Structure where
  rnf m = rnf (models m) `seq` ()

- Using DERIVE would be so much simpler , but also more difficult to get working on GHC-7.4 ( for now ) 
 deriving instance NFData Structure 
 deriving instance NFData Model 
 deriving instance NFData Chain 
 deriving instance NFData Residue 
 deriving instance NFData Atom 
 -
deriving instance NFData Structure
deriving instance NFData Model
deriving instance NFData Chain
deriving instance NFData Residue
deriving instance NFData Atom

data Model     = Model     { modelId   :: !Int,
                             chains    :: L.List Chain
                           } deriving (Eq, Show, Generic)

instance NFData Model where
  rnf m = modelId m `seq` rnf (chains m) `seq` ()

data Chain     = Chain     { chainId   :: !Char,
                             residues  :: L.List Residue
                           } deriving (Eq, Show, Generic)

instance NFData Chain where
  rnf m = chainId m `seq` rnf (residues m) `seq` ()

data Residue   = Residue   { resName   :: !String,
                             resSeq    :: !Int,
                             atoms     :: L.List Atom,

                             insCode   :: !Char
  ss : : SSType
                           } deriving (Eq, Show, Generic)

instance NFData Residue where
  rnf r = rnf (atoms r) `seq` ()
  TODO : 
 data SSType = SSHelix   HelixType | 
               SSStrand StrandType StrandSense 
 
data SSType = SSHelix  HelixType |
              SSStrand StrandType StrandSense
 -}

data Atom      = Atom      { atName    :: !String,
                             atSerial  :: !Int,
                             coord     :: !(V3 Double),

                             bFactor   :: !Double,
                             occupancy :: !Double,
                             element   :: !String,
                             segid     :: !String,
                             charge    :: !String,
                             hetatm    :: !Bool
                           } deriving (Eq, Show, Generic)

instance NFData Atom where
  rnf (Atom {}) = ()
