{-# LANGUAGE NoMonomorphismRestriction, TypeFamilies, FlexibleContexts #-}

module Music.Graphics.Diagrams (
        -- draw,
        -- writeGraphic,
        -- openGraphic
) where

-- import Music.Score
-- import Music.Pitch
-- import Diagrams.Prelude hiding (Time, Duration)
-- import qualified Diagrams.Backend.SVG as SVG
-- 
-- -- test       
-- import Music.Prelude.Basic
-- import Control.Lens
-- import System.Process
-- import Text.Blaze.Svg.Renderer.Utf8 (renderSvg)
-- import qualified Data.ByteString.Lazy as ByteString
-- 
-- 
-- timeToDouble :: Time -> Double
-- timeToDouble = realToFrac . (.-. origin)
-- durationToDouble :: Duration -> Double
-- durationToDouble = realToFrac
-- pitchToDouble :: Music.Pitch.Pitch -> Double
-- pitchToDouble = realToFrac . semitones . (.-. c)
-- 
-- draw :: (Renderable (Path R2) b, Real a) => Score a -> Diagram b R2
-- draw = bg whitesmoke . scaleX 20{-TODO-} . mconcat . fmap drawNote . fmap (map1 timeToDouble . map2 durationToDouble . map3 realToFrac) . (^. events)
--     where
--         map1 f (a,b,c) = (f a,b,c)
--         map2 f (a,b,c) = (a,f b,c)
--         map3 f (a,b,c) = (a,b,f c)
--         drawNote (t,d,x) = translateY x $ translateX (t.+^(d^/2)) $ scaleX d $ noteShape
--         noteShape = lcA transparent $ fcA (blue  `withOpacity` 0.5) $ square 1
-- 
-- writeGraphic :: FilePath -> Score Double -> IO ()
-- writeGraphic path x = do
--     let dia = draw x
--     let svg = renderDia SVG.SVG (SVG.SVGOptions (Dims 1800 (1800/20)) Nothing) dia
--     let bs  = renderSvg svg
--     ByteString.writeFile path bs
--         
-- openGraphic :: Score Double -> IO ()
-- openGraphic x = do
--     writeGraphic "test.svg" x
--     -- FIXME find best reader
--     system "open -a Firefox test.svg"
--     return ()









-- drawScores
--     :: (Integral p, p ~ Pitch b, HasPitch b, Voice b ~ NotePart, HasVoice b)
--     => Score b -> Score c -> Diagram SVG R2
-- drawScores notes cmds = notes1D <> notes2D <> cmdsD <> middleLines <> crossLines
--     where
--         notes1 = mfilter (\x -> getPartGroup (getVoice x) == 1) notes
--         notes2 = mfilter (\x -> getPartGroup (getVoice x) == 2) notes
-- 
--         notes1D     = mconcat $ fmap (drawNote 1) $ perform notes1
--         notes2D     = mconcat $ fmap (drawNote 2) $ perform notes2
--         cmdsD       = mconcat $ fmap drawCmd $ perform cmds
--         middleLines = translateX ((/ 2) $ totalDur) (hrule $ totalDur)
--         crossLines  = mconcat $ fmap (\n -> translateX ((totalDur/5) * n) (vrule 100)) $ [0..5]
-- 
--         drawNote n (t,d,x) = translateY (getP x + off n) $ translateX (getT (t.+^(d^/2))) $ scaleX (getD d) $ noteShape n
--         off 1 = 50
--         off 2 = (-50)
--         drawCmd (t,d,x) = translateY 0 $ translateX (getT t) $ cmdShape
-- 
--         noteShape 1 = lcA transparent $ fcA (blue  `withOpacity` 0.3) $ square 1
--         noteShape 2 = lcA transparent $ fcA (green `withOpacity` 0.3) $ square 1
--         cmdShape = lcA (red `withOpacity` 0.3) $ vrule (200)
-- 
--         totalDur = getD $ duration notes
--         getT = fromRational . toRational
--         getD = fromRational . toRational
--         getP = (subtract 60) . fromIntegral . getPitch