module Music.Instrument.Piano where 

import Data.List
import Data.Maybe
import Music.Instrument.Common

import Music.Diatonic hiding (transpose)
import Music.Diatonic.Note hiding (transpose)
import Music.Diatonic.Degree
import Music.Diatonic.Chord

renderPianoChord annotation chord = renderPianoPositions annotation (levelChord degrees)
    where degrees = extractDegrees chord

renderPianoPositions annotation positions = foldl (markPiano annotation) cleanPiano positions

markPiano marking piano position = replaceAt (getPianoPositionCharacterIndex position) marking' piano
    where marking' = case marking of 
                       AnnotateMarking -> '*'
                       AnnotatePosition -> head (show position)
                       AnnotateNote -> abbreviateNote $ tuningAndPosToNote C position
    

cleanPiano = map (\x -> if elem x pianoMarkings then ' ' else x ) markedPiano

getPianoPositionCharacterIndex pos = fromJust (elemIndex (pianoMarkings !! pos) markedPiano)

pianoMarkings = ['a'..'l']

twoOctavePiano = unlines $ zipWith (++) (lines cleanPiano) ( map (drop 1) $ lines cleanPiano)

interleave = concat . transpose

markedPiano = unlines
        [
         " ____________________ "
        ,"| |b||d| | |g||i||k| |"
        ,"| |_||_| | |_||_||_| |"
        ,"|a |c |e |f |h |j |l |"
        ,"|__|__|__|__|__|__|__|"
        ]
        
replaceAt i v xs = map (\(x,i') -> if i==i' then v else x) $  zip xs [0..]