module Chemistry.Formula ( Formula(..)
                          , parseFormula
                          ) where

import Text.ParserCombinators.Parsec
import Chemistry.Element


data Formula = Formula [(Element, Int)] deriving (Eq, Show)

-- | Parse formula 
--
-- > parseFormula "C2H4" `shouldBe` Formula [("C", 2), ("H", 4)]  

parseFormula :: String -> Formula
parseFormula xs = case parse formula "" xs of
    Left _ -> Formula []
    Right val -> Formula val


-- Parse whole formula
formula :: Parser [(Element, Int)]
formula = many elementSymbol
    
-- Parse element
-- Element is max 3 letter long
-- Starts with upper case
-- has 0, 1 or 2 lower letters
elementSymbol :: Parser (Element, Int)
elementSymbol = do
    l1 <- upper
    l2 <- many lower
    let e = elementBySymbol (l1:l2) 
    ds <- many digit
    let n = if null ds then 1 else read ds :: Int
    return (e, n)