{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
module Reflex.Dom.Internal
  ( module Main
  , run
  , mainWidget
  , mainWidgetWithHead, mainWidgetWithCss, mainWidgetWithHead', mainWidgetInElementById, runApp'
  , mainHydrationWidgetWithHead, mainHydrationWidgetWithHead'
  ) where

import Data.ByteString (ByteString)
import Data.Text (Text)
import Reflex.Dom.Main as Main hiding
       (mainWidget, mainWidgetWithHead, mainWidgetWithCss,
        mainWidgetWithHead', mainWidgetInElementById, runApp',
        mainHydrationWidgetWithHead, mainHydrationWidgetWithHead')
import qualified Reflex.Dom.Main as Main
       (mainWidget, mainWidgetWithHead, mainWidgetWithCss,
        mainWidgetWithHead', mainWidgetInElementById, runApp',
        mainHydrationWidgetWithHead, mainHydrationWidgetWithHead')

#if defined(ghcjs_HOST_OS)
run :: a -> a
run = id
#elif defined(MIN_VERSION_jsaddle_warp)
import Language.Javascript.JSaddle (JSM)
import qualified Language.Javascript.JSaddle.Warp as JW
import System.Environment (lookupEnv)

run :: JSM () -> IO()
run jsm = do
  port <- maybe 3003 read <$> lookupEnv "JSADDLE_WARP_PORT"
  putStrLn $ "Running jsaddle-warp server on port " <> show port
  JW.run port jsm

#elif defined(MIN_VERSION_jsaddle_wkwebview)
#if defined(ios_HOST_OS)
import Data.Default
import Data.Monoid ((<>))
import Language.Javascript.JSaddle (JSM)
import Language.Javascript.JSaddle.WKWebView (run', mainBundleResourcePath)
import Language.Javascript.JSaddle.WKWebView.Internal (jsaddleMainHTMLWithBaseURL)

-- TODO: upstream to jsaddle-wkwebview
run :: JSM () -> IO ()
run jsm = do
  let indexHtml = "<!DOCTYPE html><html><head></head><body></body></html>"
  baseUrl <- mainBundleResourcePath >>= \case
    Nothing -> do
      putStrLn "Reflex.Dom.run: unable to find main bundle resource path. Assets may not load properly."
      return ""
    Just p -> return $ "file://" <> p <> "/index.html"
  run' def $ jsaddleMainHTMLWithBaseURL indexHtml baseUrl jsm

#else
import Language.Javascript.JSaddle.WKWebView (run)
#endif
#elif defined(ANDROID)
import Android.HaskellActivity
import Control.Monad
import Control.Monad.IO.Class (liftIO, MonadIO)
import Control.Concurrent
import Language.Javascript.JSaddle (JSM)
import Data.Default
import Data.IORef
import Data.Maybe
import Data.String
import Reflex.Dom.Android.MainWidget
import System.IO
import System.IO.Unsafe
import Language.Javascript.JSaddle (JSM, eval)

run :: JSM () -> IO ()
run jsm = do
  hSetBuffering stdout LineBuffering
  hSetBuffering stderr LineBuffering
  continueWithCallbacks $ def
    { _activityCallbacks_onCreate = \_ -> do
        a <- getHaskellActivity
        let startPage = fromString "https://appassets.androidplatform.net/index.html"
        startMainWidget a startPage jsm
    , _activityCallbacks_onBackPressed = triggerBackButton
    }
  forever $ threadDelay 1000000000

triggerBackButton :: MonadIO m => m ()
triggerBackButton = withGlobalJSExecutor goBack

#elif defined(wasm32_HOST_ARCH)
import qualified Language.Javascript.JSaddle.Wasm as Wasm (run)
import Language.Javascript.JSaddle (JSM)
run :: JSM () -> IO ()
run = Wasm.run 0

#else
import Language.Javascript.JSaddle.WebKitGTK (run)

#endif

mainWidget :: (forall x. Widget x ()) -> IO ()
mainWidget :: (forall x. Widget x ()) -> IO ()
mainWidget forall x. Widget x ()
w = JSM () -> IO ()
run (JSM () -> IO ()) -> JSM () -> IO ()
forall a b. (a -> b) -> a -> b
$ (forall x. Widget x ()) -> JSM ()
Main.mainWidget Widget x ()
forall x. Widget x ()
w
{-# INLINE mainWidget #-}

mainWidgetWithHead :: (forall x. Widget x ()) -> (forall x. Widget x ()) -> IO ()
mainWidgetWithHead :: (forall x. Widget x ()) -> (forall x. Widget x ()) -> IO ()
mainWidgetWithHead forall x. Widget x ()
h forall x. Widget x ()
b = JSM () -> IO ()
run (JSM () -> IO ()) -> JSM () -> IO ()
forall a b. (a -> b) -> a -> b
$ (forall x. Widget x ()) -> (forall x. Widget x ()) -> JSM ()
Main.mainWidgetWithHead Widget x ()
forall x. Widget x ()
h Widget x ()
forall x. Widget x ()
b
{-# INLINE mainWidgetWithHead #-}

mainWidgetWithCss :: ByteString -> (forall x. Widget x ()) -> IO ()
mainWidgetWithCss :: ByteString -> (forall x. Widget x ()) -> IO ()
mainWidgetWithCss ByteString
css forall x. Widget x ()
w = JSM () -> IO ()
run (JSM () -> IO ()) -> JSM () -> IO ()
forall a b. (a -> b) -> a -> b
$ ByteString -> (forall x. Widget x ()) -> JSM ()
Main.mainWidgetWithCss ByteString
css Widget x ()
forall x. Widget x ()
w
{-# INLINE mainWidgetWithCss #-}

mainWidgetWithHead' :: (a -> Widget () b, b -> Widget () a) -> IO ()
mainWidgetWithHead' :: forall a b. (a -> Widget () b, b -> Widget () a) -> IO ()
mainWidgetWithHead' (a -> Widget () b, b -> Widget () a)
w = JSM () -> IO ()
run (JSM () -> IO ()) -> JSM () -> IO ()
forall a b. (a -> b) -> a -> b
$ (a -> Widget () b, b -> Widget () a) -> JSM ()
forall a b. (a -> Widget () b, b -> Widget () a) -> JSM ()
Main.mainWidgetWithHead' (a -> Widget () b, b -> Widget () a)
w
{-# INLINE mainWidgetWithHead' #-}

mainWidgetInElementById :: Text -> (forall x. Widget x ()) -> IO ()
mainWidgetInElementById :: Text -> (forall x. Widget x ()) -> IO ()
mainWidgetInElementById Text
eid forall x. Widget x ()
w = JSM () -> IO ()
run (JSM () -> IO ()) -> JSM () -> IO ()
forall a b. (a -> b) -> a -> b
$ Text -> (forall x. Widget x ()) -> JSM ()
Main.mainWidgetInElementById Text
eid Widget x ()
forall x. Widget x ()
w
{-# INLINE mainWidgetInElementById #-}

runApp' :: (forall x. AppInput DomTimeline -> Widget x (AppOutput DomTimeline)) -> IO ()
runApp' :: (forall x.
 AppInput DomTimeline -> Widget x (AppOutput DomTimeline))
-> IO ()
runApp' forall x. AppInput DomTimeline -> Widget x (AppOutput DomTimeline)
app = JSM () -> IO ()
run (JSM () -> IO ()) -> JSM () -> IO ()
forall a b. (a -> b) -> a -> b
$ (forall x.
 AppInput DomTimeline -> Widget x (AppOutput DomTimeline))
-> JSM ()
forall t.
(t ~ DomTimeline) =>
(forall x. AppInput t -> Widget x (AppOutput t)) -> JSM ()
Main.runApp' AppInput DomTimeline -> Widget x (AppOutput DomTimeline)
forall x. AppInput DomTimeline -> Widget x (AppOutput DomTimeline)
app
{-# INLINE runApp' #-}

mainHydrationWidgetWithHead :: (forall x. HydrationWidget x ()) -> (forall x. HydrationWidget x ()) -> IO ()
mainHydrationWidgetWithHead :: (forall x. HydrationWidget x ())
-> (forall x. HydrationWidget x ()) -> IO ()
mainHydrationWidgetWithHead forall x. HydrationWidget x ()
h forall x. HydrationWidget x ()
b = JSM () -> IO ()
run (JSM () -> IO ()) -> JSM () -> IO ()
forall a b. (a -> b) -> a -> b
$ (forall x. HydrationWidget x ())
-> (forall x. HydrationWidget x ()) -> JSM ()
Main.mainHydrationWidgetWithHead HydrationWidget x ()
forall x. HydrationWidget x ()
h HydrationWidget x ()
forall x. HydrationWidget x ()
b
{-# INLINE mainHydrationWidgetWithHead #-}

mainHydrationWidgetWithHead' :: HydrationWidget () () -> HydrationWidget () () -> IO ()
mainHydrationWidgetWithHead' :: HydrationWidget () () -> HydrationWidget () () -> IO ()
mainHydrationWidgetWithHead' HydrationWidget () ()
h HydrationWidget () ()
b = JSM () -> IO ()
run (JSM () -> IO ()) -> JSM () -> IO ()
forall a b. (a -> b) -> a -> b
$ HydrationWidget () () -> HydrationWidget () () -> JSM ()
Main.mainHydrationWidgetWithHead' HydrationWidget () ()
h HydrationWidget () ()
b
{-# INLINE mainHydrationWidgetWithHead' #-}