    {-# LINE 1 "System/CWiid.hsc" #-}
    {-# LANGUAGE ForeignFunctionInterface #-}
    {-# LINE 2 "System/CWiid.hsc" #-}

    module System.CWiid
           (cwiidOpen, cwiidSetLed, cwiidSetRptMode, cwiidGetBtnState,
            cwiidLed1, cwiidLed2, cwiidLed3, cwiidLed4, combineCwiidLedFlag,
            cwiidBtn2, cwiidBtn1, cwiidBtnB, cwiidBtnA, cwiidBtnMinus,
            cwiidBtnHome, cwiidBtnLeft, cwiidBtnRight, cwiidBtnDown, cwiidBtnUp,
            cwiidBtnPlus, combineCwiidBtnFlag, diffCwiidBtnFlag,
            CWiidBtnFlag(..), CWiidState(..), CWiidWiimote) where

    -- import Foreign.C.Error
    import Data.Bits
    import Foreign.C.Types
    import Foreign.Marshal
    import Foreign.Ptr
    import Foreign.Storable

    {-# LINE 19 "System/CWiid.hsc" #-}

    -----------------------------------------------------------------------------
    -- Data type
    ---

    -- typedef struct {
    --         uint8_t b[6];
    -- } __attribute__((packed)) bdaddr_t;
    -- #define BDADDR_ANY   (&(bdaddr_t) {{0, 0, 0, 0, 0, 0}})
    data CWiidBdaddr = CWiidBdaddr Int Int Int Int Int Int
    instance Storable CWiidBdaddr where
      sizeOf = const (6)
    {-# LINE 31 "System/CWiid.hsc" #-}
      alignment = sizeOf
      poke bdat (CWiidBdaddr b0 b1 b2 b3 b4 b5) = do
        ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) bdat b0
    {-# LINE 34 "System/CWiid.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 1)) bdat b1
    {-# LINE 35 "System/CWiid.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 2)) bdat b2
    {-# LINE 36 "System/CWiid.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 3)) bdat b3
    {-# LINE 37 "System/CWiid.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 4)) bdat b4
    {-# LINE 38 "System/CWiid.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 5)) bdat b5
    {-# LINE 39 "System/CWiid.hsc" #-}
      peek bdat = do
        b0 <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) bdat
    {-# LINE 41 "System/CWiid.hsc" #-}
        b1 <- ((\hsc_ptr -> peekByteOff hsc_ptr 1)) bdat
    {-# LINE 42 "System/CWiid.hsc" #-}
        b2 <- ((\hsc_ptr -> peekByteOff hsc_ptr 2)) bdat
    {-# LINE 43 "System/CWiid.hsc" #-}
        b3 <- ((\hsc_ptr -> peekByteOff hsc_ptr 3)) bdat
    {-# LINE 44 "System/CWiid.hsc" #-}
        b4 <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) bdat
    {-# LINE 45 "System/CWiid.hsc" #-}
        b5 <- ((\hsc_ptr -> peekByteOff hsc_ptr 5)) bdat
    {-# LINE 46 "System/CWiid.hsc" #-}
        return $ CWiidBdaddr b0 b1 b2 b3 b4 b5

    -- typedef struct wiimote cwiid_wiimote_t;
    newtype CWiidWiimote = CWiidWiimote { unCWiidWiimote :: Ptr () }

    {--
    struct cwiid_state {
            uint8_t rpt_mode;
            uint8_t led;
            uint8_t rumble;
            uint8_t battery;
            uint16_t buttons;
            uint8_t acc[3];
            struct cwiid_ir_src ir_src[CWIID_IR_SRC_COUNT];
            enum cwiid_ext_type ext_type;
            union ext_state ext;
            enum cwiid_error error;
    };
    --}
    newtype CWiidLedFlag = CWiidLedFlag { unCWiidLedFlag :: Int }
                         deriving (Eq, Show)
    cwiidLed1  :: CWiidLedFlag
    cwiidLed1  = CWiidLedFlag 1
    cwiidLed2  :: CWiidLedFlag
    cwiidLed2  = CWiidLedFlag 2
    cwiidLed3  :: CWiidLedFlag
    cwiidLed3  = CWiidLedFlag 4
    cwiidLed4  :: CWiidLedFlag
    cwiidLed4  = CWiidLedFlag 8

    {-# LINE 73 "System/CWiid.hsc" #-}
    combineCwiidLedFlag :: [CWiidLedFlag] -> CWiidLedFlag
    combineCwiidLedFlag = CWiidLedFlag . foldr ((.|.) . unCWiidLedFlag) 0

    newtype CWiidBtnFlag = CWiidBtnFlag { unCWiidBtnFlag :: Int }
                         deriving (Eq, Show)
    cwiidBtn2      :: CWiidBtnFlag
    cwiidBtn2      = CWiidBtnFlag 1
    cwiidBtn1      :: CWiidBtnFlag
    cwiidBtn1      = CWiidBtnFlag 2
    cwiidBtnB      :: CWiidBtnFlag
    cwiidBtnB      = CWiidBtnFlag 4
    cwiidBtnA      :: CWiidBtnFlag
    cwiidBtnA      = CWiidBtnFlag 8
    cwiidBtnMinus  :: CWiidBtnFlag
    cwiidBtnMinus  = CWiidBtnFlag 16
    cwiidBtnHome   :: CWiidBtnFlag
    cwiidBtnHome   = CWiidBtnFlag 128
    cwiidBtnLeft   :: CWiidBtnFlag
    cwiidBtnLeft   = CWiidBtnFlag 256
    cwiidBtnRight  :: CWiidBtnFlag
    cwiidBtnRight  = CWiidBtnFlag 512
    cwiidBtnDown   :: CWiidBtnFlag
    cwiidBtnDown   = CWiidBtnFlag 1024
    cwiidBtnUp     :: CWiidBtnFlag
    cwiidBtnUp     = CWiidBtnFlag 2048
    cwiidBtnPlus   :: CWiidBtnFlag
    cwiidBtnPlus   = CWiidBtnFlag 4096

    {-# LINE 91 "System/CWiid.hsc" #-}
    combineCwiidBtnFlag :: [CWiidBtnFlag] -> CWiidBtnFlag
    combineCwiidBtnFlag = CWiidBtnFlag . foldr ((.|.) . unCWiidBtnFlag) 0
    diffCwiidBtnFlag :: CWiidBtnFlag -> CWiidBtnFlag -> CWiidBtnFlag
    diffCwiidBtnFlag a b = CWiidBtnFlag $ ai - (ai .&. bi)
      where ai = unCWiidBtnFlag a
            bi = unCWiidBtnFlag b

    data CWiidState = CWiidState { rptMode :: Int, led :: Int, rumble :: Int,
                                   battery :: Int, buttons :: Int } -- xxx 定義不足
                    deriving Show
    instance Storable CWiidState where
      sizeOf = const (60)
    {-# LINE 103 "System/CWiid.hsc" #-}
      alignment = sizeOf
      poke cwst (CWiidState rp l ru ba bu) = do
        ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) cwst rp
    {-# LINE 106 "System/CWiid.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 1)) cwst l
    {-# LINE 107 "System/CWiid.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 2)) cwst ru
    {-# LINE 108 "System/CWiid.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 3)) cwst ba
    {-# LINE 109 "System/CWiid.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 4)) cwst bu
    {-# LINE 110 "System/CWiid.hsc" #-}
      peek cwst = do
        rp <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) cwst
    {-# LINE 112 "System/CWiid.hsc" #-}
        l <- ((\hsc_ptr -> peekByteOff hsc_ptr 1)) cwst
    {-# LINE 113 "System/CWiid.hsc" #-}
        ru <- ((\hsc_ptr -> peekByteOff hsc_ptr 2)) cwst
    {-# LINE 114 "System/CWiid.hsc" #-}
        ba <- ((\hsc_ptr -> peekByteOff hsc_ptr 3)) cwst
    {-# LINE 115 "System/CWiid.hsc" #-}
        bu <- ((\hsc_ptr -> peekByteOff hsc_ptr 4)) cwst
    {-# LINE 116 "System/CWiid.hsc" #-}
        return $ CWiidState rp l ru ba bu

    -----------------------------------------------------------------------------
    -- Haskell land
    ---
    -- wiimote = cwiid_open(&bdaddr, 0)))
    cwiidOpen :: IO (Maybe CWiidWiimote)
    cwiidOpen =
      alloca $ \bdAddr -> do
        poke bdAddr $ CWiidBdaddr 0 0 0 0 0 0
        handle <- c_cwiid_open bdAddr 0 -- エラー処理必要
        if handle == nullPtr
          then return Nothing
          else return $ Just $ CWiidWiimote handle

    cwiidSetLed :: CWiidWiimote -> IO CInt
    cwiidSetLed wm = c_cwiid_set_led  handle 9 -- set on LED 1 and 4
      where handle = unCWiidWiimote wm

    cwiidSetRptMode :: CWiidWiimote -> IO CInt
    cwiidSetRptMode wm = c_cwiid_set_rpt_mode handle 2 -- set BTN
      where handle = unCWiidWiimote wm

    cwiidGetBtnState :: CWiidWiimote -> IO CWiidBtnFlag
    cwiidGetBtnState wm =
      alloca $ \wiState -> do
        _ <- c_cwiid_get_state handle wiState
        ws <- peek wiState
        return $ CWiidBtnFlag $ buttons ws
          where handle = unCWiidWiimote wm

    -----------------------------------------------------------------------------
    -- C land
    ---
    -- Haskell => C
    ---

    -- cwiid_wiimote_t *cwiid_open(bdaddr_t *bdaddr, int flags)
    foreign import ccall safe "cwiid_open" c_cwiid_open
      :: Ptr CWiidBdaddr -> CInt -> IO (Ptr ())

    -- typedef unsigned char             uint8_t
    -- int cwiid_set_led(cwiid_wiimote_t *wiimote, uint8_t led)
    foreign import ccall safe "cwiid_set_led" c_cwiid_set_led
      :: Ptr () -> CUChar -> IO CInt

    -- int cwiid_set_rpt_mode(cwiid_wiimote_t *wiimote, uint8_t rpt_mode);
    foreign import ccall safe "cwiid_set_rpt_mode" c_cwiid_set_rpt_mode
      :: Ptr () -> CUChar -> IO CInt

    -- int cwiid_get_state(cwiid_wiimote_t *wiimote, struct cwiid_state *state);
    foreign import ccall safe "cwiid_get_state" c_cwiid_get_state
      :: Ptr () -> Ptr CWiidState -> IO CInt

    -- C => Haskell
    ---

    -- int cwiid_set_mesg_callback(cwiid_wiimote_t *wiimote,
    --                             cwiid_mesg_callback_t *callback)
    -- xxxxx
    -- typedef void cwiid_mesg_callback_t(cwiid_wiimote_t *, int,
    --                                    union cwiid_mesg [], struct timespec *)
    -- xxxxx