{-# LANGUAGE CPP, FlexibleContexts, TypeFamilies #-}
{-# OPTIONS_GHC -F -pgmFtrhsx #-}
module Main where

import Control.Applicative ((<$>))
import Control.Concurrent (forkIO, killThread)
import Control.Monad (msum)
import Control.Monad.Reader (MonadReader(..), ReaderT(..))
import Control.Monad.Trans(MonadIO(liftIO))
import Data.List (sort)
import Data.Set  (Set, fromList, insert)
import Happstack.Server as H (Browsing(DisableBrowsing), Conf(port), Method(GET), Response, ServerPartT, asContentType, dir, serveDirectory, mapServerPartT, methodM, nullConf, ok, nullDir, seeOther, serveFile, simpleHTTP, toResponse)
import Happstack.Server.SimpleHTTP (waitForTermination)
import Happstack.Server.HSP.HTML ()
import HSP.Google.Analytics(UACCT(UACCT), analytics)
import HSP
import HSP.ServerPartT ()
import Network.IRC ()
import Network.IRC.Bot               (BotMonad)
import Network.IRC.Bot.Core as B (User(..), BotConf(..), simpleBot, nullBotConf)
import Network.IRC.Bot.Part.Channels ( initChannelsPart )
import Network.IRC.Bot.Part.Dice     ( dicePart )
import Network.IRC.Bot.Part.Hello    ( helloPart )
import Network.IRC.Bot.Part.NickUser ( nickUserPart )
import Network.IRC.Bot.Part.Ping     ( pingPart )
import Network.IRC.Bot.Log       ( nullLogger )
import Network.IRC.Bot.PosixLogger ( posixLogger )
import qualified HSX.XMLGenerator as HSX
import Network(PortID(PortNumber))
import System.Console.GetOpt (ArgDescr(NoArg, ReqArg), ArgOrder(Permute), OptDescr(Option), getOpt)
import System.Directory (createDirectoryIfMissing, getDirectoryContents)
import System.Environment (getArgs, getProgName)
import System.Exit (exitFailure)
import System.FilePath
import System.IO (stdout)
import System.Log.Logger (Priority(DEBUG, INFO, ERROR), logM, rootLoggerName, setHandlers, setLevel, updateGlobalLogger)
import System.Log.Handler.Simple (fileHandler, streamHandler)
#ifdef __CABAL__
import Paths_happstackDotCom (getDataDir)
#endif

main :: IO ()
main = do 
  progName <- getProgName
#ifdef __CABAL__
  dd  <- getDataDir
  let defaultConf' = (defaultConf progName) { dataDir = dd }
#else
  let defaultConf' = defaultConf progName
#endif
  -- parse the command-line options
  args <- getArgs
  appConf <- case parseConfig args of
               (Left e) -> do logM progName ERROR (unlines e)
                              exitFailure
               (Right f) -> return (f defaultConf')

  -- create log directory if missing
  createDirectoryIfMissing True (logDir appConf)

  -- setup the log files
  setupLogger progName (logDir appConf) (logMode appConf)
             
  -- start IRC bot
  ircTids <- if (ircBot appConf) 
               then do let botConf = nullBotConf { channelLogger = Just $ posixLogger (Just $ ircLogDir appConf) "#happs"
                                                 , B.logger = nullLogger
                                                 , host   = "irc.freenode.net"
                                                 , B.port = (PortNumber 6667)
                                                 , nick   = ircNick appConf
                                                 , user   = User { username   = ircNick appConf
                                                                 , hostname   = "happstack.com"
                                                                 , servername = "irc.freenode.net"
                                                                 , realname   = "happstack.com bot"
                                                                 }
                                                 , channels = ircChans appConf 
                                                 }
                       ircParts  <- initIrcParts (channels botConf)
                       simpleBot botConf ircParts
               else return []

  let themeDir = (dataDir appConf) </> "theme"
  httpTid <- forkIO $ simpleHTTP (httpConf appConf) (impl appConf themeDir (docDir appConf) (ircLogDir appConf))
  waitForTermination
  killThread httpTid
  mapM_ killThread ircTids

impl :: AppConf -> FilePath -> FilePath -> FilePath -> ServerPartT IO Response
impl appConf themeDir docDir ircLogDir = 
   mapServerPartT (flip runReaderT appConf) $
    msum [ dir "favicon.ico"    $ serveFile (asContentType "http://image/vnd.microsoft.icon") (themeDir </> "favicon.ico")
         , dir "theme"          $ serveDirectory DisableBrowsing [] themeDir
         , dir "irc-logs"       $ msum [ do methodM GET ; (ok . toResponse) =<< (unXMLGenT $ ircLogs ircLogDir)
                                       , serveDirectory DisableBrowsing [] ircLogDir
                                       ]
         , dir "index.html"     $ (ok . toResponse) =<< (unXMLGenT home)
         , dir "download"       $ (ok . toResponse) =<< (unXMLGenT download)
         , dir "docs"           $ msum [ do { nullDir ; (ok . toResponse) =<< (unXMLGenT docs) } 
                                       , dir "crashcourse" $ serveDirectory DisableBrowsing [] "/home/jeremy/public_html/happstack-crashcourse"
                                       , serveDirectory DisableBrowsing [] docDir
                                       ]
         , dir "community"      $ (ok . toResponse) =<< (unXMLGenT community)

         , methodM GET >> seeOther "/index.html" (toResponse "index.html")
         ]

data AppConf
    = AppConf { httpConf   :: Conf
              , baseURI    :: String
              , store      :: FilePath
              , dataDir    :: FilePath 
              , docDir     :: FilePath
              , ircLogDir  :: FilePath
              , logDir     :: FilePath
              , logMode    :: LogMode
              , ircBot     :: Bool
              , ircNick    :: String
              , ircChans   :: Set String
              , uacct      :: Maybe UACCT
              }

defaultConf :: String -> AppConf
defaultConf progName 
    = AppConf { httpConf  = nullConf
              , baseURI   = "/"
              , store     = "_local/" ++ progName ++ "_state"
              , dataDir   = ""
              , docDir    = "docs"
              , ircLogDir = "irc-logs"
              , logDir    = "logs"
              , logMode   = Development
              , ircBot    = False
              , ircNick   = "synthea"
              , ircChans  = fromList ["#happs"]
              , uacct     = Nothing
              }

data LogMode
    = Production
    | Development
      deriving (Read, Show, Eq, Ord, Enum, Bounded)

setupLogger :: String -> FilePath -> LogMode -> IO ()
setupLogger progName logDir logMode = do
    appLog    <- fileHandler (logDir </> (progName ++ "_root.log"))   DEBUG
    accessLog <- fileHandler (logDir </> (progName ++ "_access.log")) INFO
    stdoutLog <- streamHandler stdout DEBUG

    case logMode of
      Development -> do
          -- Root Log
          updateGlobalLogger rootLoggerName 
            (setLevel DEBUG . setHandlers [appLog, stdoutLog])
          -- Access Log
          updateGlobalLogger "Happstack.Server.AccessLog.Combined" 
            (setLevel INFO . setHandlers [accessLog])

      Production -> do
          -- Root Log
          updateGlobalLogger rootLoggerName 
            (setLevel INFO . setHandlers [appLog])
          -- Access Log
          updateGlobalLogger "Happstack.Server.AccessLog.Combined" 
            (setLevel INFO . setHandlers [accessLog])

opts :: [OptDescr (AppConf -> AppConf)]
opts = [ Option [] ["http-port"]   (ReqArg (\h c -> c { httpConf = (httpConf c) {H.port = read h} }) "port") "port to bind http server"
       , Option [] ["base-uri"]    (ReqArg (\h c -> c {baseURI = h}) "uri") "http://servername:<port>/"
       , Option [] ["store"]       (ReqArg (\h c -> c {store = h}) "PATH") "The directory used for database storage."
       , Option [] ["static"]      (ReqArg (\h c -> c { dataDir = h}) "PATH") "The directory which contains the data files."
       , Option [] ["data-dir"]    (ReqArg (\h c -> c { dataDir = h}) "PATH") "Alias for --static."
       , Option [] ["doc-dir"]     (ReqArg (\h c -> c { docDir = h}) "PATH") "The directory which contains the haddock documentation files."
       , Option [] ["irc-log-dir"] (ReqArg (\h c -> c { ircLogDir = h}) "PATH") "The directory which contains the irc log files." 
       , Option [] ["log-dir"]     (ReqArg (\h c -> c { logDir = h}) "PATH") "Alias for --logs"
       , Option [] ["logs"]        (ReqArg (\h c -> c { logDir = h}) "PATH") "The directory to store server log files in."
       , Option [] ["log-mode"]    (ReqArg (\h c -> c { logMode = read h}) (show ([minBound .. maxBound] :: [LogMode]))) "The logging mode to use"
       , Option [] ["irc-nick"]    (ReqArg (\h c -> c { ircNick = h}) "nick") "The nick to use on irc."
       , Option [] ["irc-chan"]    (ReqArg (\h c -> c { ircChans = insert h (ircChans c) }) "#chan") "The channel to log on irc."
       , Option [] ["irc-bot"]     (NoArg  (\c   -> c { ircBot = True})) "Run the irc logging bot."
       , Option [] ["enable-analytics"] 
                                   (NoArg  (\c   -> c { uacct = Just (UACCT "UA-7111625-1") })) "Enable google analytics tracking."
       ]


parseConfig :: [String] -> Either [String] (AppConf -> AppConf)
parseConfig args
    = case getOpt Permute opts args of
        (flags,_,[]) -> Right $ \appConf -> foldr ($) appConf flags
        (_,_,errs)   -> Left errs

data PageSection = Home | Download | Docs | Community | Other deriving (Eq, Ord, Show, Read)

appTemplate ::
    ( XMLGenerator m
    , EmbedAsChild m String
    , EmbedAsChild m ()
    , EmbedAsChild m headers
    , EmbedAsChild m body
    , EmbedAsChild m [HSX.XML m]
    , MonadReader  AppConf m 
    ) => String -> headers -> PageSection -> body -> XMLGenT m (HSX.XML m)
appTemplate title headers pagesection body =
    <html>
     <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      <meta name="description" content="A Haskell Web Framework" />
      <meta name="keywords" content="haskell, web framework, web server" />
      <meta name="google-site-verification" content="8J6bU6Xf7cimqJ7B3krUJXwyPFYGEZaA2J6zdqQfVuI" />
      <link href="/theme/theme.css" rel="stylesheet" type="text/css" />
      <link rel="icon" type="image/vnd.microsoft.icon" href="favicon.ico" />
      <title><% title %></title>
      <% headers %>
     </head>
     <body>
      <% top pagesection %>
      <% body %>
      <% footer %>
      <% do appConf <- ask
            case (uacct appConf) of
              Nothing  -> return []
              (Just u) -> analytics u
      %>
     </body>
    </html>

top :: (XMLGenerator m) => PageSection -> XMLGenT m (HSX.XML m)
top pageSection =
   <div id="top">
    <div id="logo">
      <span class="logo-big"><a href="/">Happstack</a></span><br />
      <span class="logo-sub">A Haskell Web Framework</span>
    </div>
    <ul id="main-menu">
      <% if pageSection == Home 
           then <li class="current">Home</li>
           else <li><a href="/">Home</a></li> %>
      <% if pageSection == Download 
           then <li class="current">Download</li>
           else <li><a href="/download">Download</a></li> %>
      <% if pageSection == Docs
           then <li class="current">Docs</li>
           else <li><a href="/docs">Docs</a></li> %>
      <% if pageSection == Community
           then <li class="current">Community</li>
           else <li><a href="/community">Community</a></li> %>
      <li><a href="http://happstack.blogspot.com/">Blog</a></li>
    </ul>
   </div>

footer :: (XMLGenerator m) => XMLGenT m (HSX.XML m)
footer =
   <div id="footer">
     <p>Powered by Happstack: A Haskell Web Framework.</p><p>Get this site's <a href="http://patch-tag.com/r/stepcut/happstackDotCom">source code</a> via <code>darcs get http://patch-tag.com/r/stepcut/happstackDotCom</code></p>
   </div>

sidebar :: (XMLGenerator m) => XMLGenT m (HSX.XML m)
sidebar =
   <div id="sidebar">

     <h3 class="label-green">Contribute</h3>
     <p>Cool stuff you can help with:</p>
     <ul id="quicklinks">
      <li><a href="http://code.google.com/p/happstack/issues/list">Bug Tracker</a></li>
      <li><a href="http://code.google.com/p/happstack/w/list">Happstack Wiki</a></li>
     </ul>

     <h3 class="label-green">Quick Links</h3>
     <ul id="quicklinks">
      <li><a href="/docs/6.0.0/index.html">API Reference</a></li>
      <li><a href="/docs/crashcourse/index.html">Happstack Crash Course</a></li>
      <li><a href="http://groups.google.com/group/HAppS">Mailing List</a></li>
      <li><a href="http://patch-tag.com/r/mae/happstack/">Happstack @ patch-tag.com</a></li>
      <li><a href="http://code.google.com/p/happstack/wiki/RoadMap">Roadmap</a></li>
     </ul>
{-
     <h3 class="label-green">Latest Tweets!</h3>
     <% twitter %>
-}
   </div>

twitter :: (XMLGenerator m) => XMLGenT m (HSX.XML m)
twitter =
    <div id="twitter">
      <script type="text/javascript" src="http://widgets.twimg.com/j/2/widget.js"/>
      <script type="text/javascript">
       new TWTR.Widget({
        version: 2,
        type: 'profile',
        rpp: 8,
        interval: 6000,
        width: 'auto',
        height: 300,
        theme: {
          shell: {
            background: '#fff',
            color: '#000'
          },
          tweets: {
            background: '#ffffff',
            color: '#333333',
            links: '#111166'
          }
         },
        features: {
          scrollbar: true,
          loop: false,
          live: false,
          hashtags: true,
          timestamp: true,
          avatars: false,
          behavior: 'all'
        }
       }).render().setUser('happstack').start();
      </script>
  </div>

{-
oldHomeContent :: (XMLGenerator m) => XMLGenT m (HSX.XML m)
oldHomeContent =
    <div>

     <h1 class="label-green">What is Happstack?</h1>

     <p>Happstack is a Haskell web framework. Happstack is designed so that developers can prototype quickly, deploy painlessly, scale massively, operate reliably, and change easily. It supports GNU/Linux, OS X, FreeBSD, and Windows environments.</p>

     <p>The Happstack project focuses on three areas of development:</p>

     <dl>
      <dt>Integration</dt>
      <dd>Happstack leverages many of the existing high quality libraries available on Hackage. Through integration, Happstack has support for many templating libraries, database libraries, and more.</dd>
      <dt>Innovation</dt>
      <dd>acid-state (a Haskell-based, noSQL RAM cloud), ixset (a Set type which supports multiple indexes), and web-routes (type-safe url routing), all began as Happstack projects. They are available, however, for use with any framework, not just Happstack.</dd>
      <dt>Documentation</dt>
      <dd>There are three layers of documentation.
        <ol>
         <li><b>API documentation</b> - good haddock documentation with examples for the whole API.</li>
         <li><b>API tutorials</b> - good haddock documentation is essential, but not sufficient. In order to learn a new API, you need a guide that shows you where to get started, explains the big picture, and shows you how to handle specific tasks. The <a href="http://happstack.com/docs/crashcourse/index.html">Happstack Crashcourse</a> is a growing tutorial which shows you how to develop web applications using Happstack. It includes many small, self-contained and thoroughly explained examples which you can download and run.</li>
         <li><b>High-level design</b> - Using great libraries does not guarantee success anymore than using great ingredients guarantees a delicious cake. There are many important design decisions that must be made along the way. Each website is grows differently and has different requirements. So, the next level of documentation will discuss various design ideologies, practices, and how to implement them using Happstack. This will include topics like content and presentation layer separation, REST, MVC-style design, data partitioning, staging and deployment, etc.</li>
        </ol>
      </dd> 
     </dl>
     <h2 class="label-yellow">Some Happstack Technologies</h2>
     <h3 class="label-red">RAM Cloud Database Architecture</h3>
     <p>Happstack favors the use of acid-state, a <a href="http://highscalability.com/blog/2009/3/16/are-cloud-based-memory-architectures-the-next-big-thing.html">RAM cloud</a> database architecture. acid-state provides you the speed and predictability of RAM based queries combined with the durability, replication, and ACID properties of traditional databases. This architecture provides you with fast, predictable query times with out the uncertainly of cache misses. It simplifies your development because it is built around Haskell datatypes and functions. This means you do not need to learn a specialized query language. You also do not have to worry about database denormalization, data marshaling, <a href="http://xkcd.com/327/">SQL-injection attacks</a>, etc. Nor do you have to worry about installing, tuning, configuring, and upgrading a caching layer such as memcached or database servers.</p>

     <p>Happstack can also be used with existing databases such as MySQL, Postgres, Cassandra, CouchDB, etc. if that better suits your needs.</p>

     <h3 class="label-red">Integrated HTTP Server</h3>
     <p>Happstack includes an fast, secure, integrated HTTP server. This means you do not need to install, maintain, and configure a separate HTTP server such as Apache. Because the server is integrated into your application, you also have opportunity for your application to automatic adjust and tune the parameters at run-time.</p>

     <h3 class="label-red">Flexible Routing and Request Processing DSL</h3>
     <p>Happstack provides a flexible system for mapping URIs to handlers, processing the QUERY_STRING and request body, and generating responses.</p>

     <h3 class="label-red">Flexible Templating Options</h3>
     <p>Happstack does not force you to use any particular templating or HTML generation solution. Each organization and project has different needs and a one size fits all approach can not satisfy everyone. Instead Happstack provides integration with a variety of templating solutions to meet different needs. This includies HSP, HStringTemplate, hamlet, heist, BlazeHTML and more! It is easy to add additional 3rd party or custom options as well. A discussion of options can be found <a href="http://happstack.com/docs/crashcourse/Templates.html#templates">here</a>.</p>

     <h3 class="label-red">Type-Safety</h3>
     <p>Happstack includes a number of optional features which can increase the type safety of your web application. This means greater assurance that your site is free from broken URLs, SQL and javascript injection attacks, missing form fields, etc. This includes technology such as <a href="http://happstack.com/docs/crashcourse/WebRoutes.html">web-routes</a> for type-safe URL routing and <a href="https://github.com/jaspervdj/digestive-functors">digestive-functors</a> for type-safe form processing.</p>

     <h2 class="label-yellow">Getting Started</h2>
     <p>The fastest way to get started is to install happstack from hackage using cabal.</p>
     <div class="code">
      <code>
       $ export PATH=~/.cabal/bin:$PATH<br />
       $ cabal update<br />
       $ cabal install happstack
      </code>
     </div>

     <h2 class="label-yellow">Simple App</h2>
     <p>Here is a simple app to test out your installation. The application will run on port 8000 by default. If you are reading this website on the same machine you are running the app on, just <a href="http://localhost:8000/">click here</a> to see it.</p>

     <div class="code">

      <p><span class="hs-keyword">module</span> <span class="hs-conid">Main</span> <span class="hs-keyword">where</span></p>

      <p><span class="hs-keyword">import</span> <span class="hs-conid">Happstack</span><span class="hs-varop">.</span><span class="hs-conid">Server</span></p>
      <p><span class="hs-definition">main</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">simpleHTTP</span> <span class="hs-varid">nullConf</span> <span class="hs-varop">$</span> <span class="hs-varid">ok</span> <span class="hs-str">"Hello, World!"</span></p>

    </div>

   </div>
-}

homeContent :: (XMLGenerator m) => XMLGenT m (HSX.XML m)
homeContent =
    <div>
     <h1 class="label-green">News (via Twitter)</h1>
     <% twitter %>
     <p>Follow us on <a href="http://www.twitter.com/happstack">Twitter</a></p>
     <h1 class="label-green">What is Happstack?</h1>

     <p>Happstack is a fast and flexible Haskell web framework. Happstack is designed so that developers can prototype quickly, deploy painlessly, scale massively, operate reliably, and change easily. Happstack is supported on GNU/Linux, OS X, FreeBSD, and Windows environments.</p>

     <h2 class="label-yellow"><span class="package-name">happstack-server</span></h2>
     <p>At the core of Happstack is <a href="http://hackage.haskell.org/package/happstack-server"><span class="package-name">happstack-server</span></a>. <span class="package-name">happstack-server</span> is a fast and simple HTTP server with built-in support for templating (via <a href="http://happstack.com/docs/crashcourse/Templates.html#helloblaze"><span class="package-name">blaze-html</span></a>), request routing, form-decoding, cookies, file-uploads, etc. <span class="package-name">happstack-server</span> is all you need to create a simple website.</p>

     <p><span class="package-name">happstack-server</span> is database agnostic and can be used with any of your favorite database libraries from <a href="http://hackage.haskell.org/packages/hackage.html">hackage</a>. <span class="package-name">happstack-server</span> is extensively documented in <a href="http://happstack.com/docs/crashcourse/index.html">The Happstack Crashcourse</a>.</p>

     <h2 class="label-yellow"><span class="package-name">happstack-lite</span></h2>
     <p><span class="package-name">happstack-lite</span> is a streamlined version of Happstack designed to make it quick and easy to start developing web applications. For more information check out the <a href="http://happstack.com/docs/happstack-lite/happstack-lite.html"><span class="package-name">happstack-lite</span> tutorial.</a></p>

     <h2 class="label-yellow">Extensions</h2>
     
     <p>Happstack provides a wide range of extensions including:</p>
     <dl>
      <dt><span class="package-name">acid-state</span></dt>
      <dd><a href="http://acid-state.seize.it/"><span class="package-name">acid-state</span></a> is a native Haskell, in-memory, transactional ACID, noSQL database. <span class="package-name">acid-state</span> is a cleaner, faster, and more robust rewrite of the classic <a href="http://happstack.com/docs/crashcourse/HappstackState.html#happstack_state"><span class="package-name">happstack-state</span></a> system. It can easily store complex Haskell datatypes, queries are written in Haskell, and it uses <a href="http://acid-state.seize.it/safecopy"><span class="package-name">safecopy</span></a> for automatic version migration. </dd>

     <dt><span class="package-name">ixset</span></dt>
      <dd><a href=""><span class="package-name">ixset</span></a> is a set-like datatype with support for multiple indexes. It is similar to a table in a traditional SQL database. <span class="package-name">ixset</span> is often used with the <a href="http://acid-state.seize.it/"><span class="package-name">acid-state</span></a> library.</dd>

      <dt><span class="package-name">happstack-plugins</span></dt>
        <dd><a href="http://hackage.haskell.org/package/happstack-plugins"><span class="package-name">happstack-plugins</span></a> provides on-the-fly recompilation and dynamic loading of code into running servers. This is especially useful for reloading compiled HTML templates (such as <span class="package-name">blaze-html</span>). Check out a demonstration <a href="http://happstack.blogspot.com/2010/10/recompile-your-haskell-based-templates.html">here</a>.</dd>
      <dt><span class="package-name">jmacro</span></dt>
       <dd><a href="http://hackage.haskell.org/package/jmacro"><span class="package-name">jmacro</span></a> is a Javascript templating library. It supports splicing Haskell values into Javascript, static syntax checking, hygienic naming, and more. Documentation on using it with Happstack can be found <a href="http://happstack.com/docs/crashcourse/Templates.html#jmacro">here</a>.</dd>

      <dt><span class="package-name">happstack-hsp</span></dt>
      <dd><span class="package-name">happstack-hsp</span> leverages the <span class="package-name">HSX</span> and <span class="package-name">HSP</span> libraries to provide powerful XML and HTML templates. <span class="package-name">HSX</span> allows literal XML markup to be embedded in Haskell code. This means that you have the full power of Haskell at your disposal in your templates, not some weak, limited templating language.</dd>

     <dt><span class="package-name">happstack-heist</span></dt>
     <dd><a href="http://hackage.haskell.org/package/happstack-heist"><span class="package-name">happstack-heist</span></a> brings the power of <a rel="nofollow" href="http://snapframework.com/docs/tutorials/heist"><span class="package-name">heist</span></a> templates to Happstack. <span class="package-name">heist</span> aims to keep the presentation and business logic well separated. Because <span class="package-name">heist</span> uses external <kbd>.xml</kbd> files for the templates, the templates can be easily edited by non-programmers and modifications do not require the server to be recompiled or restarted. Using <span class="package-name">heist</span> with Happstack is documented <a href="http://happstack.com/docs/crashcourse/Templates.html#helloheist">here</a>.</dd>

     <dt><span class="package-name">happstack-hamlet</span></dt>
      <dd><a href="http://hackage.haskell.org/package/happstack-hamlet"><span class="package-name">happstack-hamlet</span></a> brings <a href="http://www.yesodweb.com/book/templates/conceptId_________" rel="nofollow"><span class="package-name">hamlet</span></a> templates to Happstack.</dd>

     <dt><span class="package-name">happstack-hstringtemplate</span></dt>
      <dd><a href="http://hackage.haskell.org/package/happstack-hstringtemplate"><span class="package-name">happstack-hstringtemplate</span></a> allows the use of templates which are similar to the Java <a href="http://www.stringtemplate.org/" rel="nofollow">StringTemplate</a> engine.</dd>

     <dt><span class="package-name">web-routes</span></dt>
      <dd><span class="package-name">web-routes</span> is a family of libraries which provide type-safe URL routing. URLs can be mapped to types and back via a number of methods including invertible-syntax descriptions, parsec, template-haskell, quasi-quotation, and more. Documenation can be found <a href="http://happstack.com/docs/crashcourse/WebRoutes.html#web-routes">here</a>.</dd>

     <dt><span class="package-name">digestive-functors</span></dt>
      <dd>The <a href="http://hackage.haskell.org/package/digestive-functors"><span class="package-name">digestive-functors</span></a> library provides type-safe, composable HTML form generation and processing. The <a href="http://hackage.haskell.org/package/digestive-functors-happstack"><span class="package-name">digestive-functors-happstack</span></a> library provides Happstack support. The <a href="http://hackage.haskell.org/package/digestive-functors-hsp"><span class="package-name">digestive-functors-hsp</span></a> library includes combinators for using <span class="package-name">digestive-functors</span> with <span class="package-name">HSP</span> templates.</dd>

     <dt><span class="package-name">happstack-authenticate</span></dt>
      <dd><a href="http://src.seereason.com/happstack-authenticate/"><span class="package-name">happstack-authenticate</span></a> is a high-level authentication library for Happstack built on top of the <a href="http://hackage.haskell.org/package/authenticate"><span class="package-name">authenticate</span></a> library. It provides support for authentication via OpenId, Facebook, or a username/password. It includes support for multiple authentication methods per account, as well as multiple personalities per account. It includes themeable templates that can easily be integrated into your site.</dd>

      <dt><span class="package-name">Other</span></dt>
       <dd>Happstack can also be used with a wide variety of packages on hackage with no special support. You can use database libraries like, HDBC, Takusen, CouchDB, etc. You can use libraries like aeson for JSON support. Happstack is designed to be open and flexible.</dd>

     </dl>

     <h2 class="label-yellow">Getting Started</h2>
     <p>The fastest way to get started is to install happstack from hackage using cabal.</p>
     <div class="code">
      <code>
       $ export PATH=~/.cabal/bin:$PATH<br />
       $ cabal update<br />
       $ cabal install happstack-server
      </code>
     </div>

     <h2 class="label-yellow">Simple App</h2>
     <p>Here is a simple app to test out your installation. The application will run on port 8000 by default. If you are reading this website on the same machine you are running the app on, just <a href="http://localhost:8000/">click here</a> to see it.</p>

     <div class="code">

      <p><span class="hs-keyword">module</span> <span class="hs-conid">Main</span> <span class="hs-keyword">where</span></p>

      <p><span class="hs-keyword">import</span> <span class="hs-conid">Happstack</span><span class="hs-varop">.</span><span class="hs-conid">Server</span></p>
      <p><span class="hs-definition">main</span> <span class="hs-keyglyph">=</span> <span class="hs-varid">simpleHTTP</span> <span class="hs-varid">nullConf</span> <span class="hs-varop">$</span> <span class="hs-varid">ok</span> <span class="hs-str">"Hello, World!"</span></p>

    </div>

    <p>Next, head over to the <a href="/docs/crashcourse/index.html">Happstack Crash Course</a> and start hacking!</p>

   </div>


home :: (XMLGenerator m, EmbedAsChild m [HSX.XML m], EmbedAsChild m (), MonadReader AppConf m) => XMLGenT m (HSX.XML m)
home =
    appTemplate "Happstack - A Haskell Web Framework" () Home $ 
      mainContent homeContent

download :: (XMLGenerator m, EmbedAsChild m [HSX.XML m], EmbedAsChild m (), MonadReader AppConf m) => XMLGenT m (HSX.XML m)
download =
    appTemplate "Happstack - Download" () Download $ 
      mainContent $ 
        <div>
          <h1 class="label-green">How to get Happstack</h1>
           <h2 class="label-yellow"><code>cabal install happstack</code></h2>
            <p>The easiest way to get happstack is to just install it from <a href="http://www.google.co.uk/search?hl=en&as_sitesearch=hackage.haskell.org/package&as_q=happstack">hackage</a> using the <code>cabal</code> command.</p>
            <div class="code">
             <code>
               $ export PATH=~/.cabal/bin:$PATH<br />
               $ cabal update<br />
               $ cabal install happstack
             </code>
            </div>
           <h2 class="label-yellow">Getting the development version of the source code</h2>
            <p>You can get and install the latest development source using <a href="http://darcs.net/">darcs</a>.</p>
            <div class="code">
             <code>
               $ cabal update<br />
               $ darcs get http://patch-tag.com/r/mae/happstack<br />
               $ cd happstack<br />
               $ chmod +x bin/build-install-all.sh<br />
               $ ./bin/build-install-all.sh<br />
             </code>
            </div>
            
            <p>After you have checked out the code, you can get further updates by running:</p>
            <div class="code">
             <code>
               $ darcs pull
             </code>
            </div>

            <p>To submit a patch run:</p>            
            <div class="code">
             <code>
               $ darcs record<br />
               $ darcs send
             </code>
            </div>
            
            <p>Note that <code>darcs send</code> assumes you have a working <code>sendmail</code> installed. Another option is to write the patches to a file and then manually attach the patches to an email message. You should send the patches to <a href="http://groups.google.com/group/HAppS">our mailing list</a>.</p>
            <div class="code">
             <code>
               $ darcs record<br />
               $ darcs send -o descriptive_name.dpatch
             </code>
            </div>
           <h2 class="label-yellow">Browse the source code online</h2>
            <p>You can browse the source code online by <a href="http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty">visiting our project</a> on patch-tag.com.</p>
        </div>

docs :: (XMLGenerator m, EmbedAsChild m (), EmbedAsChild m [HSX.XML m], MonadReader AppConf m) => XMLGenT m (HSX.XML m)
docs =
    appTemplate "Happstack - Documentation" () Docs $ 
      mainContent $
        <div>
         <h1 class="label-green">Documentation</h1>
         <h2 class="label-yellow">Official Documentation & Tutorials</h2>
         <dl>
           <dt>Happstack Lite Tutorial</dt>
           <dd><span class="package-name">happstack-lite</span> is a great starting point for new Happstack developers. Check out <a href="http://happstack.com/docs/happstack-lite/happstack-lite.html">this short tutorial</a>.</dd>
           <dt>Happstack Crash Course</dt> 
           <dd>The <a href="/docs/crashcourse/index.html">Happstack Crash Course</a> is the most complete resource for learning Happstack. New sections are added regularly, so check back often.</dd>
           <dt>Haddock API Reference</dt>
           <dd>The haddock API documentation for Happstack can be found <a href="/docs/6.0.0/index.html">here</a>.</dd>
         </dl>
         <h2 class="label-yellow">Examples</h2>
          <dl>
           <dt>Guestbook Demo</dt>
           <dd>
            <p>The guestbook demo, included with Happstack, is a complete, cabalized web application which demonstrates using MACID database, HSP templating, and HStringTemplate. There is currently no separate tutorial, but the code is heavily commented for instructive purposes.</p>

            <p>You can browse the source code for the guestbook demo <a href="http://patch-tag.com/r/mae/happstack/snapshot/current/content/pretty/happstack/templates/project">here.</a></p>
            <p>To get a local copy you can play with do:</p>
            <div class="code">
             <code>
               $ export PATH=~/.cabal/bin:$PATH<br />
               $ cabal update<br />
               $ cabal install happstack<br />
               $ happstack new project guestbook<br />
               $ cd guestbook
             </code>
            </div>
           </dd>

           <dt><span class="package-name">happstack-imageboard</span></dt>
           <dd><p><a href="http://src.seereason.com/examples/happstack-imageboard/"><span class="package-name">happstack-imageboard</span></a> implements a simple 4chan-like imageboard. It demonstrates acid-state, ixset, digestive-functors, HSX, jmacro, web-routes, cookies, AJAX, uploads, image resizing, and more. It is available via:</p>
               <div class="code"><code>darcs get http://src.seereason.com/examples/happstack-imageboard/</code></div>
           </dd>
          </dl>
         <h2 class="label-yellow">3rd Party Tutorials & Examples</h2>
          <dl>
           <dt>Short tutorial on Happstack.State / MACID</dt>
            <dd><a href="http://www.kuliniewicz.org/blog/archives/2009/04/05/happstackstate-the-basics/">Happstack.State - the basics by Paul Kuliniewicz</a></dd>
           <dt>Tutorialpedia web-routes</dt>
            <dd><a href="http://tutorialpedia.org/tutorials/Happstack+type+safe+URLs.html">Happstack type-safe routing and URLs using web-routes and the Regular library</a></dd>
 
          <dt>Build a pasteboard with Happstack</dt>
            <dd><a href="http://gitit.net/paste.lhs">This tutorial</a> demonstrates building a simple <i>pasteboard</i> application by using Happstack with sqlite and <code>Text.Html</code>.</dd>

         </dl>
       
        </div>

community :: (XMLGenerator m, EmbedAsChild m (), EmbedAsChild m [HSX.XML m], MonadReader AppConf m) => XMLGenT m (HSX.XML m)
community =
    appTemplate "Happstack - Community" () Community $ 
      mainContent $
        <div>
         <h1 class="label-green">Community</h1>
          <p>Happstack is a open community. We encourage you to participate in making Happstack a better project. Right now we are focused on making Happstack more accessible to newcomers. If you think something is confusing, let us know!</p>

          <p>There are many ways to interact with the Happstack community.</p>

         <h3 class="label-yellow">Mailing List</h3>
           <p><a href="http://groups.google.com/group/HAppS">Join our mailing list</a> to ask questions, suggest changes and improvements, or just keep an eye on things.</p>

         <h3 class="label-yellow">stack<b>overflow</b></h3>
          <p>You can also post questions on stack<b>overflow</b> with the <a href="http://stackoverflow.com/tags/happstack">happstack</a> tag.</p>

         <h3 class="label-yellow">IRC</h3>
          <p>Join us on <code>#happs</code> on <code>irc.freenode.net</code>. If someone does not answer your question right away, hang around and someone probably will. You can also browse the irc logs <a href="/irc-logs/">here</a>.</p>

         <h3 class="label-yellow">Bug Reports</h3>
          <p>Found a bug? Got a feature suggestion? In addition to the mailing list and irc channel, you might consider <a href="http://code.google.com/p/happstack/issues/list">submitting a bug report</a>.</p>

         <h3 class="label-yellow">Happstack Wiki</h3>
          <p>We also have a wiki: <a href="http://code.google.com/p/happstack/w/list">Happstack Wiki</a>.</p>

         <h3 class="label-yellow">Follow us on Twitter</h3>
          <p>When the mailing list is quiet, it may sometimes feel like nothing is happening. Get bite sized updates about what is going on with Happstack on a near daily basis by following us on twitter. <a href="http://www.twitter.com/happstack">http://www.twitter.com/happstack</a></p>

         <h3 class="label-yellow">Find us on Facebook</h3>
          <p>If you haven't deactivated your Facebook account you can also follow us on Facebook <a href="http://www.facebook.com/happstack">http://www.facebook.com/happstack</a></p>

        </div>

mainContent :: (XMLGenerator m, EmbedAsChild m c ) => c -> XMLGenT m (HSX.XML m)
mainContent c =
   <div id="mainbox">
     <% sidebar %>
     <div id="content">
      <% c %>
     </div>
   </div>


ircLogs :: (XMLGenerator m, EmbedAsChild m XML, EmbedAsChild m [HSX.XML m], EmbedAsChild m (), MonadIO m, MonadReader AppConf m) => FilePath -> XMLGenT m (HSX.XML m)
ircLogs ircLogDir =
    do logFiles <- liftIO $ (reverse . sort . filter ((\ext -> (ext == ".html") || (ext == ".txt")) . takeExtension)) <$> getDirectoryContents ircLogDir
       appTemplate "Happstack - IRC Logs" () Other $
         mainContent  $
                  <ul>
                   <% mapM (\logFile -> <li><a href=("/irc-logs" </> logFile)><% logFile %></a></li>) logFiles %>
                  </ul>
                

initIrcParts :: (BotMonad m) =>
             Set String  -- ^ set of channels to join
          -> IO [m ()]
initIrcParts chans =
    do (_, channelsPart) <- initChannelsPart chans
       return [ pingPart
              , nickUserPart
              , channelsPart
              , dicePart
              , helloPart
              ]

