-- |
-- Module     : Simulation.Aivika.Experiment.Base.ExperimentSpecsWriter
-- Copyright  : Copyright (c) 2012-2017, David Sorokin <david.sorokin@gmail.com>
-- License    : BSD3
-- Maintainer : David Sorokin <david.sorokin@gmail.com>
-- Stability  : experimental
-- Tested with: GHC 8.0.1
--
-- The module defines 'ExperimentSpecsWriter' that knows how to write
-- in HTML the experiment specs which include the simulation specs and 
-- the number of simulation runs.
--

module Simulation.Aivika.Experiment.Base.ExperimentSpecsWriter 
       (ExperimentSpecsWriter(..),
        defaultExperimentSpecsWriter) where

import Simulation.Aivika
import Simulation.Aivika.Experiment.Types
import Simulation.Aivika.Experiment.Base.HtmlWriter

-- | Defines a writer that knows how to represent the
-- experiment specs as the HTML table.
data ExperimentSpecsWriter =
  ExperimentSpecsWriter { ExperimentSpecsWriter -> Int
experimentSpecsWidth         :: Int,
                          -- ^ The width of the HTML table.
                          ExperimentSpecsWriter -> String
experimentSpecsNameText     :: String,
                          -- ^ Translated text \"Experiment Specs\".
                          ExperimentSpecsWriter -> String
experimentSpecsStartTimeText :: String,
                          -- ^ Translated text \"start time\".
                          ExperimentSpecsWriter -> String
experimentSpecsStopTimeText  :: String,
                          -- ^ Translated text \"stop time\".
                          ExperimentSpecsWriter -> String
experimentSpecsDTText        :: String,
                          -- ^ Translated text \"time step\".
                          ExperimentSpecsWriter -> String
experimentSpecsRunCountText  :: String,
                          -- ^ Translated text \"run count\".
                          ExperimentSpecsWriter -> String
experimentSpecsIntegMethodText    :: String,
                          -- ^ Translated text \"integration method\".
                          ExperimentSpecsWriter -> String
experimentSpecsEulerText     :: String,
                          -- ^ Translated text \"Euler's\".
                          ExperimentSpecsWriter -> String
experimentSpecsRungeKutta2Text :: String,
                          -- ^ Translated text \"the 2-nd order Runge-Kutta\".
                          ExperimentSpecsWriter -> String
experimentSpecsRungeKutta4Text :: String,
                          -- ^ Translated text \"the 4-th order Runge-Kutta\".
                          ExperimentSpecsWriter -> String
experimentSpecsRungeKutta4bText :: String,
                          -- ^ Translated text \"the 4-th order Runge-Kutta 3/8-rule\".
                          ExperimentSpecsWriter -> ShowS
experimentSpecsFormatter     :: ShowS,
                          -- ^ The formatter of numbers.
                          ExperimentSpecsWriter
-> ExperimentSpecsWriter -> Experiment -> HtmlWriter ()
experimentSpecsWrite :: ExperimentSpecsWriter
                                                  -> Experiment
                                                  -> HtmlWriter ()
                          -- ^ This function creates HTML.
                        }

-- | The default writer.
defaultExperimentSpecsWriter :: ExperimentSpecsWriter
defaultExperimentSpecsWriter :: ExperimentSpecsWriter
defaultExperimentSpecsWriter =
  ExperimentSpecsWriter :: Int
-> String
-> String
-> String
-> String
-> String
-> String
-> String
-> String
-> String
-> String
-> ShowS
-> (ExperimentSpecsWriter -> Experiment -> HtmlWriter ())
-> ExperimentSpecsWriter
ExperimentSpecsWriter { 
    experimentSpecsWidth :: Int
experimentSpecsWidth = Int
400,
    experimentSpecsNameText :: String
experimentSpecsNameText = String
"Experiment Specs",
    experimentSpecsStartTimeText :: String
experimentSpecsStartTimeText = String
"start time",
    experimentSpecsStopTimeText :: String
experimentSpecsStopTimeText = String
"stop time",
    experimentSpecsDTText :: String
experimentSpecsDTText = String
"time step",
    experimentSpecsRunCountText :: String
experimentSpecsRunCountText = String
"run count",
    experimentSpecsIntegMethodText :: String
experimentSpecsIntegMethodText = String
"integration method",
    experimentSpecsEulerText :: String
experimentSpecsEulerText = String
"Euler's",
    experimentSpecsRungeKutta2Text :: String
experimentSpecsRungeKutta2Text = String
"the 2-nd order Runge-Kutta",
    experimentSpecsRungeKutta4Text :: String
experimentSpecsRungeKutta4Text = String
"the 4-th order Runge-Kutta",
    experimentSpecsRungeKutta4bText :: String
experimentSpecsRungeKutta4bText = String
"the 4-th order Runge-Kutta 3/8-rule",
    experimentSpecsFormatter :: ShowS
experimentSpecsFormatter = ShowS
forall a. a -> a
id,
    experimentSpecsWrite :: ExperimentSpecsWriter -> Experiment -> HtmlWriter ()
experimentSpecsWrite = \ExperimentSpecsWriter
writer Experiment
exp ->
      do let format :: ShowS
format String
x = ExperimentSpecsWriter -> ShowS
experimentSpecsFormatter ExperimentSpecsWriter
writer String
x
         String -> HtmlWriter ()
writeHtml String
"<p>"
         String -> HtmlWriter ()
writeHtml String
"<table frame='border' cellspacing='4' width='"
         String -> HtmlWriter ()
writeHtml (String -> HtmlWriter ()) -> String -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show (Int -> String) -> Int -> String
forall a b. (a -> b) -> a -> b
$ ExperimentSpecsWriter -> Int
experimentSpecsWidth ExperimentSpecsWriter
writer
         String -> HtmlWriter ()
writeHtml String
"'>"
         String -> HtmlWriter ()
writeHtml String
"<tr>"
         String -> HtmlWriter ()
writeHtml String
"<td colspan='2'>"
         String -> HtmlWriter ()
writeHtml String
"<p align='center'>"
         String -> HtmlWriter ()
writeHtmlText (String -> HtmlWriter ()) -> String -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$ ExperimentSpecsWriter -> String
experimentSpecsNameText ExperimentSpecsWriter
writer
         String -> HtmlWriter ()
writeHtml String
"</p>"
         String -> HtmlWriter ()
writeHtml String
"</td>"
         String -> HtmlWriter ()
writeHtml String
"</tr>"
         String -> HtmlWriter ()
writeHtml String
"<tr>"
         String -> HtmlWriter ()
writeHtml String
"<td>"
         String -> HtmlWriter ()
writeHtmlText (String -> HtmlWriter ()) -> String -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$ ExperimentSpecsWriter -> String
experimentSpecsStartTimeText ExperimentSpecsWriter
writer 
         String -> HtmlWriter ()
writeHtml String
"</td>"
         String -> HtmlWriter ()
writeHtml String
"<td>"
         String -> HtmlWriter ()
writeHtmlText (String -> HtmlWriter ()) -> String -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$ ShowS
format ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Double -> String
forall a. Show a => a -> String
show (Double -> String) -> Double -> String
forall a b. (a -> b) -> a -> b
$ Specs -> Double
spcStartTime (Specs -> Double) -> Specs -> Double
forall a b. (a -> b) -> a -> b
$ Experiment -> Specs
experimentSpecs Experiment
exp
         String -> HtmlWriter ()
writeHtml String
"</td>"
         String -> HtmlWriter ()
writeHtml String
"</tr>"
         String -> HtmlWriter ()
writeHtml String
"<tr>"
         String -> HtmlWriter ()
writeHtml String
"<td>"
         String -> HtmlWriter ()
writeHtmlText (String -> HtmlWriter ()) -> String -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$ ExperimentSpecsWriter -> String
experimentSpecsStopTimeText ExperimentSpecsWriter
writer
         String -> HtmlWriter ()
writeHtml String
"</td>"
         String -> HtmlWriter ()
writeHtml String
"<td>"
         String -> HtmlWriter ()
writeHtmlText (String -> HtmlWriter ()) -> String -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$ ShowS
format ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Double -> String
forall a. Show a => a -> String
show (Double -> String) -> Double -> String
forall a b. (a -> b) -> a -> b
$ Specs -> Double
spcStopTime (Specs -> Double) -> Specs -> Double
forall a b. (a -> b) -> a -> b
$ Experiment -> Specs
experimentSpecs Experiment
exp
         String -> HtmlWriter ()
writeHtml String
"</td>"
         String -> HtmlWriter ()
writeHtml String
"</tr>"
         String -> HtmlWriter ()
writeHtml String
"<tr>"
         String -> HtmlWriter ()
writeHtml String
"<td>"
         String -> HtmlWriter ()
writeHtmlText (String -> HtmlWriter ()) -> String -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$ ExperimentSpecsWriter -> String
experimentSpecsDTText ExperimentSpecsWriter
writer
         String -> HtmlWriter ()
writeHtml String
"</td>"
         String -> HtmlWriter ()
writeHtml String
"<td>"
         String -> HtmlWriter ()
writeHtmlText (String -> HtmlWriter ()) -> String -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$ ShowS
format ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Double -> String
forall a. Show a => a -> String
show (Double -> String) -> Double -> String
forall a b. (a -> b) -> a -> b
$ Specs -> Double
spcDT (Specs -> Double) -> Specs -> Double
forall a b. (a -> b) -> a -> b
$ Experiment -> Specs
experimentSpecs Experiment
exp
         String -> HtmlWriter ()
writeHtml String
"</td>"
         String -> HtmlWriter ()
writeHtml String
"</tr>"
         String -> HtmlWriter ()
writeHtml String
"<tr>"
         String -> HtmlWriter ()
writeHtml String
"<td>"
         String -> HtmlWriter ()
writeHtmlText (String -> HtmlWriter ()) -> String -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$ ExperimentSpecsWriter -> String
experimentSpecsRunCountText ExperimentSpecsWriter
writer
         String -> HtmlWriter ()
writeHtml String
"</td>"
         String -> HtmlWriter ()
writeHtml String
"<td>"
         String -> HtmlWriter ()
writeHtmlText (String -> HtmlWriter ()) -> String -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$ ShowS
format ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show (Int -> String) -> Int -> String
forall a b. (a -> b) -> a -> b
$ Experiment -> Int
experimentRunCount Experiment
exp
         String -> HtmlWriter ()
writeHtml String
"</td>"
         String -> HtmlWriter ()
writeHtml String
"</tr>"
         String -> HtmlWriter ()
writeHtml String
"<tr>"
         String -> HtmlWriter ()
writeHtml String
"<td>"
         String -> HtmlWriter ()
writeHtmlText (String -> HtmlWriter ()) -> String -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$ ExperimentSpecsWriter -> String
experimentSpecsIntegMethodText ExperimentSpecsWriter
writer
         String -> HtmlWriter ()
writeHtml String
"</td>"
         String -> HtmlWriter ()
writeHtml String
"<td>"
         let method :: Method
method = Specs -> Method
spcMethod (Specs -> Method) -> Specs -> Method
forall a b. (a -> b) -> a -> b
$ Experiment -> Specs
experimentSpecs Experiment
exp
         String -> HtmlWriter ()
writeHtml (String -> HtmlWriter ()) -> String -> HtmlWriter ()
forall a b. (a -> b) -> a -> b
$ Method -> ExperimentSpecsWriter -> String
methodName Method
method ExperimentSpecsWriter
writer
         String -> HtmlWriter ()
writeHtml String
"</td>"
         String -> HtmlWriter ()
writeHtml String
"</tr>"
         String -> HtmlWriter ()
writeHtml String
"</table>" 
         String -> HtmlWriter ()
writeHtml String
"</p>"
    }

-- | Return the method name.
methodName :: Method -> ExperimentSpecsWriter -> String
methodName :: Method -> ExperimentSpecsWriter -> String
methodName Method
Euler       = ExperimentSpecsWriter -> String
experimentSpecsEulerText
methodName Method
RungeKutta2 = ExperimentSpecsWriter -> String
experimentSpecsRungeKutta2Text
methodName Method
RungeKutta4 = ExperimentSpecsWriter -> String
experimentSpecsRungeKutta4Text
methodName Method
RungeKutta4b = ExperimentSpecsWriter -> String
experimentSpecsRungeKutta4bText