-- |
-- Module      :  Phladiprelio.Ukrainian.ReadDurations
-- Copyright   :  (c) OleksandrZhabenko 2021-2024
-- License     :  MIT
-- Stability   :  Experimental
-- Maintainer  :  oleksandr.zhabenko@yahoo.com
--
-- Functions to read the properties data from the files with the special Haskell-like syntaxis.

{-# LANGUAGE BangPatterns, NoImplicitPrelude #-}

module Phladiprelio.Ukrainian.ReadDurations where

import GHC.Base
import CaseBi.Arr (getBFstLSorted')
import Phladiprelio.Ukrainian.SyllableDouble
import Text.Read (readMaybe)
import Data.Maybe
import System.IO
import GHC.List
import Data.List (unlines,lines)
import System.Directory (doesFileExist)
import Phladiprelio.Ukrainian.Melodics


{-| For more information on implementation, please refer to the link:
 
<https://oleksandr-zhabenko.github.io/uk/rhythmicity/PhLADiPreLiO.Eng.21.html#ability-to-use-your-own-durations-of-representations-of-sounds-or-phonetic-phenomena> 
-}
sound8s :: FlowSound
sound8s :: FlowSound
sound8s = [Sound8
1,Sound8
2,Sound8
3,Sound8
4,Sound8
5,Sound8
6,Sound8
7,Sound8
8,Sound8
9,Sound8
10,Sound8
11,Sound8
15,Sound8
16,Sound8
17,Sound8
18,Sound8
19,Sound8
20,Sound8
21,Sound8
22,Sound8
23,Sound8
24,Sound8
25,Sound8
26,Sound8
27,Sound8
28,Sound8
29,Sound8
30,Sound8
31,Sound8
32,Sound8
33,Sound8
34,Sound8
35,Sound8
36,Sound8
37,Sound8
38,Sound8
39,Sound8
40,Sound8
41,Sound8
42,
   Sound8
43,Sound8
44,Sound8
45,Sound8
46,Sound8
47,Sound8
48,Sound8
49,Sound8
50,Sound8
51,Sound8
52,Sound8
53,Sound8
54,Sound8
66,Sound8
101]



{-|

The first number is the default value that corresponds usually to the word gap duration (and here is not important).
The next 52 'Double' numbers become the durations of the above specified 'Sound8' values respectively, the order
must be preserved (if you consider it important, well, it should be!). If some number in the file cannot be read
as a 'Double' number the function uses the first one that can be instead (the default value). If no such is specified
at all, then the default number is 1.0 for all the 'Sound8' sound representations that is hardly correct.

-}
readSound8ToDouble :: String -> (Double,[(Sound8, Double)])
readSound8ToDouble :: String -> (Double, [(Sound8, Double)])
readSound8ToDouble String
xs
 | String -> Bool
forall a. [a] -> Bool
null String
xs = (Double
1.0,FlowSound -> [Double] -> [(Sound8, Double)]
forall a b. [a] -> [b] -> [(a, b)]
zip FlowSound
sound8s ([Double] -> [(Sound8, Double)])
-> (Double -> [Double]) -> Double -> [(Sound8, Double)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Double -> [Double]
forall a. Int -> a -> [a]
replicate Int
10000 (Double -> [(Sound8, Double)]) -> Double -> [(Sound8, Double)]
forall a b. (a -> b) -> a -> b
$ Double
1.0)
 | Bool
otherwise =
    let wws :: [String]
wws = String -> [String]
lines String
xs
        dbls :: [Maybe Double]
dbls = (String -> Maybe Double) -> [String] -> [Maybe Double]
forall a b. (a -> b) -> [a] -> [b]
map (\String
ks -> String -> Maybe Double
forall a. Read a => String -> Maybe a
readMaybe String
ks::Maybe Double) [String]
wws
        dbH :: Double
dbH
         | [Maybe Double] -> Bool
forall a. [a] -> Bool
null [Maybe Double]
dbls Bool -> Bool -> Bool
|| (Maybe Double -> Bool) -> [Maybe Double] -> Bool
forall a. (a -> Bool) -> [a] -> Bool
all Maybe Double -> Bool
forall a. Maybe a -> Bool
isNothing [Maybe Double]
dbls = Double
1.0
         | Bool
otherwise = Maybe Double -> Double
forall a. HasCallStack => Maybe a -> a
fromJust (Maybe Double -> Double)
-> ([Maybe Double] -> Maybe Double) -> [Maybe Double] -> Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe Double] -> Maybe Double
forall a. HasCallStack => [a] -> a
head ([Maybe Double] -> Maybe Double)
-> ([Maybe Double] -> [Maybe Double])
-> [Maybe Double]
-> Maybe Double
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Maybe Double -> Bool) -> [Maybe Double] -> [Maybe Double]
forall a. (a -> Bool) -> [a] -> [a]
filter Maybe Double -> Bool
forall a. Maybe a -> Bool
isJust ([Maybe Double] -> Double) -> [Maybe Double] -> Double
forall a b. (a -> b) -> a -> b
$ [Maybe Double]
dbls
        dbSs :: [Double]
dbSs = (Maybe Double -> Double) -> [Maybe Double] -> [Double]
forall a b. (a -> b) -> [a] -> [b]
map (Double -> Maybe Double -> Double
forall a. a -> Maybe a -> a
fromMaybe Double
dbH) [Maybe Double]
dbls
        (Double
firstD,[(Sound8, Double)]
lsts)
          | [Maybe Double] -> Bool
forall a. [a] -> Bool
null [Maybe Double]
dbls = (Double
1.0,FlowSound -> [Double] -> [(Sound8, Double)]
forall a b. [a] -> [b] -> [(a, b)]
zip FlowSound
sound8s ([Double] -> [(Sound8, Double)])
-> (Double -> [Double]) -> Double -> [(Sound8, Double)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Double -> [Double]
forall a. Int -> a -> [a]
replicate Int
10000 (Double -> [(Sound8, Double)]) -> Double -> [(Sound8, Double)]
forall a b. (a -> b) -> a -> b
$ Double
1.0)
          | Bool
otherwise = (Double
dbH,FlowSound -> [Double] -> [(Sound8, Double)]
forall a b. [a] -> [b] -> [(a, b)]
zip FlowSound
sound8s ([Double]
dbSs [Double] -> [Double] -> [Double]
forall a. Monoid a => a -> a -> a
`mappend` Int -> Double -> [Double]
forall a. Int -> a -> [a]
replicate Int
10000 Double
1.0))
            in (Double
firstD,[(Sound8, Double)]
lsts)

divide2SDDs :: String -> [String]
divide2SDDs :: String -> [String]
divide2SDDs String
ys
 | [String] -> Bool
forall a. [a] -> Bool
null [String]
tss = [[String] -> String
unlines [String]
kss]
 | Bool
otherwise = [String] -> String
unlines [String]
kss String -> [String] -> [String]
forall a. a -> [a] -> [a]
: String -> [String]
divide2SDDs ([String] -> String
unlines [String]
rss)
     where wwss :: [String]
wwss = String -> [String]
lines String
ys
           ([String]
kss,[String]
tss) = (String -> Bool) -> [String] -> ([String], [String])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break ((Char -> Bool) -> String -> Bool
forall a. (a -> Bool) -> [a] -> Bool
any (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
'*')) [String]
wwss
           rss :: [String]
rss = (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
dropWhile ((Char -> Bool) -> String -> Bool
forall a. (a -> Bool) -> [a] -> Bool
any (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'*')) [String]
tss

readSyllableDurations :: FilePath -> IO [[[[Sound8]]] -> [[Double]]]
readSyllableDurations :: String -> IO [[[FlowSound]] -> [[Double]]]
readSyllableDurations String
file = do
  Bool
exists <- String -> IO Bool
doesFileExist String
file
  if Bool
exists then do 
   String
xs <- String -> IO String
readFile String
file
   let yss :: [String]
yss = Int -> [String] -> [String]
forall a. Int -> [a] -> [a]
take Int
9 ([String] -> [String])
-> (String -> [String]) -> String -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
divide2SDDs (String -> [String]) -> String -> [String]
forall a b. (a -> b) -> a -> b
$ String
xs
       readData :: [(Double, [(Sound8, Double)])]
readData = (String -> (Double, [(Sound8, Double)]))
-> [String] -> [(Double, [(Sound8, Double)])]
forall a b. (a -> b) -> [a] -> [b]
map String -> (Double, [(Sound8, Double)])
readSound8ToDouble [String]
yss
   [[[FlowSound]] -> [[Double]]] -> IO [[[FlowSound]] -> [[Double]]]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([[[FlowSound]] -> [[Double]]] -> IO [[[FlowSound]] -> [[Double]]])
-> ([(Double, [(Sound8, Double)])]
    -> [[[FlowSound]] -> [[Double]]])
-> [(Double, [(Sound8, Double)])]
-> IO [[[FlowSound]] -> [[Double]]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Double, [(Sound8, Double)]) -> [[FlowSound]] -> [[Double]])
-> [(Double, [(Sound8, Double)])] -> [[[FlowSound]] -> [[Double]]]
forall a b. (a -> b) -> [a] -> [b]
map (\(Double
d,[(Sound8, Double)]
zs) -> (Sound8 -> Double) -> [[FlowSound]] -> [[Double]]
forall a.
SyllableDurations4 a =>
(a -> Double) -> [[[a]]] -> [[Double]]
syllableDurationsGDc (Double -> [(Sound8, Double)] -> Sound8 -> Double
forall a b. Ord a => b -> [(a, b)] -> a -> b
getBFstLSorted' Double
d [(Sound8, Double)]
zs)) ([(Double, [(Sound8, Double)])]
 -> IO [[[FlowSound]] -> [[Double]]])
-> [(Double, [(Sound8, Double)])]
-> IO [[[FlowSound]] -> [[Double]]]
forall a b. (a -> b) -> a -> b
$ [(Double, [(Sound8, Double)])]
readData
  else [[[FlowSound]] -> [[Double]]] -> IO [[[FlowSound]] -> [[Double]]]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []