module Data.HodaTime.Pattern.LocalTime
(
  -- * Standard Patterns
   pt
  ,pT
  -- * Custom Patterns
  --
  -- | Used to create specialized patterns
  ,pHH
  ,phh
  ,pmm
  ,pss
  ,pp
  ,ppp
  ,hour'
  ,minute'
  ,second'
)
where

import Data.HodaTime.Pattern.Internal
import Data.HodaTime.Pattern.ParseTypes (TimeInfo)
import qualified Data.HodaTime.Pattern.ParseTypes as PT(hour, minute, second)
import Data.HodaTime.LocalTime.Internal (HasLocalTime)
import qualified Data.HodaTime.LocalTime.Internal as LT(hour, minute, second)
import Control.Applicative ((<|>))
import Text.Parsec (oneOf, digit)
import qualified Text.Parsec as P (char)

-- x = maybe (error "duh") id $ localTime 1 2 3 0
-- parse pT "01:01:01" :: IO LocalTime
-- format pT x
-- format pt x

-- | The double digit hour of day in the 12-hour clock; a value 1-12. When parsing, if no am/pm designator is specified, the parsed value is in the morning.
phh :: HasLocalTime lt => Pattern (lt -> lt) (lt -> String) String
phh :: forall lt.
HasLocalTime lt =>
Pattern (lt -> lt) (lt -> String) String
phh = Lens lt lt Hour Hour
-> Parser Hour String
-> ((lt -> Hour) -> Format String (lt -> String))
-> String
-> Pattern (lt -> lt) (lt -> String) String
forall s a.
Lens s s a a
-> Parser a String
-> ((s -> a) -> Format String (s -> String))
-> String
-> Pattern (s -> s) (s -> String) String
pat_lens (Hour -> f Hour) -> lt -> f lt
forall lt (f :: * -> *).
(HasLocalTime lt, Functor f) =>
(Hour -> f Hour) -> lt -> f lt
Lens lt lt Hour Hour
LT.hour (Parser Hour String
forall {u}. ParsecT String u Identity Hour
p_a Parser Hour String -> Parser Hour String -> Parser Hour String
forall a.
ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Hour String
forall {u}. ParsecT String u Identity Hour
p_b) (lt -> Hour) -> Format String (lt -> String)
forall b a r. Show b => (a -> b) -> Format r (a -> r)
f_shown_two String
"hour: 01-12"
  where
    p_a :: ParsecT String u Identity Hour
p_a = Char -> Char -> Hour
forall n. (Num n, Read n) => Char -> Char -> n
digitsToInt (Char -> Char -> Hour)
-> ParsecT String u Identity Char
-> ParsecT String u Identity (Char -> Hour)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'0' ParsecT String u Identity (Char -> Hour)
-> ParsecT String u Identity Char -> ParsecT String u Identity Hour
forall a b.
ParsecT String u Identity (a -> b)
-> ParsecT String u Identity a -> ParsecT String u Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf [Char
'1'..Char
'9']
    p_b :: ParsecT String u Identity Hour
p_b = Char -> Char -> Hour
forall n. (Num n, Read n) => Char -> Char -> n
digitsToInt (Char -> Char -> Hour)
-> ParsecT String u Identity Char
-> ParsecT String u Identity (Char -> Hour)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'1' ParsecT String u Identity (Char -> Hour)
-> ParsecT String u Identity Char -> ParsecT String u Identity Hour
forall a b.
ParsecT String u Identity (a -> b)
-> ParsecT String u Identity a -> ParsecT String u Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf [Char
'0'..Char
'2']

-- | The double digit hour of day in the 24-hour clock; a value 00-23.
pHH :: HasLocalTime lt => Pattern (lt -> lt) (lt -> String) String
pHH :: forall lt.
HasLocalTime lt =>
Pattern (lt -> lt) (lt -> String) String
pHH = Lens lt lt Hour Hour
-> Parser Hour String
-> ((lt -> Hour) -> Format String (lt -> String))
-> String
-> Pattern (lt -> lt) (lt -> String) String
forall s a.
Lens s s a a
-> Parser a String
-> ((s -> a) -> Format String (s -> String))
-> String
-> Pattern (s -> s) (s -> String) String
pat_lens (Hour -> f Hour) -> lt -> f lt
forall lt (f :: * -> *).
(HasLocalTime lt, Functor f) =>
(Hour -> f Hour) -> lt -> f lt
Lens lt lt Hour Hour
LT.hour (Parser Hour String
forall {u}. ParsecT String u Identity Hour
p_a Parser Hour String -> Parser Hour String -> Parser Hour String
forall a.
ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Hour String
forall {u}. ParsecT String u Identity Hour
p_b) (lt -> Hour) -> Format String (lt -> String)
forall b a r. Show b => (a -> b) -> Format r (a -> r)
f_shown_two String
"hour: 00-23"
  where
    p_a :: ParsecT String u Identity Hour
p_a = Char -> Char -> Hour
forall n. (Num n, Read n) => Char -> Char -> n
digitsToInt (Char -> Char -> Hour)
-> ParsecT String u Identity Char
-> ParsecT String u Identity (Char -> Hour)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf [Char
'0', Char
'1'] ParsecT String u Identity (Char -> Hour)
-> ParsecT String u Identity Char -> ParsecT String u Identity Hour
forall a b.
ParsecT String u Identity (a -> b)
-> ParsecT String u Identity a -> ParsecT String u Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit 
    p_b :: ParsecT String u Identity Hour
p_b = Char -> Char -> Hour
forall n. (Num n, Read n) => Char -> Char -> n
digitsToInt (Char -> Char -> Hour)
-> ParsecT String u Identity Char
-> ParsecT String u Identity (Char -> Hour)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'2' ParsecT String u Identity (Char -> Hour)
-> ParsecT String u Identity Char -> ParsecT String u Identity Hour
forall a b.
ParsecT String u Identity (a -> b)
-> ParsecT String u Identity a -> ParsecT String u Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf [Char
'0'..Char
'3']

hour' :: HasLocalTime lt => Pattern (TimeInfo -> TimeInfo) (lt -> String) String
hour' :: forall lt.
HasLocalTime lt =>
Pattern (TimeInfo -> TimeInfo) (lt -> String) String
hour' = Lens TimeInfo TimeInfo Hour Hour
-> Lens lt lt Hour Hour
-> Parser Hour String
-> ((lt -> Hour) -> Format String (lt -> String))
-> String
-> Pattern (TimeInfo -> TimeInfo) (lt -> String) String
forall s a s' a'.
Lens s s a a
-> Lens s' s' a' a'
-> Parser a String
-> ((s' -> a') -> Format String (s' -> String))
-> String
-> Pattern (s -> s) (s' -> String) String
pat_lens' (Hour -> f Hour) -> TimeInfo -> f TimeInfo
Lens TimeInfo TimeInfo Hour Hour
PT.hour (Hour -> f Hour) -> lt -> f lt
forall lt (f :: * -> *).
(HasLocalTime lt, Functor f) =>
(Hour -> f Hour) -> lt -> f lt
Lens lt lt Hour Hour
LT.hour (Parser Hour String
forall {u}. ParsecT String u Identity Hour
p_a Parser Hour String -> Parser Hour String -> Parser Hour String
forall a.
ParsecT String () Identity a
-> ParsecT String () Identity a -> ParsecT String () Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Hour String
forall {u}. ParsecT String u Identity Hour
p_b) (lt -> Hour) -> Format String (lt -> String)
forall b a r. Show b => (a -> b) -> Format r (a -> r)
f_shown_two String
"hour: 00-23"
  where
    p_a :: ParsecT String u Identity Hour
p_a = Char -> Char -> Hour
forall n. (Num n, Read n) => Char -> Char -> n
digitsToInt (Char -> Char -> Hour)
-> ParsecT String u Identity Char
-> ParsecT String u Identity (Char -> Hour)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf [Char
'0', Char
'1'] ParsecT String u Identity (Char -> Hour)
-> ParsecT String u Identity Char -> ParsecT String u Identity Hour
forall a b.
ParsecT String u Identity (a -> b)
-> ParsecT String u Identity a -> ParsecT String u Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT String u Identity Char
forall s (m :: * -> *) u. Stream s m Char => ParsecT s u m Char
digit 
    p_b :: ParsecT String u Identity Hour
p_b = Char -> Char -> Hour
forall n. (Num n, Read n) => Char -> Char -> n
digitsToInt (Char -> Char -> Hour)
-> ParsecT String u Identity Char
-> ParsecT String u Identity (Char -> Hour)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Char -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
Char -> ParsecT s u m Char
P.char Char
'2' ParsecT String u Identity (Char -> Hour)
-> ParsecT String u Identity Char -> ParsecT String u Identity Hour
forall a b.
ParsecT String u Identity (a -> b)
-> ParsecT String u Identity a -> ParsecT String u Identity b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> ParsecT String u Identity Char
forall s (m :: * -> *) u.
Stream s m Char =>
String -> ParsecT s u m Char
oneOf [Char
'0'..Char
'3']

-- | The double digit minute of day in the 24-hour clock; a value 00-59.
pmm :: HasLocalTime lt => Pattern (lt -> lt) (lt -> String) String
pmm :: forall lt.
HasLocalTime lt =>
Pattern (lt -> lt) (lt -> String) String
pmm = Lens lt lt Hour Hour
-> Parser Hour String
-> ((lt -> Hour) -> Format String (lt -> String))
-> String
-> Pattern (lt -> lt) (lt -> String) String
forall s a.
Lens s s a a
-> Parser a String
-> ((s -> a) -> Format String (s -> String))
-> String
-> Pattern (s -> s) (s -> String) String
pat_lens (Hour -> f Hour) -> lt -> f lt
forall lt (f :: * -> *).
(HasLocalTime lt, Functor f) =>
(Hour -> f Hour) -> lt -> f lt
Lens lt lt Hour Hour
LT.minute Parser Hour String
forall n. (Num n, Read n) => Parser n String
p_sixty (lt -> Hour) -> Format String (lt -> String)
forall b a r. Show b => (a -> b) -> Format r (a -> r)
f_shown_two String
"minute: 00-59"

minute' :: HasLocalTime lt => Pattern (TimeInfo -> TimeInfo) (lt -> String) String
minute' :: forall lt.
HasLocalTime lt =>
Pattern (TimeInfo -> TimeInfo) (lt -> String) String
minute' = Lens TimeInfo TimeInfo Hour Hour
-> Lens lt lt Hour Hour
-> Parser Hour String
-> ((lt -> Hour) -> Format String (lt -> String))
-> String
-> Pattern (TimeInfo -> TimeInfo) (lt -> String) String
forall s a s' a'.
Lens s s a a
-> Lens s' s' a' a'
-> Parser a String
-> ((s' -> a') -> Format String (s' -> String))
-> String
-> Pattern (s -> s) (s' -> String) String
pat_lens' (Hour -> f Hour) -> TimeInfo -> f TimeInfo
Lens TimeInfo TimeInfo Hour Hour
PT.minute (Hour -> f Hour) -> lt -> f lt
forall lt (f :: * -> *).
(HasLocalTime lt, Functor f) =>
(Hour -> f Hour) -> lt -> f lt
Lens lt lt Hour Hour
LT.minute Parser Hour String
forall n. (Num n, Read n) => Parser n String
p_sixty (lt -> Hour) -> Format String (lt -> String)
forall b a r. Show b => (a -> b) -> Format r (a -> r)
f_shown_two String
"minute: 00-59"

-- | The double digit second of day in the 24-hour clock; a value 00-59.
pss :: HasLocalTime lt => Pattern (lt -> lt) (lt -> String) String
pss :: forall lt.
HasLocalTime lt =>
Pattern (lt -> lt) (lt -> String) String
pss = Lens lt lt Hour Hour
-> Parser Hour String
-> ((lt -> Hour) -> Format String (lt -> String))
-> String
-> Pattern (lt -> lt) (lt -> String) String
forall s a.
Lens s s a a
-> Parser a String
-> ((s -> a) -> Format String (s -> String))
-> String
-> Pattern (s -> s) (s -> String) String
pat_lens (Hour -> f Hour) -> lt -> f lt
forall lt (f :: * -> *).
(HasLocalTime lt, Functor f) =>
(Hour -> f Hour) -> lt -> f lt
Lens lt lt Hour Hour
LT.second Parser Hour String
forall n. (Num n, Read n) => Parser n String
p_sixty (lt -> Hour) -> Format String (lt -> String)
forall b a r. Show b => (a -> b) -> Format r (a -> r)
f_shown_two String
"second: 00-59"

second' :: HasLocalTime lt => Pattern (TimeInfo -> TimeInfo) (lt -> String) String
second' :: forall lt.
HasLocalTime lt =>
Pattern (TimeInfo -> TimeInfo) (lt -> String) String
second' = Lens TimeInfo TimeInfo Hour Hour
-> Lens lt lt Hour Hour
-> Parser Hour String
-> ((lt -> Hour) -> Format String (lt -> String))
-> String
-> Pattern (TimeInfo -> TimeInfo) (lt -> String) String
forall s a s' a'.
Lens s s a a
-> Lens s' s' a' a'
-> Parser a String
-> ((s' -> a') -> Format String (s' -> String))
-> String
-> Pattern (s -> s) (s' -> String) String
pat_lens' (Hour -> f Hour) -> TimeInfo -> f TimeInfo
Lens TimeInfo TimeInfo Hour Hour
PT.second (Hour -> f Hour) -> lt -> f lt
forall lt (f :: * -> *).
(HasLocalTime lt, Functor f) =>
(Hour -> f Hour) -> lt -> f lt
Lens lt lt Hour Hour
LT.second Parser Hour String
forall n. (Num n, Read n) => Parser n String
p_sixty (lt -> Hour) -> Format String (lt -> String)
forall b a r. Show b => (a -> b) -> Format r (a -> r)
f_shown_two String
"second: 00-59"

-- | 12 hour clock time period designation short form; either A or P
pp ::  HasLocalTime lt => Pattern (lt -> lt) (lt -> String) String
pp :: forall lt.
HasLocalTime lt =>
Pattern (lt -> lt) (lt -> String) String
pp = String -> Pattern (lt -> lt) (lt -> String) String
forall a. HasCallStack => String -> a
error String
"to be implemented"  -- TODO: use the AM/PM lense

-- | 12 hour clock time period designation full form; either AM or PM
ppp ::  HasLocalTime lt => Pattern (lt -> lt) (lt -> String) String
ppp :: forall lt.
HasLocalTime lt =>
Pattern (lt -> lt) (lt -> String) String
ppp = String -> Pattern (lt -> lt) (lt -> String) String
forall a. HasCallStack => String -> a
error String
"to be implemented"  -- TODO: use the AM/PM lense

-- | Short format pattern. Currently defined as "HH:mm" but should eventually follow the locale
pt :: HasLocalTime lt => Pattern (lt -> lt) (lt -> String) String
pt :: forall lt.
HasLocalTime lt =>
Pattern (lt -> lt) (lt -> String) String
pt = Pattern (lt -> lt) (lt -> String) String
forall lt.
HasLocalTime lt =>
Pattern (lt -> lt) (lt -> String) String
pHH Pattern (lt -> lt) (lt -> String) String
-> Pattern Char String String
-> Pattern (lt -> lt) (lt -> String) String
forall a b r c. Pattern a b r -> Pattern c r r -> Pattern a b r
<% Char -> Pattern Char String String
char Char
':' Pattern (lt -> lt) (lt -> String) String
-> Pattern (lt -> lt) (lt -> String) String
-> Pattern (lt -> lt) (lt -> String) String
forall a. Semigroup a => a -> a -> a
<> Pattern (lt -> lt) (lt -> String) String
forall lt.
HasLocalTime lt =>
Pattern (lt -> lt) (lt -> String) String
pmm

-- | Long format pattern. Currently defined as "HH:mm:ss" but should eventually follow locale
pT ::  HasLocalTime lt => Pattern (lt -> lt) (lt -> String) String
pT :: forall lt.
HasLocalTime lt =>
Pattern (lt -> lt) (lt -> String) String
pT = Pattern (lt -> lt) (lt -> String) String
forall lt.
HasLocalTime lt =>
Pattern (lt -> lt) (lt -> String) String
pHH Pattern (lt -> lt) (lt -> String) String
-> Pattern Char String String
-> Pattern (lt -> lt) (lt -> String) String
forall a b r c. Pattern a b r -> Pattern c r r -> Pattern a b r
<% Char -> Pattern Char String String
char Char
':' Pattern (lt -> lt) (lt -> String) String
-> Pattern (lt -> lt) (lt -> String) String
-> Pattern (lt -> lt) (lt -> String) String
forall a. Semigroup a => a -> a -> a
<> Pattern (lt -> lt) (lt -> String) String
forall lt.
HasLocalTime lt =>
Pattern (lt -> lt) (lt -> String) String
pmm Pattern (lt -> lt) (lt -> String) String
-> Pattern Char String String
-> Pattern (lt -> lt) (lt -> String) String
forall a b r c. Pattern a b r -> Pattern c r r -> Pattern a b r
<% Char -> Pattern Char String String
char Char
':' Pattern (lt -> lt) (lt -> String) String
-> Pattern (lt -> lt) (lt -> String) String
-> Pattern (lt -> lt) (lt -> String) String
forall a. Semigroup a => a -> a -> a
<> Pattern (lt -> lt) (lt -> String) String
forall lt.
HasLocalTime lt =>
Pattern (lt -> lt) (lt -> String) String
pss