-- | SDIF (Sound Description Interchange Format)
module Sound.SDIF where

import qualified Data.ByteString.Lazy as B
import Sound.SDIF.Byte.SDIF
import Sound.SDIF.Frame
import Sound.SDIF.Matrix
import Sound.SDIF.Type

-- | SDIF data store.
data SDIF = SDIF { sdif_b :: B.ByteString
                 , sdif_frames :: Int
                 , sdif_frame_i :: [(Int, Int)]
                 , sdif_frame_c :: [Frame] }
            deriving (Eq, Show)

-- | Decode 'SDIF' data stream.
decode_sdif :: B.ByteString -> SDIF
decode_sdif sdf =
    let n = sdif_b_frames sdf
        ix = sdif_b_frame_i sdf n
        frm (i,j) = decode_frame (section' sdf i j)
        s = SDIF { sdif_b = sdf
                 , sdif_frames = n
                 , sdif_frame_i = ix
                 , sdif_frame_c = map frm ix }
    in if is_sdif_b sdf
       then s
       else error "decode_sdif" "illegal data"

-- | Read and decode 'SDIF' from named file.
sdif_read_file :: FilePath -> IO SDIF
sdif_read_file file_name = do
  b <- B.readFile file_name
  return (decode_sdif b)

-- | Extract /n/th frame data from 'SDIF'.
sdif_frame_b :: SDIF -> Int -> B.ByteString
sdif_frame_b sdf n =
    let (i,j) = sdif_frame_i sdf !! n
    in (section' (sdif_b sdf) i j)

-- | Extract and decode /n/th frame from 'SDIF'.
sdif_frame :: SDIF -> Int -> Frame
sdif_frame sdf n = sdif_frame_c sdf !! n

-- | Extract and decode /j/th matrix from /i/th frame from 'SDIF'.
sdif_matrix :: SDIF -> Int -> Int -> Matrix
sdif_matrix sdf i = frame_matrix (sdif_frame sdf i)

-- | Run 'matrix_v' on result of 'sdif_matrix'.
sdif_matrix_v :: SDIF -> Int -> Int -> [Datum]
sdif_matrix_v sdf i = matrix_v . sdif_matrix sdf i