-- | Contains all necessary types and constructors for citing sources in Drasil.
module Language.Drasil.Data.Citation (
  -- * Types
  CiteField(..), HP(..), CitationKind(..),
  -- * Class
  HasFields(..),
  -- * 'CiteField' Constructors
  -- ** 'People' -> 'CiteField'
  author, editor,
  -- ** 'String' -> 'CiteField'
  address, bookTitle, howPublished, howPublishedU, institution, journal, note,
  organization, publisher, school, series, title, typeField,
  -- FIXME: these should be checked for bounds
  -- ** 'Int' -> 'CiteField'
  chapter, edition, number, volume, year,
  -- ** ['Int'] -> 'CiteField'
  pages,
  -- ** 'Month' -> 'CiteField'
  month
) where

import Language.Drasil.People (People)
import Language.Drasil.Data.Date (Month(..))
import Control.Lens (Lens')

-- | Fields used in citations.
data CiteField = Address      String
               | Author       People
               | BookTitle    String -- ^ Used for 'InCollection' references only.
               | Chapter      Int
               | Edition      Int
               | Editor       People
               | HowPublished HP     -- ^ Can be published via URL or something else.
               | Institution  String
               | Journal      String
               | Month        Month
               | Note         String
               | Number       Int
               | Organization String
               | Pages        [Int] -- ^ Range of pages (ex1. 1-32; ex2. 7,31,52-55).
               | Publisher    String
               | School       String
               | Series       String
               | Title        String
               | Type         String -- ^ BibTeX "type" field.
               | Volume       Int
               | Year         Int

-- | 'Citation's should have a fields ('CiteField').
class HasFields c where
  -- | Provides a 'Lens' to 'CiteField's.
  getFields :: Lens' c [CiteField]

-- | How something is published. Necessary for URLs to work properly.
data HP = URL String
        | Verb String

-- | External references come in many flavours. Articles, Books, etc.
-- (we are using the types available in Bibtex).
data CitationKind = Article
                  | Book
                  | Booklet
                  | InBook
                  | InCollection
                  | InProceedings
                  | Manual
                  | MThesis
                  | Misc
                  | PhDThesis
                  | Proceedings
                  | TechReport
                  | Unpublished

-- | Smart field constructor for a 'CiteField'.
author, editor :: People -> CiteField
author :: People -> CiteField
author = People -> CiteField
Author
editor :: People -> CiteField
editor = People -> CiteField
Editor

-- | Smart field constructor for a 'CiteField'.
address, bookTitle, institution, journal,
  howPublished, howPublishedU, note, organization, publisher, school, series, title,
  typeField :: String -> CiteField

address :: String -> CiteField
address       = String -> CiteField
Address
bookTitle :: String -> CiteField
bookTitle     = String -> CiteField
BookTitle
howPublished :: String -> CiteField
howPublished  = HP -> CiteField
HowPublished forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> HP
Verb
-- | URL version of 'howPublished'.
howPublishedU :: String -> CiteField
howPublishedU = HP -> CiteField
HowPublished forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> HP
URL
institution :: String -> CiteField
institution   = String -> CiteField
Institution
journal :: String -> CiteField
journal       = String -> CiteField
Journal
note :: String -> CiteField
note          = String -> CiteField
Note
organization :: String -> CiteField
organization  = String -> CiteField
Organization
publisher :: String -> CiteField
publisher     = String -> CiteField
Publisher
school :: String -> CiteField
school        = String -> CiteField
School
series :: String -> CiteField
series        = String -> CiteField
Series
title :: String -> CiteField
title         = String -> CiteField
Title
typeField :: String -> CiteField
typeField     = String -> CiteField
Type

-- | Smart field constructor for a 'CiteField'.
chapter, edition, number, volume, year :: Int -> CiteField

chapter :: Int -> CiteField
chapter = Int -> CiteField
Chapter
edition :: Int -> CiteField
edition = Int -> CiteField
Edition
number :: Int -> CiteField
number = Int -> CiteField
Number
volume :: Int -> CiteField
volume = Int -> CiteField
Volume
year :: Int -> CiteField
year = Int -> CiteField
Year

-- | Smart field constructor for a 'CiteField'.
pages :: [Int] -> CiteField
pages :: [Int] -> CiteField
pages = [Int] -> CiteField
Pages

-- | Smart field constructor for a 'CiteField'.
month :: Month -> CiteField
month :: Month -> CiteField
month = Month -> CiteField
Month