module ID3.Type.FrameInfo where

import ID3.Parser.UnSync        (synchronise, integerToWords)
import ID3.Type.Unparse
import Codec.Binary.UTF8.String (encode, encodeString, decode)
import Data.Accessor
import Data.Word                (Word8)

data FrameInfo = UFID { owner :: String
                      , id    :: String }
               | Text { enc   :: Integer
                      , text  :: String }
               | TXXX { enc   :: Integer
                      , descr :: String
                      , text  :: String }
               | URL  { url   :: String }
               | WXXX { enc   :: Integer
                      , descr :: String
                      , url   :: String }
               | MCDI -- TODO
               | ETCO -- { format :: Integer
                      -- , events :: [Event]} -- TODO
               | MLLT -- TODO
               | SYTC -- TODO
               | USLT { enc   :: Integer
                      , lang  :: String
                      , descr :: String
                      , text  :: String }
               | SYLT { enc     :: Integer
                      , lang    :: String
                      , timeFormat :: Integer
                      , content :: Integer
                      , descr   :: String } -- .... TODO
               | COMM { enc   :: Integer
                      , lang  :: String
                      , descr :: String
                      , text  :: String }
               | RVA2 -- TODO
               | EQU2 -- TODO
               | RVRB -- TODO
               | APIC { enc :: Integer
                      , mime :: String
                      , picType :: Word8
                      , descr   :: String
                      , picData :: [Word8] } -- .... TODO
               | GEOB -- TODO
               | PCNT { counter :: Integer }
               | POPM { email   :: String
                      , rating  :: Integer
                      , counter :: Integer }
               | RBUF -- TODO
               | AENC -- TODO
               | LINK -- TODO
               | POSS -- TODO
               | USER { enc   :: Integer
                      , lang  :: String
                      , text  :: String }
               | OWNE -- TODO
               | COMR -- TODO
               | ENCR -- TODO
               | GRID -- TODO
               | PRIV -- TODO
               | SIGN -- TODO
               | ASPI -- TODO

               -- not native
               | TCMP { isPart :: Bool }
               | Unknown { value :: String }
          deriving (Eq, Show)


encodeAll = concatMap encode

infoTextContent = accessor text (\x f -> f {text = x})
--url = accessor (encode . url) (\x f -> f {url = decode x})

instance Parsed FrameInfo where
    unparse inf = case inf of
               UFID owner id       -> (encode owner) ++ [0x00] ++ (encode id)
               Text enc text       -> (fromInteger enc) : (encode text)
               TXXX enc descr text -> (fromInteger enc) : (encode descr) ++ [0x00] ++ (encode text)
               URL  url            ->  encode url
               WXXX enc descr url  -> (fromInteger enc) : (encode descr) ++ [0x00] ++ (encode url)
               --MCDI -- TODO
               --ETCO -- { format :: Integer
                    -- , events :: [Event]} -- TODO
               --MLLT -- TODO
               --SYTC -- TODO
               USLT enc lang descr text -> (fromInteger enc) : (encodeAll [lang, descr]) ++ [0x00] ++ (encode text)
               --SYLT enc lang timeFormat content descr
               COMM enc lang descr text -> (fromInteger enc) : (encodeAll [lang, descr]) ++ [0x00] ++ (encode text)
               --RVA2 -- TODO
               --EQU2 -- TODO
               --RVRB -- TODO
               APIC enc mime picType descr picData -> (fromInteger enc) : (encode mime) ++ [0x00,picType] ++ (encode descr) ++[0x00]++ picData
               --GEOB -- TODO
               PCNT counter              -> integerToWords 4 counter
               POPM email rating counter -> (encode email) ++ [0x00, fromInteger rating] ++ (integerToWords 4 counter)
               --RBUF -- TODO
               --AENC -- TODO
               --LINK -- TODO
               --POSS -- TODO
               USER enc lang text -> (fromInteger enc) : (encode lang) ++ [0x00] ++ (encode text)
               --OWNE -- TODO
               --COMR -- TODO
               --ENCR -- TODO
               --GRID -- TODO
               --PRIV -- TODO
               --SIGN -- TODO
               --ASPI -- TODO
               TCMP isPart -> 0x03 : (encode $ if isPart then "1" else "0")
               Unknown x -> encode x
               _ -> encode "unknown!!!"