-- Copyright 2018 Evan Laforge
-- This program is distributed under the terms of the GNU General Public
-- License 3.0, see COPYING or http://www.gnu.org/licenses/gpl-3.0.txt

-- | DSL functions to add metadata to Korvais.
module Solkattu.Dsl.Metadata (
    comment, date, source, similarTo
    , recording
    , korvaiT, koraippu, mohra, mohraKorvai, sarvalaghu, tirmanam
    , sequenceT, faran, exercise, trikalam
    , withType
) where
import qualified Util.CallStack as CallStack
import qualified Solkattu.Korvai as Korvai
import Solkattu.Korvai (Korvai)
import qualified Solkattu.Metadata as Metadata
import qualified Solkattu.Tags as Tags

import Global


-- | Attach a generic comment.
comment :: Text -> Korvai -> Korvai
comment :: Text -> Korvai -> Korvai
comment = Text -> Text -> Korvai -> Korvai
withTag Text
Tags.comment

date :: CallStack.Stack => Int -> Int -> Int -> Korvai -> Korvai
date :: Stack => Int -> Int -> Int -> Korvai -> Korvai
date Int
y Int
m Int
d = Metadata -> Korvai -> Korvai
Korvai.withKorvaiMetadata (Metadata -> Korvai -> Korvai) -> Metadata -> Korvai -> Korvai
forall a b. (a -> b) -> a -> b
$ Metadata
forall a. Monoid a => a
mempty { _date :: Maybe Day
Korvai._date = Day -> Maybe Day
forall a. a -> Maybe a
Just Day
date }
    where !date :: Day
date = Stack => Int -> Int -> Int -> Day
Int -> Int -> Int -> Day
Metadata.makeDate Int
y Int
m Int
d

-- | Where or from who I learned it.
source :: Text -> Korvai -> Korvai
source :: Text -> Korvai -> Korvai
source = Text -> Text -> Korvai -> Korvai
withTag Text
Tags.source

-- | This could be considered a variant of the other.  Takes "Module"
-- "variableName", since the location is added later in "Solkattu.All".
-- The link is verified in Db_test.
similarTo :: Text -> Text -> Korvai -> Korvai
similarTo :: Text -> Text -> Korvai -> Korvai
similarTo Text
module_ Text
variableName =
    Text -> Text -> Korvai -> Korvai
withTag Text
Tags.similarTo (Text
module_ Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"." Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
variableName)

-- | A recording where the clip is played.
recording :: CallStack.Stack => Text -- ^ URL to the recording or video
    -> Maybe (Metadata.Time, Metadata.Time)
    -- ^ start and end time of the clip within the recording
    -> Korvai -> Korvai
recording :: Stack => Text -> Maybe (Time, Time) -> Korvai -> Korvai
recording Text
url Maybe (Time, Time)
maybeRange =
    Text -> Text -> Korvai -> Korvai
withTag Text
Tags.recording (Stack => Text -> Maybe (Time, Time) -> Text
Text -> Maybe (Time, Time) -> Text
Metadata.showRecording Text
url Maybe (Time, Time)
maybeRange)

-- * types

korvaiT :: Korvai -> Korvai
korvaiT :: Korvai -> Korvai
korvaiT = Text -> Korvai -> Korvai
withType Text
"korvai"

koraippu :: Korvai -> Korvai
koraippu :: Korvai -> Korvai
koraippu = Text -> Korvai -> Korvai
withType Text
"koraippu"

mohra :: Korvai -> Korvai
mohra :: Korvai -> Korvai
mohra = Text -> Korvai -> Korvai
withType Text
"mohra"

mohraKorvai :: Korvai -> Korvai
mohraKorvai :: Korvai -> Korvai
mohraKorvai = Text -> Korvai -> Korvai
withType Text
"mohra-korvai"

sarvalaghu :: Korvai -> Korvai
sarvalaghu :: Korvai -> Korvai
sarvalaghu = Text -> Korvai -> Korvai
withType Text
"sarvalaghu"

-- | A short cadence, suitable to end a phrase or section.
tirmanam :: Korvai -> Korvai
tirmanam :: Korvai -> Korvai
tirmanam = Text -> Korvai -> Korvai
withType Text
"tirmanam"

-- | A development sequence, possibly leading to a korvai.
sequenceT :: Korvai -> Korvai
sequenceT :: Korvai -> Korvai
sequenceT = Text -> Korvai -> Korvai
withType Text
"sequence"

faran :: Korvai -> Korvai
faran :: Korvai -> Korvai
faran = Text -> Korvai -> Korvai
withType Text
"faran"

exercise :: Korvai -> Korvai
exercise :: Korvai -> Korvai
exercise =
    Text -> Text -> Korvai -> Korvai
replaceSectionTags Text
Tags.type_ Text
Tags.exercise (Korvai -> Korvai) -> (Korvai -> Korvai) -> Korvai -> Korvai
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Korvai -> Korvai
withType Text
Tags.exercise
    -- Replace the inferred development and ending types, exercises generally
    -- don't have those things.

trikalam :: Korvai -> Korvai
trikalam :: Korvai -> Korvai
trikalam = Text -> Korvai -> Korvai
withType Text
"trikalam"

withType :: Text -> Korvai -> Korvai
withType :: Text -> Korvai -> Korvai
withType = Text -> Text -> Korvai -> Korvai
withTag Text
Tags.type_

-- * util

withTag :: Text -> Text -> Korvai -> Korvai
withTag :: Text -> Text -> Korvai -> Korvai
withTag Text
k Text
v = Metadata -> Korvai -> Korvai
Korvai.withKorvaiMetadata (Metadata -> Korvai -> Korvai) -> Metadata -> Korvai -> Korvai
forall a b. (a -> b) -> a -> b
$
    Metadata
forall a. Monoid a => a
mempty { _tags :: Tags
Korvai._tags = Text -> Text -> Tags
Tags.tag Text
k Text
v }

replaceSectionTags :: Text -> Text -> Korvai -> Korvai
replaceSectionTags :: Text -> Text -> Korvai -> Korvai
replaceSectionTags Text
k Text
v = (Tags -> Tags) -> Korvai -> Korvai
Korvai.modifySections ((Tags -> Tags) -> Korvai -> Korvai)
-> (Tags -> Tags) -> Korvai -> Korvai
forall a b. (a -> b) -> a -> b
$ Text -> Text -> Tags -> Tags
Tags.replace Text
k Text
v