module Main where

import Control.Monad.State
import Control.Monad.Writer
import Control.Monad.Exit
import Actions

-----------------------------------------------------------------------


competentCells :: Action
competentCells =
    do
      makeYPDAgarPlates
      makeSingleColoniesPlates
      growYeastCulture
      exitWith "Finished"



-----------------------------------------------------------------------

makeYPDAgarPlates :: Action
makeYPDAgarPlates = 
    do
      check (preCondition (isIn Store "YPD agar bottle"))
      check (preCondition (isIn ColdRoom "sealed yeast colonies plate"))

      move   (Object     "petri dish") 
             (Start      Store) 
             (End        (In LaminarFlowHood))

      move   (Object     "YPD agar bottle") 
             (Start      (In HotCupboard)) 
             (End        (In LaminarFlowHood))

      delid  (Object     "petri dish") 
             (LidLoc     (In LaminarFlowHood))

      pour   (Component  YPDAgar) 
             (Volume     "20ml") 
             (Container1 "YPD agar bottle") 
             (Container2 "petri dish")

      rename (OldName "petri dish") 
             (NewName "YPD agar plate")

      wait   (Time "30 minutes")
             (Goal "to prevent condensation buildup")

      seal   (Object "YPD agar plate") 
             (Goal "to prevent drying of YPD agar and maintain sterility") 
             (Method "sealing method")
    



----------------------------------------------------------------------

makeSingleColoniesPlates :: Action
makeSingleColoniesPlates = 
    do
      check (preCondition (isIn (In Minus80) "yeast vial"))

      
      move     (Object      "YPD agar plate") 
               (Start       Store) 
               (End         (In LaminarFlowHood))

      move     (Object      "inoculating loop") 
               (Start       ColdRoom) 
               (End         (In LaminarFlowHood))

      move     (Object      "yeast vial") 
               (Start       (In Minus80)) 
               (End         (In LaminarFlowHood))
               -- on ice

      delid    (Object     "YPD agar plate") 
               (LidLoc     (In LaminarFlowHood))

      add      (Component   Yeast)
               (Volume      "small volume")
               (Container1  "yeast vial") 
               (Container2  "YPD agar plate")
               (Equipment   "inoculating loop")
               -- method: method of inoculation of yeast cells

      streak   (Component    Yeast)
               (Object       "YPD agar plate")
               (Equipment   "inoculating loop")
               (Goal        "to produce single colonies")

      rename   (OldName     "YPD agar plate")
               (NewName     "single colonies plate")

      move     (Object      "single colonies plate") 
               (Start       (In LaminarFlowHood))
               (End         (In NonShakingIncubator))

      incubate (Object      "single colonies plate")
               (Equipment   "non-shaking incubator")
               (RPM         0)
               (Temperature 30)
               (TimeInterval "24hours" "48hours")
               (Goal        "to grow visible single yeast colonies approximately 2-5mm in diameter")

      move     (Object      "single colonies plate") 
               (Start       (In NonShakingIncubator))
               (End         (In LaminarFlowHood))

      cover    (Object      "single colonies plate") 
               (LidLoc      (In LaminarFlowHood))

      seal     (Object      "single colonies plate") 
               (Goal        "to prevent drying of YPD agar and maintain sterility")   
               (Method      "sealing method")

      rename   (OldName     "single colonies plate")
               (NewName     "sealed yeast single colonies plate")

      move     (Object      "sealed yeast single colonies plate") 
               (Start       (In LaminarFlowHood))
               (End         ColdRoom)

      check (postCondition (isIn ColdRoom "sealed yeast single colonies plate"))




-----------------------------------------------------------------------

growYeastCulture :: Action
growYeastCulture =
    do 
      check (preCondition (isIn Store "YPD media bottle"))

      move     (Object      "YPD media bottle") 
               (Start       Store) 
               (End         (In LaminarFlowHood))

      move     (Object      "500ml conical flask") 
               (Start       Store) 
               (End         (In LaminarFlowHood))

      move     (Object      "sealed yeast colonies plate") 
               (Start       ColdRoom) 
               (End         (In LaminarFlowHood))

      add      (Component   YPDMedium)
               (Volume      "50ml")
               (Container1  "YPD media bottle") 
               (Container2  "500ml conical flask")
               (Equipment   "pipette")

      rename   (OldName     "500ml conical flask")
               (NewName     "YPD conical flask")

      delid    (Object     "sealed yeast colonies plate") 
               (LidLoc     (In LaminarFlowHood))

      add      (Component   SingleYeastColony)
               (Volume      "small volume")
               (Container1  "sealed yeast colonies plate") 
               (Container2  "YPD conical flask")
               (Equipment   "inoculating loop")

      rename   (OldName     "YPD conical flask")
               (NewName     "Yeast culture flask")

      move     (Object      "Yeast culture flask") 
               (Start       (In LaminarFlowHood)) 
               (End         (In ShakingIncubator))

      incubate (Object      "Yeast culture flask")
               (Equipment   "shaking incubator")
               (RPM         200)
               (Temperature 30)
               (TimeInterval "12hours" "24hours")
               (Goal        "to grow yeast until the medium becomes cloudy")




-------------------------------------------------------------------



main = let ((err,log),lab) = 
               runState (runWriterT (runExitT competentCells)) initialLab 
       in 
       do
         putStrLn (show lab)
         putStrLn ""
         putStrLn (prettylog log)
         putStrLn err



------------------------------------------------------------------------

initialLab = Lab [
                  LabEquipment Bottle [YPDAgar] "YPD agar bottle", 
                  LabEquipment PetriDish [] "petri dish",
                  LabEquipment Bottle [YPDMedium] "YPD media bottle",
                  LabEquipment ConicalFlask [] "500ml conical flask",
                  LabEquipment InoculatingLoop [] "inoculating loop",
                  LabEquipment ShakingIncubator [] "shaking incubator",
                  LabEquipment Pipette [] "pipette",
                  LabEquipment Vial [Yeast] "yeast vial",
                  LabEquipment NonShakingIncubator [] "non-shaking incubator"
                 ]


