{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE NamedFieldPuns #-}

module Modelling.ActivityDiagram.Config (
  AdConfig (..),
  defaultAdConfig,
  checkAdConfig,
) where

import GHC.Generics (Generic)

data AdConfig = AdConfig {
  AdConfig -> (Int, Int)
actionLimits :: !(Int, Int),
  AdConfig -> (Int, Int)
objectNodeLimits :: !(Int, Int),
  AdConfig -> Int
maxNamedNodes :: Int,
  AdConfig -> Int
decisionMergePairs :: Int,
  AdConfig -> Int
forkJoinPairs :: Int,
  AdConfig -> Int
activityFinalNodes :: Int,
  AdConfig -> Int
flowFinalNodes :: Int,
  AdConfig -> Int
cycles :: Int
} deriving ((forall x. AdConfig -> Rep AdConfig x)
-> (forall x. Rep AdConfig x -> AdConfig) -> Generic AdConfig
forall x. Rep AdConfig x -> AdConfig
forall x. AdConfig -> Rep AdConfig x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. AdConfig -> Rep AdConfig x
from :: forall x. AdConfig -> Rep AdConfig x
$cto :: forall x. Rep AdConfig x -> AdConfig
to :: forall x. Rep AdConfig x -> AdConfig
Generic, ReadPrec [AdConfig]
ReadPrec AdConfig
Int -> ReadS AdConfig
ReadS [AdConfig]
(Int -> ReadS AdConfig)
-> ReadS [AdConfig]
-> ReadPrec AdConfig
-> ReadPrec [AdConfig]
-> Read AdConfig
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS AdConfig
readsPrec :: Int -> ReadS AdConfig
$creadList :: ReadS [AdConfig]
readList :: ReadS [AdConfig]
$creadPrec :: ReadPrec AdConfig
readPrec :: ReadPrec AdConfig
$creadListPrec :: ReadPrec [AdConfig]
readListPrec :: ReadPrec [AdConfig]
Read, Int -> AdConfig -> ShowS
[AdConfig] -> ShowS
AdConfig -> String
(Int -> AdConfig -> ShowS)
-> (AdConfig -> String) -> ([AdConfig] -> ShowS) -> Show AdConfig
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> AdConfig -> ShowS
showsPrec :: Int -> AdConfig -> ShowS
$cshow :: AdConfig -> String
show :: AdConfig -> String
$cshowList :: [AdConfig] -> ShowS
showList :: [AdConfig] -> ShowS
Show)

defaultAdConfig :: AdConfig
defaultAdConfig :: AdConfig
defaultAdConfig = AdConfig
  { actionLimits :: (Int, Int)
actionLimits = (Int
4, Int
4),
    objectNodeLimits :: (Int, Int)
objectNodeLimits = (Int
1, Int
1),
    maxNamedNodes :: Int
maxNamedNodes = Int
5,
    decisionMergePairs :: Int
decisionMergePairs = Int
1,
    forkJoinPairs :: Int
forkJoinPairs = Int
1,
    activityFinalNodes :: Int
activityFinalNodes = Int
1,
    flowFinalNodes :: Int
flowFinalNodes = Int
1,
    cycles :: Int
cycles = Int
1
  }

checkAdConfig :: AdConfig -> Maybe String
checkAdConfig :: AdConfig -> Maybe String
checkAdConfig AdConfig {
    (Int, Int)
actionLimits :: AdConfig -> (Int, Int)
actionLimits :: (Int, Int)
actionLimits,
    (Int, Int)
objectNodeLimits :: AdConfig -> (Int, Int)
objectNodeLimits :: (Int, Int)
objectNodeLimits,
    Int
maxNamedNodes :: AdConfig -> Int
maxNamedNodes :: Int
maxNamedNodes,
    Int
decisionMergePairs :: AdConfig -> Int
decisionMergePairs :: Int
decisionMergePairs,
    Int
forkJoinPairs :: AdConfig -> Int
forkJoinPairs :: Int
forkJoinPairs,
    Int
activityFinalNodes :: AdConfig -> Int
activityFinalNodes :: Int
activityFinalNodes,
    Int
flowFinalNodes :: AdConfig -> Int
flowFinalNodes :: Int
flowFinalNodes,
    Int
cycles :: AdConfig -> Int
cycles :: Int
cycles
  }
  | (Int, Int) -> Int
forall a b. (a, b) -> a
fst (Int, Int)
actionLimits Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0
    = String -> Maybe String
forall a. a -> Maybe a
Just String
"Minimum number of Actions must be non-negative"
  | (Int -> Int -> Bool) -> (Int, Int) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(>) (Int, Int)
actionLimits
    = String -> Maybe String
forall a. a -> Maybe a
Just String
"Maximal number of Actions must not be larger than the minimum number"
  | (Int, Int) -> Int
forall a b. (a, b) -> a
fst (Int, Int)
objectNodeLimits Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0
    = String -> Maybe String
forall a. a -> Maybe a
Just String
"Minimum number of Object Nodes must be non-negative"
  | (Int -> Int -> Bool) -> (Int, Int) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
(>) (Int, Int)
objectNodeLimits
    = String -> Maybe String
forall a. a -> Maybe a
Just String
"Maximal number of Object Nodes must not be larger than the minimum number"
  | (Int, Int) -> Int
forall a b. (a, b) -> a
fst (Int, Int)
actionLimits Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int, Int) -> Int
forall a b. (a, b) -> a
fst (Int, Int)
objectNodeLimits Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0
    = String -> Maybe String
forall a. a -> Maybe a
Just String
"Minimum number of Actions and Object Nodes together must be positive"
  | (Int, Int) -> Int
forall a b. (a, b) -> a
fst (Int, Int)
actionLimits Int -> Int -> Int
forall a. Num a => a -> a -> a
+ (Int, Int) -> Int
forall a b. (a, b) -> a
fst (Int, Int)
objectNodeLimits Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
maxNamedNodes
    = String -> Maybe String
forall a. a -> Maybe a
Just String
"Minimal number of Actions and Object Nodes together must not be larger than maximum number of Named Nodes"
  | Int
decisionMergePairs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0
    = String -> Maybe String
forall a. a -> Maybe a
Just String
"Number of Decision and Merge pairs must be non-negative"
  | Int
forkJoinPairs Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0
    = String -> Maybe String
forall a. a -> Maybe a
Just String
"Number of Fork and Join pairs must be non-negative"
  | Int
activityFinalNodes Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0
    = String -> Maybe String
forall a. a -> Maybe a
Just String
"Number of Activity Final Nodes must be non-negative"
  | Int
flowFinalNodes Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0
    = String -> Maybe String
forall a. a -> Maybe a
Just String
"Number of Flow Final Nodes must be non-negative"
  | Int
activityFinalNodes Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
flowFinalNodes Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
0
    = String -> Maybe String
forall a. a -> Maybe a
Just String
"Total number of Final Nodes must be positive"
  | Int
activityFinalNodes Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
flowFinalNodes Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
forkJoinPairs
    = String -> Maybe String
forall a. a -> Maybe a
Just String
"Total number of Final Nodes must be less or equal to the number of Fork and Join pairs plus one"
  | Int
cycles Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
decisionMergePairs
    = String -> Maybe String
forall a. a -> Maybe a
Just String
"Number of Cycles must be less or equal to the number of Decision and Merge pairs"
  | Bool
otherwise
    = Maybe String
forall a. Maybe a
Nothing