content: module Reddit.Types.SubredditSettings
    ( SubredditSettings(..)
    , ContentOptions(..)
    , SpamFilterStrength(..)
    , SubredditType(..)
    , WikiEditMode(..) ) where
  
  import Reddit.Parser
  import Reddit.Utilities
  
  import Control.Applicative
  import Data.Aeson
  import Data.Default.Class
  import Data.Monoid hiding (Any(..))
  import Data.Text (Text)
  import Network.API.Builder.Query
  import Prelude
  
  data SubredditSettings = SubredditSettings { sidebarText :: Text
                                             , descriptionText :: Text
                                             , title :: Text
                                             , linkType :: ContentOptions
                                             , hideScoreMins :: Integer
                                             , submitLinkLabel :: Maybe Text
                                             , submitTextLabel :: Maybe Text
                                             , domainCSS :: Maybe Bool
                                             , domainSidebar :: Maybe Bool
                                             , showMedia :: Bool
                                             , over18 :: Bool
                                             , language :: Text
                                             , wikiEditKarma :: Integer
                                             , wikiEditAge :: Integer
                                             , wikiEditMode :: WikiEditMode
                                             , spamComments :: SpamFilterStrength
                                             , spamSelfposts :: SpamFilterStrength
                                             , spamLinks :: SpamFilterStrength
                                             , publicTrafficStats :: Bool
                                             , subredditType :: SubredditType }
    deriving (Show, Read, Eq)
  
  instance FromJSON SubredditSettings where
    parseJSON (Object o) = do
      o `ensureKind` subredditSettingsPrefix
      d <- o .: "data"
      SubredditSettings <$> (unescape <$> d .: "description")
                        <*> d .: "public_description"
                        <*> d .: "title"
                        <*> d .: "content_options"
                        <*> d .: "comment_score_hide_mins"
                        <*> d .: "submit_link_label"
                        <*> d .: "submit_text_label"
                        <*> d .:? "domain_css"
                        <*> d .:? "domain_sidebar"
                        <*> d .: "show_media"
                        <*> d .: "over_18"
                        <*> d .: "language"
                        <*> d .: "wiki_edit_karma"
                        <*> d .: "wiki_edit_age"
                        <*> d .: "wikimode"
                        <*> d .: "spam_comments"
                        <*> d .: "spam_selfposts"
                        <*> d .: "spam_links"
                        <*> d .: "public_traffic"
                        <*> d .: "subreddit_type"
    parseJSON _ = mempty
  
  instance ToJSON SubredditSettings where
    toJSON settings = object
      [ "description" .= sidebarText settings
      , "public_description" .= descriptionText settings
      , "title" .= title settings
      , "content_options" .= linkType settings
      , "comment_score_hide_mins" .= hideScoreMins settings
      , "submit_link_label" .= submitLinkLabel settings
      , "submit_text_label" .= submitTextLabel settings
      , "domain_css" .= domainCSS settings
      , "domain_sidebar" .= domainSidebar settings
      , "show_media" .= showMedia settings
      , "over_18" .= over18 settings
      , "language" .= language settings
      , "wiki_edit_karma" .= wikiEditKarma settings
      , "wiki_edit_age" .= wikiEditAge settings
      , "wikimode" .= wikiEditMode settings
      , "spam_comments" .= spamComments settings
      , "spam_selfposts" .= spamSelfposts settings
      , "spam_links" .= spamLinks settings
      , "public_traffic" .= publicTrafficStats settings
      , "subreddit_type" .= subredditType settings ]
  
  data SubredditType = Public
                     | Private
                     | Restricted
                     | GoldRestricted
                     | Archived
    deriving (Show, Read, Eq)
  
  subredditTypeText :: SubredditType -> Text
  subredditTypeText Public = "public"
  subredditTypeText Private = "private"
  subredditTypeText Restricted = "restricted"
  subredditTypeText GoldRestricted = "gold_restricted"
  subredditTypeText Archived = "archived"
  
  instance FromJSON SubredditType where
    parseJSON (String s) =
      case s of
        "public" -> return Public
        "private" -> return Private
        "restricted" -> return Restricted
        "gold_restricted" -> return GoldRestricted
        "archived" -> return Archived
        _ -> mempty
    parseJSON _ = mempty
  
  instance ToJSON SubredditType where
    toJSON = String . subredditTypeText
  
  instance Default SubredditType where
    def = Public
  
  instance ToQuery SubredditType where
    toQuery k v = [(k, subredditTypeText v)]
  
  data ContentOptions = Any
                      | Link
                      | Self
    deriving (Show, Read, Eq)
  
  contentOptionsText :: ContentOptions -> Text
  contentOptionsText Any = "any"
  contentOptionsText Link = "link"
  contentOptionsText Self = "self"
  
  instance FromJSON ContentOptions where
    parseJSON (String s) =
      case s of
        "any" -> return Any
        "link" -> return Link
        "self" -> return Self
        _ -> mempty
    parseJSON _ = mempty
  
  instance ToJSON ContentOptions where
    toJSON = String . contentOptionsText
  
  instance ToQuery ContentOptions where
    toQuery k v = [(k, contentOptionsText v)]
  
  instance Default ContentOptions where
    def = Any
  
  data SpamFilterStrength = FilterLow
                          | FilterHigh
                          | FilterAll
    deriving (Show, Read, Eq)
  
  instance FromJSON SpamFilterStrength where
    parseJSON (String s) =
      case s of
        "low" -> return FilterLow
        "high" -> return FilterHigh
        "all" -> return FilterAll
        _ -> mempty
    parseJSON _ = mempty
  
  spamFilterStrengthText :: SpamFilterStrength -> Text
  spamFilterStrengthText FilterLow = "low"
  spamFilterStrengthText FilterHigh = "high"
  spamFilterStrengthText FilterAll = "all"
  
  instance ToJSON SpamFilterStrength where
    toJSON = String . spamFilterStrengthText
  
  instance ToQuery SpamFilterStrength where
    toQuery k v = [(k, spamFilterStrengthText v)]
  
  data WikiEditMode = Anyone
                    | ApprovedOnly
                    | ModOnly
    deriving (Show, Read, Eq)
  
  instance FromJSON WikiEditMode where
    parseJSON (String s) =
      case s of
        "disabled" -> return ModOnly
        "modonly" -> return ApprovedOnly
        "anyone" -> return Anyone
        _ -> mempty
    parseJSON _ = mempty
  
  wikiEditModeText :: WikiEditMode -> Text
  wikiEditModeText ModOnly = "disabled"
  wikiEditModeText Anyone = "anyone"
  wikiEditModeText ApprovedOnly = "modonly"
  
  instance ToJSON WikiEditMode where
    toJSON = String . wikiEditModeText
  
  instance ToQuery WikiEditMode where
    toQuery k v = [(k, wikiEditModeText v)]
  
  instance Default WikiEditMode where
    def = Anyone
  
  subredditSettingsPrefix :: Text
  subredditSettingsPrefix = "subreddit_settings"
  