module Editlet
import iTasks
import iTasks.API.Core.Client.Editlet
import iTasks.API.Core.Client.Interface
import iTasks.API.Extensions.CodeMirror
import iTasks.API.Extensions.JointJS.JointJS
import StdDebug
:: TimeDelta = SetSec !Int | SetMin !Int | SetHour !Int
derive class iTask TimeDelta
buienLet :: Editlet String Void
buienLet = Editlet "Buienradar" {html=const (RawText html), updateUI = \_ _ a st w = (a,st,w), handlers = \_ -> [], genDiff = \_ _ -> Nothing, appDiff = \_ v -> v}
where
html = "
"
:: StringDelta = {newString :: String}
derive class iTask StringDelta
stringlet :: Editlet String [String]
stringlet = Editlet "Hello world"
{html = \cid -> TextareaTag [IdAttr cid] []
,updateUI = onUpdate
,handlers = \cid -> [ComponentEvent cid "keyup" onChange]
,genDiff = \o n -> if (o == n) Nothing (Just [n,n])
,appDiff = \n _ -> hd n
}
where
onUpdate :: ComponentId (Maybe [String]) String (Maybe Void) *JSWorld -> (!String, Maybe Void, !*JSWorld)
onUpdate id _ val st world
# world = setDomAttr id "value" (toJSVal val) world
= (val,st,world)
onChange :: ComponentId (JSVal EditletEvent) String (Maybe Void) *JSWorld -> (!String, Maybe Void, !*JSWorld)
onChange id event val st world
= let (val, w) = getDomAttr id "value" world in (jsValToString val, st, w)
timelet :: Time -> Editlet Time [TimeDelta]
timelet t = Editlet t
{html = \id -> RawText ("
")
,updateUI = onUpdate
,handlers = \_ -> []
,genDiff = genDiff
,appDiff = appDiff
}
where
onUpdate :: ComponentId (Maybe [TimeDelta]) Time (Maybe Void) *JSWorld -> (!Time, Maybe Void, !*JSWorld)
onUpdate id _ val st world
# world = setDomAttr id "innerHTML" (toJSVal (toString val)) world
# world = setDomAttr id "style.color" (toJSVal (colors !! (val.Time.sec rem (length colors)))) world
= (val,st,world)
colors = ["#f0f","#00f","#f00","#30f","#ff0","#66f"]
genDiff :: Time Time -> Maybe [TimeDelta]
genDiff t1 t2 = case ( (if (t1.Time.sec == t2.Time.sec) [] [SetSec t2.Time.sec])
++ (if (t1.Time.min == t2.Time.min) [] [SetMin t2.Time.min])
++ (if (t1.Time.hour == t2.Time.hour) [] [SetHour t2.Time.hour])
) of [] = Nothing ; delta = Just delta
appDiff :: [TimeDelta] Time -> Time
appDiff [] t = t
appDiff [SetSec s:d] t = appDiff d {Time|t & sec = s}
appDiff [SetMin m:d] t = appDiff d {Time|t & min = m}
appDiff [SetHour h:d] t = appDiff d {Time|t & hour = h}
clocklet :: Time -> Editlet Time Time
clocklet t = Editlet t
{html = \id -> RawText ("")
,updateUI = onInit
,handlers = \_ -> []
,genDiff = \t1 t2 -> if (t1 == t2) Nothing (Just t2)
,appDiff = \tn to -> tn
}
where
onInit :: ComponentId (Maybe Time) Time (Maybe Void) *JSWorld -> (!Time, Maybe Void, !*JSWorld)
onInit id Nothing val st world
# world = addJSFromUrl "/coolclock.js" Nothing world
# world = addJSFromUrl "/moreskins.js" Nothing world
= trace_n "onInit done" (val,st,world)
// Update
onInit id mbDiff val st world = (val, st, world)
onLoad :: *JSWorld -> *JSWorld
onLoad world
# world = trace_n "onLoad" world
# (window,world) = jsWindow world
# (coolclock,world) = jsGetObjectAttr "CoolClock" window world
//# (coolclock,world) = findObject "CoolClock" world
# (err,world) = jsIsUndefined coolclock world
| err = trace_n "No CoolClock" world
# (method,world) = jsGetObjectAttr "findAndCreateClocks" coolclock world
# (err,world) = jsIsUndefined method world
| err = trace_n "No findAndCreateClocks" world
# (_,world) = callObjectMethod "findAndCreateClocks" [] coolclock world
= world
/*
onUpdate :: ComponentId (JSPtr JSObject) Time *JSWorld -> (!Time, !*JSWorld)
onUpdate id event val=:{Time|hour,min,sec} world
# (coolclock,world) = findObject "CoolClock" world
# (err,world) = jsIsUndefined coolclock world
# (method,world) = jsGetObjectAttr "findAndCreateClocks" coolclock world
# (err,world) = jsIsUndefined method world
# (_,world) = jsCallObjectMethod "findAndCreateClocks" [] coolclock world
# (config,world) = jsGetObjectAttr "config" coolclock world
# (err,world) = jsIsUndefined config world
# (tracker,world) = jsGetObjectAttr "clockTracker" config world
# (err,world) = jsIsUndefined tracker world
# (myclock,world) = jsGetObjectAttr id tracker world
# (err,world) = jsIsUndefined myclock world
# (_,world) = jsCallObjectMethod "setTime" [hour,min,sec] myclock world
= (val,world)
*/
:: Game = { board :: !TicTacToe // the current board
, names :: !Players // the current two players
, turn :: !TicTac // the player at turn
}
:: Players = { tic :: !Name // the tic player is starting
, tac :: !Name // the tac player
}
:: Name :== String
:: TicTacToe :== [[Tile]]
:: Tile = Clear | Filled TicTac
:: TicTac = Tic | Tac
:: Coordinate = {col :: Int, row :: Int} // 0 <= col <= 2 && 0 <= row <= 2
instance ~ TicTac where ~ Tic = Tac
~ Tac = Tic
derive class iTask Tile, TicTac, Coordinate
tictactoelet :: (TicTacToe,TicTac) -> Editlet (TicTacToe,TicTac) (TicTacToe,TicTac)
tictactoelet t=:(board,turn) = Editlet t
{html = \id -> DivTag [IdAttr "tictactoe"] [init_board "tictactoe" t]
,updateUI = onUpdate
,handlers = \_ -> []
++[ComponentEvent (cellId "tictactoe" c) "click" (onCellClick c) \\ c <- [{col=x,row=y} \\ x <- [0..2] & y <- [0..2] ]]
,genDiff = \t1 t2 -> if (t1 === t2) Nothing (Just t2)
,appDiff = \tn to -> tn
}
where
//onInit :: ComponentId (JSPtr JSObject) (TicTacToe,TicTac) *JSWorld -> (!(TicTacToe,TicTac), !*JSWorld)
//onInit editorId _ state world = (state,redraw "tictactoe" state world)
onUpdate :: ComponentId (Maybe (TicTacToe,TicTac)) (TicTacToe,TicTac) (Maybe Void) *JSWorld -> (!(TicTacToe,TicTac), Maybe Void, !*JSWorld)
onUpdate editorId _ state st world = (state,st,world) //(state,redraw "tictactoe" state world)
onCellClick :: Coordinate ComponentId (JSVal EditletEvent) (TicTacToe,TicTac) (Maybe Void) *JSWorld -> (!(TicTacToe,TicTac), Maybe Void, !*JSWorld)
onCellClick coord editorId event (board,turn) st world
# state = (add_cell coord turn board, ~turn)
= (state, st, redraw "tictactoe" state world)
redraw :: !String !(TicTacToe,TicTac) *JSWorld -> *JSWorld
redraw editorId state world = setDomAttr editorId "innerHTML" (toJSVal (toString (init_board editorId state))) world
init_board :: !String !(TicTacToe,TicTac) -> HtmlTag
init_board editorId (board,turn)
= TableTag [BorderAttr "0"]
[ TrTag [] [ cell {col=x,row=y} \\ x <- [0..2] ] \\ y <- [0..2] ]
where
cell c = case lookup1 c (tiles board) of
Filled t = TdTag [] [TileTag (64,64) t]
Clear = TdTag [AlignAttr "center"] [ButtonTag [IdAttr (cellId editorId c)] [Text "Choose"]]
TileTag (w,h) t = ImgTag [ SrcAttr ("/" <+++ t <+++ ".png"), WidthAttr (toString w), HeightAttr (toString h) ]
cellId editorId {col,row} = editorId <+++ "-" <+++ col <+++ row
tiles :: !TicTacToe -> [(Coordinate,Tile)]
tiles board
= flatten [ [ ({col=x,row=y},cell)
\\ cell <- row & x <- [0..]
]
\\ row <- board & y <- [0..]
]
add_cell :: !Coordinate !TicTac !TicTacToe -> TicTacToe
add_cell new turn board
= [ [ if (new === {col=x,row=y}) (Filled turn) cell
\\ cell <- row & x <- [0..]
]
\\ row <- board & y <- [0..]
]
lookup1 key table = hd [v \\ (k,v) <- table | k === key]
empty_board :: TicTacToe
empty_board = repeatn 3 (repeatn 3 Clear)
defcm = { configuration = [CMMode "javascript", CMLineNumbers True]
, position = 0
, selection = Nothing
, source = "Buu"}
//test5 = updateInformation "CodeMirror" [] (codeMirrorEditlet "buu")
test5 :: Task CodeMirror
test5 = withShared defcm (\defcm -> updateSharedInformation "CodeMirror Settings" [] defcm
-||
updateSharedInformation "CodeMirror Editor"
[UpdateWith (\cm -> codeMirrorEditlet cm [])
(\_ (Editlet value _) -> value)] defcm )
//test5 = updateInformation "CodeMirror" [] (codeMirrorEditlet gDefault{|*|} [])
test4 = updateInformation "Tic tac toe" [] (tictactoelet (empty_board,Tic))
test2 = updateInformation "Test" [] (timelet (fromString "13:00:00"))
test3 = viewSharedInformation "Clock2" [] (mapRead (\t -> (timelet t,clocklet t)) currentTime)
//||- viewInformation (Title "Buienradar") [] buienLet
//<<@ AfterLayout (uiDefSetDirection Horizontal)
//test = viewSharedInformation "Clock" [ViewWith timeEditlet] currentTime
test = updateInformation "String" [] stringlet @ (\(Editlet value _) -> value) >&> viewSharedInformation "DEBUG" []
test6 = viewInformation "JointJS" [] (jointJSEditlet JointJS)
Start :: *World -> *World
Start world = startEngine test6 world