{-# LINE 1 "Sound/MikMod/Flags.hsc" #-}
{-# LANGUAGE ForeignFunctionInterface #-}
{-# LINE 2 "Sound/MikMod/Flags.hsc" #-}
module Sound.MikMod.Flags where

import Foreign

import Data.List
import Data.Maybe

import Sound.MikMod.Synonyms


{-# LINE 12 "Sound/MikMod/Flags.hsc" #-}

-- | Class to handle the bit flags. It's Enum with UWORD (CUShort) instead
-- of Int and without irrelevant functionality.
class Flag a where
  toFlag   :: a -> UWORD
  fromFlag :: UWORD -> a

data DriverModeFlag =
  DMode16Bits |
  DModeStereo |
  DModeSoftSndfx |
  DModeSoftMusic |
  DModeHQMixer |
  DModeFloat |
  DModeSurround |
  DModeInterp |
  DModeReverse |
  DModeSIMDMixer |
  DModeNoiseReduction
    deriving (Eq, Show)

instance Flag DriverModeFlag where
  toFlag flag = case flag of
    DMode16Bits -> (1)
{-# LINE 36 "Sound/MikMod/Flags.hsc" #-}
    DModeStereo -> (2)
{-# LINE 37 "Sound/MikMod/Flags.hsc" #-}
    DModeSoftSndfx -> (4)
{-# LINE 38 "Sound/MikMod/Flags.hsc" #-}
    DModeSoftMusic -> (8)
{-# LINE 39 "Sound/MikMod/Flags.hsc" #-}
    DModeHQMixer -> (16)
{-# LINE 40 "Sound/MikMod/Flags.hsc" #-}
    DModeFloat -> (32)
{-# LINE 41 "Sound/MikMod/Flags.hsc" #-}
    DModeSurround -> (256)
{-# LINE 42 "Sound/MikMod/Flags.hsc" #-}
    DModeInterp -> (512)
{-# LINE 43 "Sound/MikMod/Flags.hsc" #-}
    DModeReverse -> (1024)
{-# LINE 44 "Sound/MikMod/Flags.hsc" #-}
    DModeSIMDMixer -> (2048)
{-# LINE 45 "Sound/MikMod/Flags.hsc" #-}
    DModeNoiseReduction -> (4096)
{-# LINE 46 "Sound/MikMod/Flags.hsc" #-}
  fromFlag n = case n of
    (1) -> DMode16Bits
{-# LINE 48 "Sound/MikMod/Flags.hsc" #-}
    (2) -> DModeStereo
{-# LINE 49 "Sound/MikMod/Flags.hsc" #-}
    (4) -> DModeSoftSndfx
{-# LINE 50 "Sound/MikMod/Flags.hsc" #-}
    (8) -> DModeSoftMusic
{-# LINE 51 "Sound/MikMod/Flags.hsc" #-}
    (16) -> DModeHQMixer
{-# LINE 52 "Sound/MikMod/Flags.hsc" #-}
    (32) -> DModeFloat
{-# LINE 53 "Sound/MikMod/Flags.hsc" #-}
    (256) -> DModeSurround
{-# LINE 54 "Sound/MikMod/Flags.hsc" #-}
    (512) -> DModeInterp
{-# LINE 55 "Sound/MikMod/Flags.hsc" #-}
    (1024) -> DModeReverse
{-# LINE 56 "Sound/MikMod/Flags.hsc" #-}
    (2048) -> DModeSIMDMixer
{-# LINE 57 "Sound/MikMod/Flags.hsc" #-}
    (4096) -> DModeNoiseReduction
{-# LINE 58 "Sound/MikMod/Flags.hsc" #-}
    _ -> error ("unmarshalDriverModeFlag " ++ show n)

data SampleFlag =
  SF16Bits |
  SFBigEndian |
  SFDelta |
  SFITPacked |
  SFSigned |
  SFStereo |
  SFBidi |
  SFLoop |
  SFReverse
    deriving (Eq, Show)

instance Flag SampleFlag where
  toFlag flag = case flag of
    SF16Bits -> (1)
{-# LINE 75 "Sound/MikMod/Flags.hsc" #-}
    SFBigEndian -> (8)
{-# LINE 76 "Sound/MikMod/Flags.hsc" #-}
    SFDelta -> (16) 
{-# LINE 77 "Sound/MikMod/Flags.hsc" #-}
    SFITPacked -> (32)
{-# LINE 78 "Sound/MikMod/Flags.hsc" #-}
    SFSigned -> (4)
{-# LINE 79 "Sound/MikMod/Flags.hsc" #-}
    SFStereo -> (2)
{-# LINE 80 "Sound/MikMod/Flags.hsc" #-}
    SFBidi -> (512)
{-# LINE 81 "Sound/MikMod/Flags.hsc" #-}
    SFLoop -> (256)
{-# LINE 82 "Sound/MikMod/Flags.hsc" #-}
    SFReverse -> (1024)
{-# LINE 83 "Sound/MikMod/Flags.hsc" #-}
  fromFlag n = case n of
    (1) -> SF16Bits
{-# LINE 85 "Sound/MikMod/Flags.hsc" #-}
    (8) -> SFBigEndian
{-# LINE 86 "Sound/MikMod/Flags.hsc" #-}
    (16) -> SFDelta 
{-# LINE 87 "Sound/MikMod/Flags.hsc" #-}
    (32) -> SFITPacked
{-# LINE 88 "Sound/MikMod/Flags.hsc" #-}
    (4) -> SFSigned
{-# LINE 89 "Sound/MikMod/Flags.hsc" #-}
    (2) -> SFStereo
{-# LINE 90 "Sound/MikMod/Flags.hsc" #-}
    (512) -> SFBidi
{-# LINE 91 "Sound/MikMod/Flags.hsc" #-}
    (256) -> SFLoop
{-# LINE 92 "Sound/MikMod/Flags.hsc" #-}
    (1024) -> SFReverse
{-# LINE 93 "Sound/MikMod/Flags.hsc" #-}
    _ -> error ("unmarshalSampleFlag " ++ show n)

data ModuleFlag =
  UFARPMem |
  UFBGSlides |
  UFHighBPM |
  UFInst |
  UFLinear |
  UFNNA |
  UFNoWrap |
  UFS3MSlides |
  UFXMPeriods |
  UFT2Quirks |
  UFPanning
    deriving (Eq, Show)

instance Flag ModuleFlag where
  toFlag flag = case flag of
    UFARPMem -> (256)
{-# LINE 112 "Sound/MikMod/Flags.hsc" #-}
    UFBGSlides -> (32)
{-# LINE 113 "Sound/MikMod/Flags.hsc" #-}
    UFHighBPM -> (64)
{-# LINE 114 "Sound/MikMod/Flags.hsc" #-}
    UFInst -> (4)
{-# LINE 115 "Sound/MikMod/Flags.hsc" #-}
    UFLinear -> (2)
{-# LINE 116 "Sound/MikMod/Flags.hsc" #-}
    UFNNA -> (8)
{-# LINE 117 "Sound/MikMod/Flags.hsc" #-}
    UFNoWrap -> (128)
{-# LINE 118 "Sound/MikMod/Flags.hsc" #-}
    UFS3MSlides -> (16)
{-# LINE 119 "Sound/MikMod/Flags.hsc" #-}
    UFXMPeriods -> (1)
{-# LINE 120 "Sound/MikMod/Flags.hsc" #-}
    UFT2Quirks -> (512)
{-# LINE 121 "Sound/MikMod/Flags.hsc" #-}
    UFPanning -> (1024)
{-# LINE 122 "Sound/MikMod/Flags.hsc" #-}
  fromFlag n = case n of
    (256) -> UFARPMem
{-# LINE 124 "Sound/MikMod/Flags.hsc" #-}
    (32) -> UFBGSlides
{-# LINE 125 "Sound/MikMod/Flags.hsc" #-}
    (64) -> UFHighBPM
{-# LINE 126 "Sound/MikMod/Flags.hsc" #-}
    (4) -> UFInst
{-# LINE 127 "Sound/MikMod/Flags.hsc" #-}
    (2) -> UFLinear
{-# LINE 128 "Sound/MikMod/Flags.hsc" #-}
    (8) -> UFNNA
{-# LINE 129 "Sound/MikMod/Flags.hsc" #-}
    (128) -> UFNoWrap
{-# LINE 130 "Sound/MikMod/Flags.hsc" #-}
    (16) -> UFS3MSlides
{-# LINE 131 "Sound/MikMod/Flags.hsc" #-}
    (1) -> UFXMPeriods
{-# LINE 132 "Sound/MikMod/Flags.hsc" #-}
    (512) -> UFT2Quirks
{-# LINE 133 "Sound/MikMod/Flags.hsc" #-}
    (1024) -> UFPanning
{-# LINE 134 "Sound/MikMod/Flags.hsc" #-}
    _ -> error ("unmarshalModuleFlag " ++ show n)

unpackFlags :: Flag a => UWORD -> [a]
unpackFlags packed = map fromFlag results where
  experiment = map (packed .&.) (take 16 $ (iterate (*2) 1))
  results = filter (> 0) experiment

packFlags :: Flag a => [a] -> UWORD
packFlags flags = foldl' (.|.) 0 (map toFlag flags)