{-# OPTIONS_GHC -F -pgmFtrhsx #-}

import Happstack.Server
import HSP
import Happstack.Server.HSP.HTML
import Data.Monoid

{- We define a very simple data type here to use as our
   instance for FromData -}
data Foo = Foo {bar :: Int,
                baz :: Int}
         deriving Show

{- Defining an instance of FromData is fundamentally simple.  Primarily, you should use the helper function look
to grab the string associated with the named parameter you provide.  From there, we use read to parse the string into an
int and return the final Foo.  This isn't the safest construction, because the read could fail, but you can easily provide
yourself with more safety by using the MonadPlus instance of RqData and just calling mzero when an error occurs.-}
instance FromData Foo where
    fromData = do
      x <- read `fmap` look "bar"
      y <- read `fmap` look "baz"
      return $ Foo x y

main :: IO ()
main = simpleHTTP nullConf{port=8080} $ (dir "getHandler" handler) `mappend` (dir "postHandler" handler) `mappend` home

{- Please note that we actually use the same handler for both GET & POST requests.  
   This is an advantage of using FromData.
-}
handler :: ServerPartT IO Response
handler = do
  mfoo <- getData
  case mfoo of
    Nothing -> webHSP $ didn'twork
    Just foo -> webHSP $ displayFoo foo

displayFoo :: Foo -> HSP XML
displayFoo f = <html>
                <head>
                 <title>This is a Foo</title>
                </head>
                <body>
                 <p>Here, look at a Foo:  <%show f%></p>
                 <p><a href="/">home</a></p>
                </body>
               </html>

didn'twork = <html>
              <head>
               <title>Something is wrong!</title>
              </head>
              <body>
               <p>Something has gone horribly wrong
                 <a href="/">go home</a></p>
              </body>
             </html>

home :: ServerPartT IO Response
home = webHSP $ <html>
                 <head>
                  <title>Get and Post examples</title>
                 </head>
                 <body>
                  <form action="getHandler" method="GET">
                    <p>
                     <label for="bar">Bar:  </label>
                     <input type="text" name="bar" /><br/>
                     <label for="baz">Baz:  </label>
                     <input type="text" name="baz" /><br/>
                     <input type="submit" value="Send" />
                    </p>
                  </form>
                  <form action="postHandler" method="POST">
                    <p>
                     <label for="bar">Bar:  </label>
                     <input type="text" name="bar" /><br/>
                     <label for="baz">Baz:  </label>
                     <input type="text" name="baz" /><br/>
                     <input type="submit" value="Send" />
                    </p>
                  </form>
                 </body>
                </html>