module Drasil.SSP.Requirements (funcReqs, funcReqTables, nonFuncReqs) where

import Language.Drasil
import Language.Drasil.Chunk.Concept.NamedCombinators
import qualified Language.Drasil.Sentence.Combinators as S

import Drasil.DocLang (mkInputPropsTable, mkMaintainableNFR, mkCorrectNFR,
  mkUnderstandableNFR, mkReusableNFR)
import Drasil.DocLang.SRS (datCon, propCorSol) 

import Data.Drasil.Concepts.Computation (inDatum)
import Data.Drasil.Concepts.Documentation (datum, funcReqDom, input_, name_,
  output_, physicalConstraint, symbol_, user, value, propOfCorSol)
import Data.Drasil.Concepts.Physics (twoD)

import Drasil.SSP.Defs (crtSlpSrf, slope, slpSrf)
import Drasil.SSP.IMods (fctSfty, nrmShrFor, intsliceFs, crtSlpId)
import Drasil.SSP.Unitals (constF, coords, fs, fsMin, intNormForce, 
  intShrForce, inputs, xMaxExtSlip, xMaxEtrSlip, xMinExtSlip, xMinEtrSlip, 
  yMaxSlip, yMinSlip)

{-Functional Requirements-}

funcReqs :: [ConceptInstance]
funcReqs :: [ConceptInstance]
funcReqs = [ConceptInstance
readAndStore, ConceptInstance
verifyInput, ConceptInstance
determineCritSlip, ConceptInstance
verifyOutput, 
  ConceptInstance
displayInput, ConceptInstance
displayGraph, ConceptInstance
displayFS, ConceptInstance
displayNormal, ConceptInstance
displayShear, 
  ConceptInstance
writeToFile]

funcReqTables :: [LabelledContent]
funcReqTables :: [LabelledContent]
funcReqTables = [LabelledContent
inputDataTable, LabelledContent
inputsToOutputTable]

readAndStore, verifyInput, determineCritSlip, verifyOutput, displayInput, 
  displayGraph, displayFS, displayNormal, displayShear, 
  writeToFile :: ConceptInstance

readAndStore :: ConceptInstance
readAndStore = String -> Sentence -> String -> ConceptChunk -> ConceptInstance
forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"readAndStore" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Read the", IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
plural IdeaDict
input_ Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"shown in the table", 
  LabelledContent -> Sentence -> Sentence
forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence -> Sentence
namedRef LabelledContent
inputDataTable (String -> Sentence
S String
"Required Inputs") Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"and store the", IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
plural IdeaDict
datum]) 
  String
"Read-and-Store" ConceptChunk
funcReqDom

verifyInput :: ConceptInstance
verifyInput = String -> Sentence -> String -> ConceptChunk -> ConceptInstance
forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"verifyInput" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Verify that the", IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
plural IdeaDict
inDatum, String -> Sentence
S String
"lie within the",
  Section -> Sentence -> Sentence
forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence -> Sentence
namedRef ([Contents] -> [Section] -> Section
datCon [] []) (IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
plural IdeaDict
physicalConstraint)])
  String
"Verify-Input" ConceptChunk
funcReqDom

determineCritSlip :: ConceptInstance
determineCritSlip = String -> Sentence -> String -> ConceptChunk -> ConceptInstance
forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"determineCritSlip" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Determine the", ConceptChunk -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
crtSlpSrf, String -> Sentence
S String
"for the", IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
input_, 
  IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
slope Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"corresponding to the minimum", ConstrConcept -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase ConstrConcept
fs Sentence -> Sentence -> Sentence
`sC` 
  String -> Sentence
S String
"by using", Sentence
usingIMs, String -> Sentence
S String
"to calculate the", ConstrConcept -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase ConstrConcept
fs, String -> Sentence
S String
"for a", 
  ConceptChunk -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
slpSrf Sentence -> Sentence -> Sentence
`S.and_` String -> Sentence
S String
"using", InstanceModel -> Sentence
forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence
refS InstanceModel
crtSlpId, String -> Sentence
S String
"to find the", 
  ConceptChunk -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
slpSrf, String -> Sentence
S String
"that minimizes it"]) 
  String
"Determine-Critical-Slip-Surface" ConceptChunk
funcReqDom

verifyOutput :: ConceptInstance
verifyOutput = String -> Sentence -> String -> ConceptChunk -> ConceptInstance
forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"verifyOutput" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Verify that the", DefinedQuantityDict -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase DefinedQuantityDict
fsMin Sentence -> Sentence -> Sentence
`S.and_` ConceptChunk -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
crtSlpSrf, String -> Sentence
S String
"satisfy the",
  IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
plural IdeaDict
physicalConstraint, String -> Sentence
S String
"shown in", Section -> Sentence -> Sentence
forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence -> Sentence
namedRef ([Contents] -> [Section] -> Section
propCorSol [] []) (IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
titleize' IdeaDict
propOfCorSol)])
  String
"Verify-Output" ConceptChunk
funcReqDom

displayInput :: ConceptInstance
displayInput = String -> Sentence -> String -> ConceptChunk -> ConceptInstance
forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"displayInput" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Display as", IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
output_, NP -> Sentence
forall n. NounPhrase n => n -> Sentence
phraseNP (IdeaDict -> NP
forall t. NamedIdea t => t -> NP
the IdeaDict
user) Sentence -> Sentence -> Sentence
:+: String -> Sentence
S String
"-supplied",
  IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
plural IdeaDict
input_, String -> Sentence
S String
"listed in", LabelledContent -> Sentence
forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence
refS LabelledContent
inputsToOutputTable])
  String
"Display-Input" ConceptChunk
funcReqDom

displayGraph :: ConceptInstance
displayGraph = String -> Sentence -> String -> ConceptChunk -> ConceptInstance
forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"displayGraph" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Display", ConceptChunk -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
crtSlpSrf Sentence -> Sentence -> Sentence
`S.the_ofThe` CI -> Sentence
forall c. Idea c => c -> Sentence
short CI
twoD, IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
slope Sentence -> Sentence -> Sentence
`sC` 
  String -> Sentence
S String
"as determined from", InstanceModel -> Sentence
forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence
refS InstanceModel
crtSlpId Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"graphically"]) 
  String
"Display-Graph" ConceptChunk
funcReqDom

displayFS :: ConceptInstance
displayFS = String -> Sentence -> String -> ConceptChunk -> ConceptInstance
forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"displayFS" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Display", IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase IdeaDict
value Sentence -> Sentence -> Sentence
`S.the_ofThe` ConstrConcept -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase ConstrConcept
fs, String -> Sentence
S String
"for the", 
  ConceptChunk -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
crtSlpSrf Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"as determined from", Sentence
usingIMs]) 
  String
"Display-Factor-of-Safety" ConceptChunk
funcReqDom

displayNormal :: ConceptInstance
displayNormal = String -> Sentence -> String -> ConceptChunk -> ConceptInstance
forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"displayNormal" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Using", Sentence
usingIMs Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"calculate and graphically display the",
  UnitalChunk -> Sentence
forall n. NamedIdea n => n -> Sentence
plural UnitalChunk
intNormForce]) String
"Display-Interslice-Normal-Forces" ConceptChunk
funcReqDom

displayShear :: ConceptInstance
displayShear = String -> Sentence -> String -> ConceptChunk -> ConceptInstance
forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"displayShear" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Using", Sentence
usingIMs Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"calculate and graphically display the",
  UnitalChunk -> Sentence
forall n. NamedIdea n => n -> Sentence
plural UnitalChunk
intShrForce]) String
"Display-Interslice-Shear-Forces" ConceptChunk
funcReqDom

writeToFile :: ConceptInstance
writeToFile = String -> Sentence -> String -> ConceptChunk -> ConceptInstance
forall c.
Concept c =>
String -> Sentence -> String -> c -> ConceptInstance
cic String
"writeToFile" ( [Sentence] -> Sentence
foldlSent [
  String -> Sentence
S String
"Provide the option of writing the output result data, as given in", 
  SepType -> FoldType -> [Sentence] -> Sentence
foldlList SepType
Comma FoldType
List ((ConceptInstance -> Sentence) -> [ConceptInstance] -> [Sentence]
forall a b. (a -> b) -> [a] -> [b]
map ConceptInstance -> Sentence
forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence
refS [ConceptInstance
displayInput, ConceptInstance
displayGraph, ConceptInstance
displayFS, 
  ConceptInstance
displayNormal, ConceptInstance
displayShear]) Sentence -> Sentence -> Sentence
`sC` String -> Sentence
S String
"to a file"]) String
"Write-Results-To-File" 
  ConceptChunk
funcReqDom

usingIMs :: Sentence
usingIMs :: Sentence
usingIMs = SepType -> FoldType -> [Sentence] -> Sentence
foldlList SepType
Comma FoldType
List ([Sentence] -> Sentence) -> [Sentence] -> Sentence
forall a b. (a -> b) -> a -> b
$ (InstanceModel -> Sentence) -> [InstanceModel] -> [Sentence]
forall a b. (a -> b) -> [a] -> [b]
map InstanceModel -> Sentence
forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> Sentence
refS [InstanceModel
fctSfty, InstanceModel
nrmShrFor, InstanceModel
intsliceFs]

------------------
inputDataTable :: LabelledContent
inputDataTable :: LabelledContent
inputDataTable = [DefinedQuantityDict] -> ConceptInstance -> LabelledContent
forall i r.
(Quantity i, MayHaveUnit i, HasShortName r, Referable r) =>
[i] -> r -> LabelledContent
mkInputPropsTable (ConstrConcept -> DefinedQuantityDict
forall c.
(Quantity c, Concept c, MayHaveUnit c) =>
c -> DefinedQuantityDict
dqdWr ConstrConcept
coords DefinedQuantityDict
-> [DefinedQuantityDict] -> [DefinedQuantityDict]
forall a. a -> [a] -> [a]
: (DefinedQuantityDict -> DefinedQuantityDict)
-> [DefinedQuantityDict] -> [DefinedQuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map DefinedQuantityDict -> DefinedQuantityDict
forall c.
(Quantity c, Concept c, MayHaveUnit c) =>
c -> DefinedQuantityDict
dqdWr [DefinedQuantityDict]
inputs) ConceptInstance
readAndStore
  --FIXME: this has to be seperate since coords is a different type

inputsToOutput :: [DefinedQuantityDict]
inputsToOutput :: [DefinedQuantityDict]
inputsToOutput = DefinedQuantityDict
constF DefinedQuantityDict
-> [DefinedQuantityDict] -> [DefinedQuantityDict]
forall a. a -> [a] -> [a]
: (UncertQ -> DefinedQuantityDict)
-> [UncertQ] -> [DefinedQuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map UncertQ -> DefinedQuantityDict
forall c.
(Quantity c, Concept c, MayHaveUnit c) =>
c -> DefinedQuantityDict
dqdWr [UncertQ
xMaxExtSlip, UncertQ
xMaxEtrSlip, UncertQ
xMinExtSlip, 
  UncertQ
xMinEtrSlip, UncertQ
yMaxSlip, UncertQ
yMinSlip]

inputsToOutputTable :: LabelledContent
inputsToOutputTable :: LabelledContent
inputsToOutputTable = Reference -> RawContent -> LabelledContent
llcc (String -> Reference
makeTabRef String
"inputsToOutputTable") (RawContent -> LabelledContent) -> RawContent -> LabelledContent
forall a b. (a -> b) -> a -> b
$
  [Sentence] -> [[Sentence]] -> Sentence -> Bool -> RawContent
Table [IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
titleize IdeaDict
symbol_, IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
titleize IdeaDict
name_] ([DefinedQuantityDict -> Sentence]
-> [DefinedQuantityDict] -> [[Sentence]]
forall a b. [a -> b] -> [a] -> [[b]]
mkTable [DefinedQuantityDict -> Sentence
forall c. (HasUID c, HasSymbol c) => c -> Sentence
ch, DefinedQuantityDict -> Sentence
forall n. NamedIdea n => n -> Sentence
phrase] [DefinedQuantityDict]
inputsToOutput)
  (IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
atStart' IdeaDict
input_ Sentence -> Sentence -> Sentence
+:+ String -> Sentence
S String
"to be Returned as" Sentence -> Sentence -> Sentence
+:+ IdeaDict -> Sentence
forall n. NamedIdea n => n -> Sentence
titleize IdeaDict
output_ Sentence -> ConceptInstance -> Sentence
forall r.
(Referable r, HasShortName r) =>
Sentence -> r -> Sentence
`follows`
    ConceptInstance
displayInput) Bool
True

{-Nonfunctional Requirements-}
nonFuncReqs :: [ConceptInstance]
nonFuncReqs :: [ConceptInstance]
nonFuncReqs = [ConceptInstance
correct, ConceptInstance
understandable, ConceptInstance
reusable, ConceptInstance
maintainable]

correct :: ConceptInstance
correct :: ConceptInstance
correct = String -> String -> ConceptInstance
mkCorrectNFR String
"correct" String
"Correctness"

understandable :: ConceptInstance
understandable :: ConceptInstance
understandable = String -> String -> ConceptInstance
mkUnderstandableNFR String
"understandable" String
"Understandability"

reusable :: ConceptInstance
reusable :: ConceptInstance
reusable = String -> String -> ConceptInstance
mkReusableNFR String
"reusable" String
"Reusability"

maintainable :: ConceptInstance
maintainable :: ConceptInstance
maintainable = String -> Integer -> String -> ConceptInstance
mkMaintainableNFR String
"maintainable" Integer
10 String
"Maintainability"