module StateSizedIO.GUI.WxBindingsFFI where

open import Data.Bool.Base
open import Data.Integer

open import Data.Product hiding (map)

open import NativeIO
open import NativeInt

open import Function

{-# IMPORT GHC.Conc.Sync #-}
{-# IMPORT Control.Concurrent #-}
{-# IMPORT Graphics.UI.WX #-}
{-# IMPORT Graphics.UI.WXCore #-}
{-# IMPORT Graphics.UI.WXCore.Events #-}

postulate Frame : Set
{-# COMPILED_TYPE Frame (Graphics.UI.WX.Frame ()) #-}

postulate Button : Set
{-# COMPILED_TYPE Button (Graphics.UI.WX.Button ()) #-}


postulate nativeNewFrame : String -> NativeIO Frame
{-# COMPILED nativeNewFrame (\s -> Graphics.UI.WX.frame
  [Graphics.UI.WX.text Graphics.UI.WX.:= (Data.Text.unpack s)]) #-}

postulate nativeDoThreadDelay : NativeIO Bool
{-# COMPILED nativeDoThreadDelay ((Control.Concurrent.threadDelay 100) >>= (\x -> return True)) #-}

postulate nativeSetIdle : Frame -> NativeIO Bool -> NativeIO Unit
{-# COMPILED nativeSetIdle (\fra prog -> Graphics.UI.WX.set fra
  [Graphics.UI.WX.on Graphics.UI.WX.idle Graphics.UI.WX.:= prog]) #-}

nativeMakeFrame : NativeIO Frame
nativeMakeFrame =
  nativeNewFrame "Start Text" native>>= (\f -> 
  nativeSetIdle f nativeDoThreadDelay native>>= (\x ->
  nativeReturn f))   

postulate nativeMakeButton : Frame  NativeIO Button
{-# COMPILED nativeMakeButton (\myFrame -> Graphics.UI.WX.button myFrame
  [Graphics.UI.WX.text Graphics.UI.WX.:= "click"]) #-}

postulate nativeAddButton : Frame  Button  NativeIO Unit
{-# COMPILED nativeAddButton (\myFrame bt -> Graphics.UI.WX.set myFrame
  [Graphics.UI.WX.layout Graphics.UI.WX.:=
    Graphics.UI.WX.minsize (Graphics.UI.WX.sz 500 400) $
      Graphics.UI.WX.column 1 [Graphics.UI.WX.hfill (Graphics.UI.WX.widget bt)]]) #-}


postulate  TVar : Set  Set
{-# COMPILED_TYPE TVar Control.Concurrent.STM.TVar.TVar  #-}

postulate  MVar : Set  Set
{-# COMPILED_TYPE MVar Control.Concurrent.MVar  #-}

Var : Set  Set
Var = MVar


postulate
  nativeNewVar : {A : Set}  A  NativeIO (Var A)
  nativeTakeVar : {A : Set}  Var A  NativeIO A
  nativePutVar : {A : Set}  Var A  A  NativeIO Unit

{-# COMPILED nativeNewVar (\ _ -> Control.Concurrent.newMVar ) #-}
{-# COMPILED nativeTakeVar (\ _ -> Control.Concurrent.takeMVar ) #-}
{-# COMPILED nativePutVar (\ _ -> Control.Concurrent.putMVar ) #-}


postulate nativeSetButtonHandler : Button  NativeIO Unit  NativeIO Unit
{-# COMPILED nativeSetButtonHandler (\ bt prog -> Graphics.UI.WX.set bt
  [Graphics.UI.WX.on Graphics.UI.WX.command Graphics.UI.WX.:= prog ]) #-}

postulate ThreadId : Set
{-# COMPILED_TYPE ThreadId GHC.Conc.Sync.ThreadId #-}

postulate forkIO : NativeIO Unit  NativeIO ThreadId
{-# COMPILED forkIO GHC.Conc.Sync.forkIO #-}


postulate Bitmap : Set
{-# COMPILED_TYPE Bitmap (Graphics.UI.WXCore.Bitmap ()) #-}

postulate bitmap : String  Bitmap
{-# COMPILED bitmap (\s -> Graphics.UI.WX.bitmap (Data.Text.unpack s))  #-}

postulate DC : Set
{-# COMPILED_TYPE DC (Graphics.UI.WXCore.DC ()) #-}

postulate Rect : Set
{-# COMPILED_TYPE Rect Graphics.UI.WXCore.Rect #-}


postulate nativeSetOnPaint : Frame  (DC  Rect  NativeIO Unit)  NativeIO Unit
{-# COMPILED nativeSetOnPaint (\ fra prog -> Graphics.UI.WX.set fra [Graphics.UI.WX.on Graphics.UI.WX.paint Graphics.UI.WX.:= prog]) #-}

postulate nativeRepaint : Frame  NativeIO Unit
{-# COMPILED nativeRepaint Graphics.UI.WX.repaint #-}


Point : Set
Point = ( × )

postulate NativePoint : Set
{-# COMPILED_TYPE NativePoint Graphics.UI.WXCore.Point #-}

postulate nativePoint :     NativePoint
{-# COMPILED nativePoint (\ x y -> Graphics.UI.WXCore.point (fromInteger x) (fromInteger y)) #-}


postulate nativeDrawBitmapNativePoint : DC  Bitmap  NativePoint  Bool  NativeIO Unit
{-# COMPILED nativeDrawBitmapNativePoint (\ d bi p bo -> Graphics.UI.WX.drawBitmap d bi p bo [] ) #-}

nativeDrawBitmap : DC  Bitmap  Point  Bool  NativeIO Unit
nativeDrawBitmap d bi (x , y) bo = nativeDrawBitmapNativePoint d bi (nativePoint x y) bo


postulate start : NativeIO Unit  NativeIO Unit
{-# COMPILED start Graphics.UI.WX.start #-}


--
--  Note: we add the "key pressed" event to a button
--  and not to a frame, because of a bug in wxHaskell that prevents
--  adding a key pressed event to a frame (at least on linux plattforms).
--


postulate
  Key : Set
  showKey : Key -> String
  nativeSetKeyHandler : Button  (Key  NativeIO Unit)  NativeIO Unit

{-# COMPILED_TYPE Key Graphics.UI.WXCore.Events.Key #-}
{-# COMPILED showKey (\ k -> (Data.Text.pack (Graphics.UI.WXCore.Events.showKey k))) #-}

{-# COMPILED nativeSetKeyHandler (\bt prog -> Graphics.UI.WX.set bt [Graphics.UI.WX.on Graphics.UI.WX.anyKey Graphics.UI.WX.:= prog]) #-}