module GUIgeneric.GUIExampleLib where

open import GUIgeneric.Prelude
open import GUIgeneric.PreludeGUI  -- hiding (addButton)

open import GUIgeneric.GUIDefinitions renaming (add to add'; add' to add)
open import GUIgeneric.GUI



executeChangeGui : ∀{i}  (fr : FFIFrame)(mvar : MVar StateAndGuiObj)
                          (mvarFFI : MVar StateAndFFIComp)
                          (let state = addVar mvar (SingleMVar mvarFFI))
       StateAndGuiObj × StateAndFFIComp 
      IOˢ GuiLev2Interface i  _  prod state) state

executeChangeGui fr varO varFFI ((gNew , (prop , obj)) , (gOld , ffi)) =

  deleteComp gOld ffi >>=ₚˢ λ _ 
  reCreateFrame gNew fr >>=ₚˢ λ ffiNew 
  setHandlerG gNew ffiNew varO (SingleMVar varFFI)  >>=ₚˢ λ _ 

  (translateLev1toLev2 (setAttributes  gNew prop ffiNew)) >>=ˢ λ _ _ 
  returnˢ ((gNew , (prop , obj)) , (gNew , ffiNew ))




setRightClick₃ : ∀{i} 
                      (g : Frame)
                      (ffiComp : FFIcomponents g)
                      (mvar : MVar StateAndGuiObj)
                      (mvarFFI : MVar StateAndFFIComp)
                      (getFr : FFIcomponents g  FFIFrame)
                      (let state = addVar mvar (SingleMVar mvarFFI))
                       IOˢ GuiLev3Interface i  s  s  state × Unit) state

setRightClick₃ g ffi mvar mvarFFI getFr =
  execˢ (setRightClick (getFr ffi)
                     (executeChangeGui (getFr ffi) mvar mvarFFI  [])) λ r 
  returnˢ (refl , _)

setCustomEvent₃ : ∀{i} 
                      (g : Frame)
                      (ffiComp : FFIcomponents g)
                      (mvar : MVar StateAndGuiObj)
                      (mvarFFI : MVar StateAndFFIComp)
                      (getFr : FFIcomponents g  FFIFrame)
                      (let state = addVar mvar (SingleMVar mvarFFI))
                       IOˢ GuiLev3Interface i  s  s  state × Unit) state

setCustomEvent₃ g ffi mvar mvarFFI getFr =
  execˢ (setCustomEvent (getFr ffi)
                     (executeChangeGui (getFr ffi) mvar mvarFFI  [])) λ r 
  returnˢ (refl , _)


mainGeneric : (g : Frame)(a : properties g)(o : HandlerObject  g)(getFr : FFIcomponents g  FFIFrame)
            IOˢ GuiLev3Interface   _  Unit) []

mainGeneric g propDef objDef getFr =
 let _>>=_ = _>>=ₚˢ_
     createGUIElements = λ g  cmd3 (createFrame g)
     setAttributes = λ g prop ffi  cmd3 (translateLev1toLev2ₚ (setAttributes  g prop ffi))

 in
 createGUIElements g         >>=  λ ffi 
 setAttributes g propDef ffi >>=  λ _ 

 cmd3 (initFFIMVar g ffi)                             >>=ₚsemiˢ λ mvaffi 

 cmd3 (initHandlerMVar (SingleMVar mvaffi) g propDef objDef)  >>=ₚsemiˢ λ mvar 
 cmd3 (setHandlerG g ffi mvar (SingleMVar mvaffi))    >>=ₚˢ λ _ 
 setCustomEvent₃ g ffi mvar mvaffi getFr              >>=ˢ λ _ _ 

  returnˢ _
    where
      cmd3 = translateLev2toLev3



compileProgram : (g : Frame)(a : properties g) (h : HandlerObject  g)
                   NativeIO Unit
compileProgram g a h  = start (translateLev3 (mainGeneric g a h (getFrameGen g)))

generateProgram = compileProgram

addButton : String  CompEls frame  (isOpt : IsOptimized)  CompEls frame
addButton str fr isOpt = add' buttonFrame (create-button str) fr isOpt

addTxtBox' : String  CompEls frame  (isOpt : IsOptimized)  CompEls frame
addTxtBox' str fr isOpt = add' buttonFrame (create-txtbox str) fr isOpt



record GUI {i : Size} : Set₁ where 
   field   
      defFrame  : Frame
      property  : properties defFrame
      obj       : HandlerObject i defFrame
open GUI public

guiFull2IOˢprog : GUI  IOˢ GuiLev3Interface   _  Unit) []
guiFull2IOˢprog g = mainGeneric (g .defFrame) (g .property) (g .obj) (getFrameGen (g .defFrame))

compileGUI : GUI  NativeIO Unit
compileGUI g = start (translateLev3 (guiFull2IOˢprog g))