-- Copyright 2013 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

-- | Predefined meters.
--
-- Defined separate from "Cmd.Meter" so you can redefine them without reloading
-- everything that depends on Cmd.Meter.
module Ui.Meter.Meters where
import qualified Ui.Meter.Meter as Meter
import           Ui.Meter.Meter (AbstractMeter(..), regular_subdivision)


-- half/measure, quarter/half, eighth/quarter, ...
-- These use 1s to help keep the timestep mnemonics in sync with staff notation
-- durations, as documented in "Cmd.Meter".
m84, m64, m54, m44, m34 :: AbstractMeter
m84 :: AbstractMeter
m84 = [Int] -> AbstractMeter
regular_subdivision [Int
4, Int
2, Int
2, Int
2, Int
2]
m64 :: AbstractMeter
m64 = [Int] -> AbstractMeter
regular_subdivision [Int
2, Int
3, Int
2, Int
2, Int
2]
m54 :: AbstractMeter
m54 = [Int] -> AbstractMeter
regular_subdivision [Int
1, Int
5, Int
2, Int
2, Int
2]
m44 :: AbstractMeter
m44 = [Int] -> AbstractMeter
regular_subdivision [Int
2, Int
2, Int
2, Int
2, Int
2]
m34 :: AbstractMeter
m34 = [Int] -> AbstractMeter
regular_subdivision [Int
1, Int
3, Int
2, Int
2, Int
2]
m24 :: AbstractMeter
m24 = [Int] -> AbstractMeter
regular_subdivision [Int
1, Int
2, Int
2, Int
2, Int
2]
m14 :: AbstractMeter
m14 = [Int] -> AbstractMeter
regular_subdivision [Int
1, Int
1, Int
2, Int
2, Int
2]

m98 :: AbstractMeter
m98 :: AbstractMeter
m98 = [Int] -> AbstractMeter
regular_subdivision [Int
1, Int
3, Int
3, Int
2, Int
2]

simple :: Int -> Int -> Maybe AbstractMeter
simple :: Int -> Int -> Maybe AbstractMeter
simple Int
num Int
denom = case (Int
num, Int
denom) of
    (Int
8, Int
4) -> forall a. a -> Maybe a
Just AbstractMeter
m84
    (Int
6, Int
4) -> forall a. a -> Maybe a
Just AbstractMeter
m64
    (Int
5, Int
4) -> forall a. a -> Maybe a
Just AbstractMeter
m54
    (Int
4, Int
4) -> forall a. a -> Maybe a
Just AbstractMeter
m44
    (Int
3, Int
4) -> forall a. a -> Maybe a
Just AbstractMeter
m34
    (Int
2, Int
4) -> forall a. a -> Maybe a
Just AbstractMeter
m24
    (Int
1, Int
4) -> forall a. a -> Maybe a
Just AbstractMeter
m14
    (Int
8, Int
8) -> forall a. a -> Maybe a
Just AbstractMeter
m44
    (Int, Int)
_ -> forall a. Maybe a
Nothing
    -- TODO I can't just enumerate everything.  Isn't there some way I can
    -- automatically derive the regular_subdivision?
    -- Barline duration is: num/denom
    -- The problem is I have to use integral subdivisions.

-- | 4 * 4/4 bars.
m44_4 :: AbstractMeter
m44_4 :: AbstractMeter
m44_4 = Int -> AbstractMeter -> AbstractMeter
Meter.repeat Int
4 AbstractMeter
m44

-- | 4 sections of 4/4 bars.
--
-- @LRuler.modify =<< LRuler.fit_to_end Meters.m44_block block_id@
m44_block :: [AbstractMeter]
m44_block :: [AbstractMeter]
m44_block = forall a. Int -> a -> [a]
replicate Int
4 AbstractMeter
m44_4

m3p3p2_8 :: AbstractMeter
m3p3p2_8 :: AbstractMeter
m3p3p2_8 = Int -> AbstractMeter -> AbstractMeter
Meter.repeat Int
1 forall a b. (a -> b) -> a -> b
$ [Int] -> AbstractMeter -> AbstractMeter
Meter.subdivides [Int
2, Int
2, Int
2, Int
2] forall a b. (a -> b) -> a -> b
$
    [AbstractMeter] -> AbstractMeter
D [[AbstractMeter] -> AbstractMeter
D [AbstractMeter
T, AbstractMeter
T, AbstractMeter
T], [AbstractMeter] -> AbstractMeter
D [AbstractMeter
T, AbstractMeter
T, AbstractMeter
T], [AbstractMeter] -> AbstractMeter
D [AbstractMeter
T, AbstractMeter
T]]

-- | 2+2+2 / 8, 4 quarters per measure
m2p2p2_8 :: AbstractMeter
m2p2p2_8 :: AbstractMeter
m2p2p2_8 = [Int] -> AbstractMeter
regular_subdivision [Int
1, Int
3, Int
2, Int
2, Int
2, Int
2]

-- | 3+3 / 8, 2 dotted quarters per measure
m3p3_8 :: AbstractMeter
m3p3_8 :: AbstractMeter
m3p3_8 = [Int] -> AbstractMeter
regular_subdivision [Int
1, Int
2, Int
3, Int
2, Int
2, Int
2]