module WikimediaParser where

import Text.ParserCombinators.Parsec
import Data.List (intercalate)

data WikiMarkup = Text String | Link {text::String, target::String} deriving (Eq)

instance Show WikiMarkup where
  show (Text t) = t
  show (Link t _) = t

data Page = Page [WikiMarkup] deriving (Eq)

instance Show Page where
  show (Page xs) = foldl (\x y -> x ++ (show y)) "" xs

generalParseLink p = between (string "[[") (string "]]") p

isNot c = satisfy (/= c)

betweenMatching :: Char -> GenParser Char st [Char]
betweenMatching c = do open <- many1 $ char c 
                       content <- (many $ isNot c)
                       count (length open) (char c)
                       return content

parseLink :: Parser WikiMarkup
parseLink = generalParseLink linkContent
            where linkContent = do target <- optionMaybe (try $ manyTill anyToken (char '|'))
                                   text <- many1 (noneOf "[]") 
                                   return $ Link text (maybe text id target)

parseNoWiki :: Parser WikiMarkup
parseNoWiki = between (string "<nowiki>") (string "</nowiki>") parseText

parseCategory :: Parser WikiMarkup
parseCategory = generalParseLink linkContent
                where linkContent = do option "" (string ":")
                                       string "Catégorie"
                                       many (noneOf "]")
                                       return $ Text ""

eol = char '\n' 
notEol = noneOf "\r\n"

parseUnorderedListItem = do char '*'
                            many notEol
                            eol

parseUnorderedList :: Parser WikiMarkup
parseUnorderedList = do many1 parseUnorderedListItem
                        return $ Text "" 

parseOrderedListItem = do char '#'
                          many notEol 
                          eol

parseOrderedList :: Parser WikiMarkup
parseOrderedList = do many1 parseUnorderedListItem
                      return $ Text ""

parseLinkNameSpace :: Parser WikiMarkup
parseLinkNameSpace = generalParseLink linkContent
                     where linkContent = do manyTill anyToken (char ':')
                                            text <- many (noneOf "[]")
                                            return $ Text text

parseLinkOtherLanguage :: Parser WikiMarkup
parseLinkOtherLanguage = generalParseLink linkContent
                         where linkContent = do anyToken
                                                anyToken
                                                option "" (string "mple")
                                                char ':'
                                                many (noneOf "[]")
                                                return $ Text "" 

parseUnnamedLink :: Parser WikiMarkup
parseUnnamedLink = do between (char '[') (char ']') (many $ noneOf "]")
                      return $ Text ""

parseHTMLComment :: Parser WikiMarkup
parseHTMLComment = do string "<!--"
                      manyTill (string "-->") anyToken
                      return $ Text ""

-- parseHTML = do char '<'
--                tagName <- many $ noneOf " >"
--                options <- option "" $ manyTill anyToken (char '>')
--                content <- nest
--                string "</"
--                endTag <- string tagName
--                string ">"
--                return $ intercalate "," $ [tagName, options, content, endTag] 
--             where nest = do text <- manyTill anyToken (char '<')
--                             case text of
--                               "" -> do return ""
--                               _ -> do
--                                 html <- option "" parseHTML
--                                 case html of
--                                   "" -> return text
--                                   _ -> do
--                                     next <- nest
--                                     case next of
--                                       "" -> return $ text ++ html
--                                       _ -> return $ text ++ html ++ next

parseHeading :: Parser WikiMarkup
parseHeading = do try $ betweenMatching '=' 
                  return $ Text ""

parseBrackets :: Parser WikiMarkup
parseBrackets = do between (string "{{") (string "}}") (many (noneOf "}"))
                   return $ Text ""

symbols :: String
symbols = "[{=*<"

symbol :: Parser Char
symbol = oneOf symbols

symbolW :: Parser WikiMarkup
symbolW = symbol >>= (return . Text . (\a->[a]))

notSymbol = noneOf symbols

parseSymbols = try parseCategory <|>
               try parseLink <|>
               try parseUnnamedLink <|>
               try parseBrackets <|>
               try parseHeading <|>
               try parseUnorderedList <|>
               try parseOrderedList <|>
               try parseHTMLComment <|>
               symbolW

parseText :: Parser WikiMarkup
parseText = do text <- many1 notSymbol
               return $ Text text

parseLine :: Parser WikiMarkup
parseLine = parseSymbols <|>
            parseText

parseArticle :: Parser [WikiMarkup]
parseArticle = do vals <- many parseLine
                  eof
                  return vals

concatText :: [WikiMarkup] -> [WikiMarkup]
concatText (Text x: Text y:xs) = Text (x ++ y) : concatText xs
concatText [] = []
concatText (x:xs) = x : concatText xs