module Sound.Tidal.Bjorklund (bjorklund) where

-- The below is (c) Rohan Drape, taken from the hmt library and
-- distributed here under the terms of the GNU Public Licence.  Tidal
-- used to just include the library but removed for now due to
-- dependency problems.. We could however likely benefit from other
-- parts of the library..

type STEP a = ((Int,Int),([[a]],[[a]]))

left :: STEP a -> STEP a
left :: STEP a -> STEP a
left ((i :: Int
i,j :: Int
j),(xs :: [[a]]
xs,ys :: [[a]]
ys)) =
    let (xs' :: [[a]]
xs',xs'' :: [[a]]
xs'') = Int -> [[a]] -> ([[a]], [[a]])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
j [[a]]
xs
    in ((Int
j,Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
j),(([a] -> [a] -> [a]) -> [[a]] -> [[a]] -> [[a]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
(++) [[a]]
xs' [[a]]
ys,[[a]]
xs''))

right :: STEP a -> STEP a
right :: STEP a -> STEP a
right ((i :: Int
i,j :: Int
j),(xs :: [[a]]
xs,ys :: [[a]]
ys)) =
    let (ys' :: [[a]]
ys',ys'' :: [[a]]
ys'') = Int -> [[a]] -> ([[a]], [[a]])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
i [[a]]
ys
    in ((Int
i,Int
jInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
i),(([a] -> [a] -> [a]) -> [[a]] -> [[a]] -> [[a]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
(++) [[a]]
xs [[a]]
ys',[[a]]
ys''))

bjorklund' :: STEP a -> STEP a
bjorklund' :: STEP a -> STEP a
bjorklund' (n :: (Int, Int)
n,x :: ([[a]], [[a]])
x) =
    let (i :: Int
i,j :: Int
j) = (Int, Int)
n
    in if Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
i Int
j Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= 1
       then ((Int, Int)
n,([[a]], [[a]])
x)
       else STEP a -> STEP a
forall a. STEP a -> STEP a
bjorklund' (if Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
j then STEP a -> STEP a
forall a. STEP a -> STEP a
left ((Int, Int)
n,([[a]], [[a]])
x) else STEP a -> STEP a
forall a. STEP a -> STEP a
right ((Int, Int)
n,([[a]], [[a]])
x))

bjorklund :: (Int,Int) -> [Bool]
bjorklund :: (Int, Int) -> [Bool]
bjorklund (i :: Int
i,j' :: Int
j') =
    let j :: Int
j = Int
j' Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
i
        x :: [[Bool]]
x = Int -> [Bool] -> [[Bool]]
forall a. Int -> a -> [a]
replicate Int
i [Bool
True]
        y :: [[Bool]]
y = Int -> [Bool] -> [[Bool]]
forall a. Int -> a -> [a]
replicate Int
j [Bool
False]
        (_,(x' :: [[Bool]]
x',y' :: [[Bool]]
y')) = ((Int, Int), ([[Bool]], [[Bool]]))
-> ((Int, Int), ([[Bool]], [[Bool]]))
forall a. STEP a -> STEP a
bjorklund' ((Int
i,Int
j),([[Bool]]
x,[[Bool]]
y))
    in [[Bool]] -> [Bool]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Bool]]
x' [Bool] -> [Bool] -> [Bool]
forall a. [a] -> [a] -> [a]
++ [[Bool]] -> [Bool]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Bool]]
y'