content: module Foundation
      ( App (..)
      , Route (..)
      , AppMessage (..)
      , resourcesApp
      , Handler
      , Widget
      , Form
      , module Settings
      ) where
  
  import Prelude
  import Yesod
  import Yesod.Static
  import Yesod.Default.Config
  import Yesod.Default.Util (addStaticContentExternal)
  import qualified Settings
  --import Settings.StaticFiles
  import Settings (widgetFile, Extra (..))
  import Text.Hamlet (hamletFile)
  import Data.Text (Text)
  import Data.IORef (IORef, readIORef)
  import Distribution.PackDeps.Types (Newest, Reverses, LicenseMap)
  import Yesod.Form.Jquery (YesodJquery)
  import Data.Time (UTCTime)
  
  -- | The site argument for your application. This can be a good place to
  -- keep settings and values requiring initialization before your application
  -- starts running, such as database connections. Every handler will have
  -- access to the data present here.
  data App = App
      { settings :: AppConfig DefaultEnv Extra
      , getStatic :: Static -- ^ Settings for static file serving.
      , appData :: IORef (Maybe (Newest, Reverses, (LicenseMap, LicenseMap), UTCTime))
      }
  
  -- Set up i18n messages. See the message folder.
  mkMessage "App" "messages" "en"
  
  -- This is where we define all of the routes in our application. For a full
  -- explanation of the syntax, please see:
  -- http://www.yesodweb.com/book/handler
  --
  -- This function does three things:
  --
  -- * Creates the route datatype AppRoute. Every valid URL in your
  --   application can be represented as a value of this type.
  -- * Creates the associated type:
  --       type instance Route App = AppRoute
  -- * Creates the value resourcesApp which contains information on the
  --   resources declared below. This is used in Handler.hs by the call to
  --   mkYesodDispatch
  --
  -- What this function does *not* do is create a YesodSite instance for
  -- App. Creating that instance requires all of the handler functions
  -- for our application to be in scope. However, the handler functions
  -- usually require access to the AppRoute datatype. Therefore, we
  -- split these actions into two functions and place them in separate files.
  mkYesodData "App" $(parseRoutesFile "config/routes")
  
  type Form x = Html -> MForm Handler (FormResult x, Widget)
  
  -- Please see the documentation for the Yesod typeclass. There are a number
  -- of settings which can be configured by overriding methods here.
  instance Yesod App where
      approot = guessApproot
  
      -- Disable sessions
      makeSessionBackend _ = return Nothing
  
      defaultLayout widget = do
          master <- getYesod
          mmsg <- getMessage
  
          -- We break up the default layout into two components:
          -- default-layout is the contents of the body tag, and
          -- default-layout-wrapper is the entire page. Since the final
          -- value passed to hamletToRepHtml cannot be a widget, this allows
          -- you to use normal widget features in default-layout.
  
          mAppData <- liftIO $ readIORef $ appData master
          let mLastUpdate =
                  case mAppData of
                      Nothing -> Nothing
                      Just (_, _, _, x) -> Just x
  
          pc <- widgetToPageContent $ do
              {- why this are commented?
              $(widgetFile "normalize")
              addStylesheet $ StaticR css_bootstrap_css
              -}
              $(widgetFile "default-layout")
          withUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet")
  
      -- This function creates static content files in the static folder
      -- and names them based on a hash of their content. This allows
      -- expiration dates to be set far in the future without worry of
      -- users receiving stale content.
      addStaticContent = addStaticContentExternal Right base64md5 Settings.staticDir (StaticR . flip StaticRoute [])
  
      -- Place Javascript at bottom of the body tag so the rest of the page loads first
      jsLoader _ = BottomOfBody
  
  instance YesodJquery App
  
  -- This instance is required to use forms. You can modify renderMessage to
  -- achieve customized and internationalized form validation messages.
  instance RenderMessage App FormMessage where
      renderMessage _ _ = defaultFormMessage
  