import Control.Concurrent
import Graphics.UI.Gtk
import System.Random

verifyCommand  = "Click me to verify that the GUI is still responding."
thinkCommand   = "Think really hard."
thinkObedience = "Thinking really hard..."

main = do
	-- Now for some setup. We're about to make some Gtk calls, so we should
	-- ask ourselves: are we either on the main thread or calling postGUI?
	-- Yes, we're on the main thread. Good to go.
	initGUI
	window <- windowNew
	vbox   <- vBoxNew True 2
	check  <- checkButtonNewWithLabel verifyCommand
	button <- buttonNewWithLabel thinkCommand

	-- Next up: we'll make the button actually do something.
	button `on` buttonActivated $ do
		-- Gtk calls are still OK inside this callback! It will be called by
		-- mainGUI, which we're calling below on the main thread...
		forkIO $ do
			-- ...but Gtk calls in this callback are NOT OK. So we'll use
			-- postGUIAsync.
			n <- randomRIO (1e8, 2e8) :: IO Double
			last [0..n] `seq`
			  postGUIAsync (buttonSetLabel button thinkCommand)
		buttonSetLabel button thinkObedience
	onDestroy window mainQuit

	-- Now we just need to plumb everything together and start the GUI.
	containerAdd vbox check
	containerAdd vbox button
	containerAdd window vbox
	widgetShowAll window
	mainGUI
