module Data.ByteString.IsoBaseFileFormat.Boxes.TrackRun (trackRunIso5, TrackRun) where
import Data.ByteString.IsoBaseFileFormat.Box
import Data.ByteString.IsoBaseFileFormat.ReExports
import qualified Data.ByteString as BS
trackRunIso5 :: Int32 -> [(Word32, BS.ByteString)] -> Box TrackRun
trackRunIso5 !mdatOffset !samples = Box c
  where
    !c = TrackRun (header <> body)
      where
        !header = h (fromIntegral sampleCount) dataOffset
          where
            !dataOffset       = 8 
                                  + mdatOffset + 8  
                                  + fromIntegral
                                  ((headerStaticSize `div` 8)
                                   + sampleCount * (sampleStaticSize `div` 8))
            !h                = bitBuilderWithSize (Proxy @(Header TrackRunFlagsIso5))
            !headerStaticSize = (natVal (Proxy @(SizeInBits (Header TrackRunFlagsIso5))))
            !sampleStaticSize = (natVal (Proxy @(SizeInBits (Sample TrackRunFlagsIso5))))
            !sampleCount      = fromIntegral (length samples)
        !body = mconcat $ s <$> samples
          where
            s (!duration, !bs) = bitBuilderWithSize (Proxy @(Sample TrackRunFlagsIso5)) duration size
              where
                !size = fromIntegral (BS.length bs)
newtype TrackRun where
  TrackRun :: BuilderWithSize -> TrackRun
  deriving (IsBoxContent)
instance IsBox TrackRun
type instance BoxTypeSymbol TrackRun = "trun"
data TrackRunFlags
  (dataOffsetPresent :: Bool)
  (firstSampleFlagsPresent :: Bool)
  (sampleDurationPresent :: Bool)
  (sampleSizePresent :: Bool)
  (sampleFlagsPresent :: Bool)
  (sampleCompositionTimeOffsetPresent :: Bool)
data TrackRunFlagsIso5
  :: Extends (TrackRunFlags 'True 'False 'True 'True 'True 'False)
type Header (t :: Extends (TrackRunFlags dop fsp sdp ssp sfp sctop)) =
      "version"                   @: FieldU8  := 0 
  .+:                                Field 12 := 0
  .+: "sample-scto-present"       @: Flag     := sctop
  .+: "sample-flags-present"      @: Flag     := sfp
  .+: "sample-size-present"       @: Flag     := ssp
  .+: "sample-duration-present"   @: Flag     := sdp
  .+:                                Field  5 := 0
  .+: "first-sample-flag-present" @: Flag     := fsp
  .+:                                Flag     := 'False
  .+: "data-offset-preset"        @: Flag     := dop
  .+: 'RecordField ("sample-count"  @:: FieldU32)
  :+: WhenR dop
        ('BitRecordMember ("data-offset"        @: FieldI32))
  :+: WhenR fsp
        ('RecordField ("first-sample-flags" @:: FieldU32))
type Sample (t :: Extends (TrackRunFlags dop fsp sdp ssp sfp sctop)) =
      WhenR sdp ('RecordField ("sample-duration" @:: FieldU32))
  :+: WhenR ssp ('RecordField ("sample-size"     @:: FieldU32))
  :+: WhenR sfp ('RecordField ("sample-flags"    @:: FieldU32 :=. 0x02000000))