{-
Copyright (C) 2005 John Goerzen <jgoerzen@complete.org>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-}

{- |
   Module     : Network.Email.Mailbox
   Copyright  : Copyright (C) 2005 John Goerzen
   License    : GNU GPL, version 2 or above

   Maintainer : John Goerzen <jgoerzen@complete.org> 
   Stability  : provisional
   Portability: portable

General support for e-mail mailboxes

Written by John Goerzen, jgoerzen\@complete.org
-}

module Network.Email.Mailbox(Flag(..), Flags, Message,
                              MailboxReader(..),
                              MailboxWriter(..))
where

{- | The flags which may be assigned to a message. -}
data Flag = 
           SEEN
           | ANSWERED
           | FLAGGED
           | DELETED
           | DRAFT
           | FORWARDED
           | OTHERFLAG String
           deriving (Eq, Show)
           
{- | Convenience shortcut -}
type Flags = [Flag]

{- | A Message is represented as a simple String. -}
type Message = String

{- | Main class for readable mailboxes. 

The mailbox object /a/ represents zero or more 'Message's.  Each message
has a unique identifier /b/ in a format specific to each given mailbox.
This identifier may or may not be persistent.

Functions which return a list are encouraged -- but not guaranteed -- to
do so lazily.

Implementing classes must provide, at minimum, 'getAll'.
-}
class (Show a, Show b, Eq b) => MailboxReader a b where
    {- | Returns a list of all unique identifiers. -}
    listIDs :: a -> IO [b]
    {- | Returns a list of all unique identifiers as well as all flags. -}
    listMessageFlags :: a -> IO [(b, Flags)]
    {- | Returns a list of all messages, including their content,
       flags, and unique identifiers. -}
    getAll :: a -> IO [(b, Flags, Message)]
    {- | Returns information about specific messages. -}
    getMessages :: a -> [b] -> IO [(b, Flags, Message)]

    listIDs mb = listMessageFlags mb >>= return . map fst
    listMessageFlags mb = getAll mb >>= return . 
                           map (\(i, f, _) -> (i, f))
    getMessages mb list =
        do messages <- getAll mb
           return $ filter (\(id, f, m) -> id `elem` list) messages
    
class (MailboxReader a b) => MailboxWriter a b where
    appendMessages :: a -> [(Flags, Message)] -> IO [b]
    deleteMessages :: a -> [b] -> IO ()
    addFlags :: a -> [b] -> Flags -> IO ()
    removeFlags :: a -> [b] -> Flags -> IO ()
    setFlags :: a -> [b] -> Flags -> IO ()