module Data.HodaTime.Locale.Internal
(
  Locale(..)
 ,enUS
 ,deDE
 ,jaJP
 ,windowsPictureToStrftime
)
where

-- | The culture-specific names used when formatting and parsing dates and times, as read from the operating system's
--   locale database (see "Data.HodaTime.Locale").
--
--   The month and weekday name lists describe the /Gregorian/ calendar, which is all the operating system's @LC_TIME@
--   category knows about.  The lists are ordered to line up directly with the calendar enumerations: 'monthNames' is
--   January-first (indexed by @fromEnum@ of the month) and 'dayNames' is Sunday-first (indexed by @fromEnum@ of the
--   'Data.HodaTime.CalendarDateTime.Internal.DayOfWeek', which also starts at Sunday).
--
--   The @raw*Format@ fields hold the operating system's own layout strings as POSIX @strftime@ strings, consumed by
--   @localeDatePattern@ and friends in "Data.HodaTime.Pattern.Locale".  On POSIX they come straight from @D_FMT@ \/
--   @T_FMT@ \/ @D_T_FMT@; on Windows they are translated from the Windows /picture/ strings (e.g. @dd.MM.yyyy@) by
--   'windowsPictureToStrftime'.
data Locale = Locale
  { Locale -> String
localeId          :: String     -- ^ the identifier this locale was loaded from (e.g. @\"de_DE.UTF-8\"@)
  , Locale -> [String]
monthNames        :: [String]   -- ^ full month names, January-first (12 entries for the Gregorian calendar)
  , Locale -> [String]
monthNamesShort   :: [String]   -- ^ abbreviated month names, January-first
  , Locale -> [String]
dayNames          :: [String]   -- ^ full weekday names, Sunday-first (7 entries)
  , Locale -> [String]
dayNamesShort     :: [String]   -- ^ abbreviated weekday names, Sunday-first
  , Locale -> String
amName            :: String     -- ^ the AM designator
  , Locale -> String
pmName            :: String     -- ^ the PM designator
  , Locale -> String
rawDateFormat     :: String     -- ^ the date layout as a POSIX @strftime@ string (from @D_FMT@, or translated on Windows)
  , Locale -> String
rawTimeFormat     :: String     -- ^ the time layout as a POSIX @strftime@ string (from @T_FMT@, or translated on Windows)
  , Locale -> String
rawDateTimeFormat :: String     -- ^ the combined layout as a POSIX @strftime@ string (from @D_T_FMT@, or translated on Windows)
  }
  deriving (Locale -> Locale -> Bool
(Locale -> Locale -> Bool)
-> (Locale -> Locale -> Bool) -> Eq Locale
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Locale -> Locale -> Bool
== :: Locale -> Locale -> Bool
$c/= :: Locale -> Locale -> Bool
/= :: Locale -> Locale -> Bool
Eq, Int -> Locale -> ShowS
[Locale] -> ShowS
Locale -> String
(Int -> Locale -> ShowS)
-> (Locale -> String) -> ([Locale] -> ShowS) -> Show Locale
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Locale -> ShowS
showsPrec :: Int -> Locale -> ShowS
$cshow :: Locale -> String
show :: Locale -> String
$cshowList :: [Locale] -> ShowS
showList :: [Locale] -> ShowS
Show)

-- | Translate a Windows date\/time /picture/ string (as returned by @GetLocaleInfoEx@, e.g. @dd.MM.yyyy@) into the
--   equivalent POSIX @strftime@ string, so the locale-layout patterns can consume a Windows-read locale.  Recognised
--   fields: @d@\/@dd@ (day), @ddd@\/@dddd@ (weekday name), @M@\/@MM@ (month), @MMM@\/@MMMM@ (month name), @yy@ (2-digit
--   year) and @yyyy@+ (full year), @h@\/@hh@ (12-hour), @H@\/@HH@ (24-hour), @m@\/@mm@ (minute), @s@\/@ss@ (second),
--   @t@\/@tt@ (AM\/PM).  Text inside single quotes is literal (@''@ is a literal quote) and any other character is
--   copied through (with @%@ escaped as @%%@).
--
--   NOTE: Windows' no-pad @d@\/@M@ have no exact @strftime@ counterpart in the supported set, so single @d@ maps to the
--   space-padded @%e@ and single @M@ to @%m@ (approximations); the common two-digit @dd@\/@MM@ are exact.
windowsPictureToStrftime :: String -> String
windowsPictureToStrftime :: ShowS
windowsPictureToStrftime [] = []
windowsPictureToStrftime (Char
'\'' : String
rest) = ShowS
winLiteral String
rest
windowsPictureToStrftime (Char
c : String
rest)
  | Char
c Char -> String -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` String
"dMyHhmst" = Char -> Int -> String
winField Char
c (Int
1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
same) String -> ShowS
forall a. [a] -> [a] -> [a]
++ ShowS
windowsPictureToStrftime String
rest'
  | Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'%'            = Char
'%' Char -> ShowS
forall a. a -> [a] -> [a]
: Char
'%' Char -> ShowS
forall a. a -> [a] -> [a]
: ShowS
windowsPictureToStrftime String
rest
  | Bool
otherwise           = Char
c Char -> ShowS
forall a. a -> [a] -> [a]
: ShowS
windowsPictureToStrftime String
rest
  where
    (String
same, String
rest') = (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
c) String
rest

-- | Map a Windows field letter and its repeat count to a @strftime@ specifier.
winField :: Char -> Int -> String
winField :: Char -> Int -> String
winField Char
'd' Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
4 = String
"%A" | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
3 = String
"%a" | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
2 = String
"%d" | Bool
otherwise = String
"%e"
winField Char
'M' Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
4 = String
"%B" | Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
3 = String
"%b" | Bool
otherwise = String
"%m"
winField Char
'y' Int
n | Int
n Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
3 = String
"%Y" | Bool
otherwise = String
"%y"
winField Char
'H' Int
_ = String
"%H"
winField Char
'h' Int
_ = String
"%I"
winField Char
'm' Int
_ = String
"%M"
winField Char
's' Int
_ = String
"%S"
winField Char
't' Int
_ = String
"%p"
winField Char
_   Int
_ = String
""

-- | Continue a Windows picture inside a single-quoted literal run.
winLiteral :: String -> String
winLiteral :: ShowS
winLiteral [] = []
winLiteral (Char
'\'' : Char
'\'' : String
rest) = Char
'\'' Char -> ShowS
forall a. a -> [a] -> [a]
: ShowS
winLiteral String
rest
winLiteral (Char
'\'' : String
rest)        = ShowS
windowsPictureToStrftime String
rest
winLiteral (Char
c : String
rest)
  | Char
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'%'  = Char
'%' Char -> ShowS
forall a. a -> [a] -> [a]
: Char
'%' Char -> ShowS
forall a. a -> [a] -> [a]
: ShowS
winLiteral String
rest
  | Bool
otherwise = Char
c Char -> ShowS
forall a. a -> [a] -> [a]
: ShowS
winLiteral String
rest

-- | A built-in United States English locale (@en_US@), offered so patterns can be produced without reading the machine.
--   Mirrors the @en_US@ @LC_TIME@ data: month-first dates and a 12-hour @%r@ time.
enUS :: Locale
enUS :: Locale
enUS = Locale
  { localeId :: String
localeId          = String
"en_US"
  , monthNames :: [String]
monthNames        = [String
"January",String
"February",String
"March",String
"April",String
"May",String
"June",String
"July",String
"August",String
"September",String
"October",String
"November",String
"December"]
  , monthNamesShort :: [String]
monthNamesShort   = [String
"Jan",String
"Feb",String
"Mar",String
"Apr",String
"May",String
"Jun",String
"Jul",String
"Aug",String
"Sep",String
"Oct",String
"Nov",String
"Dec"]
  , dayNames :: [String]
dayNames          = [String
"Sunday",String
"Monday",String
"Tuesday",String
"Wednesday",String
"Thursday",String
"Friday",String
"Saturday"]
  , dayNamesShort :: [String]
dayNamesShort     = [String
"Sun",String
"Mon",String
"Tue",String
"Wed",String
"Thu",String
"Fri",String
"Sat"]
  , amName :: String
amName            = String
"AM"
  , pmName :: String
pmName            = String
"PM"
  , rawDateFormat :: String
rawDateFormat     = String
"%m/%d/%Y"
  , rawTimeFormat :: String
rawTimeFormat     = String
"%r"
  , rawDateTimeFormat :: String
rawDateTimeFormat = String
"%a %d %b %Y %r %Z"
  }

-- | A built-in German locale (@de_DE@): day-first dates, 24-hour time, and \(as on a real @de_DE@\) /empty/ AM\/PM
--   designators.
deDE :: Locale
deDE :: Locale
deDE = Locale
  { localeId :: String
localeId          = String
"de_DE"
  , monthNames :: [String]
monthNames        = [String
"Januar",String
"Februar",String
"März",String
"April",String
"Mai",String
"Juni",String
"Juli",String
"August",String
"September",String
"Oktober",String
"November",String
"Dezember"]
  , monthNamesShort :: [String]
monthNamesShort   = [String
"Jan",String
"Feb",String
"Mär",String
"Apr",String
"Mai",String
"Jun",String
"Jul",String
"Aug",String
"Sep",String
"Okt",String
"Nov",String
"Dez"]
  , dayNames :: [String]
dayNames          = [String
"Sonntag",String
"Montag",String
"Dienstag",String
"Mittwoch",String
"Donnerstag",String
"Freitag",String
"Samstag"]
  , dayNamesShort :: [String]
dayNamesShort     = [String
"So",String
"Mo",String
"Di",String
"Mi",String
"Do",String
"Fr",String
"Sa"]
  , amName :: String
amName            = String
""
  , pmName :: String
pmName            = String
""
  , rawDateFormat :: String
rawDateFormat     = String
"%d.%m.%Y"
  , rawTimeFormat :: String
rawTimeFormat     = String
"%T"
  , rawDateTimeFormat :: String
rawDateTimeFormat = String
"%a %d %b %Y %T %Z"
  }

-- | A built-in Japanese locale (@ja_JP@): @年\/月\/日@-punctuated numeric dates and @午前\/午後@ AM\/PM designators.
jaJP :: Locale
jaJP :: Locale
jaJP = Locale
  { localeId :: String
localeId          = String
"ja_JP"
  , monthNames :: [String]
monthNames        = [String
"1月",String
"2月",String
"3月",String
"4月",String
"5月",String
"6月",String
"7月",String
"8月",String
"9月",String
"10月",String
"11月",String
"12月"]
  , monthNamesShort :: [String]
monthNamesShort   = [String
"1月",String
"2月",String
"3月",String
"4月",String
"5月",String
"6月",String
"7月",String
"8月",String
"9月",String
"10月",String
"11月",String
"12月"]
  , dayNames :: [String]
dayNames          = [String
"日曜日",String
"月曜日",String
"火曜日",String
"水曜日",String
"木曜日",String
"金曜日",String
"土曜日"]
  , dayNamesShort :: [String]
dayNamesShort     = [String
"日",String
"月",String
"火",String
"水",String
"木",String
"金",String
"土"]
  , amName :: String
amName            = String
"午前"
  , pmName :: String
pmName            = String
"午後"
  , rawDateFormat :: String
rawDateFormat     = String
"%Y年%m月%d日"
  , rawTimeFormat :: String
rawTimeFormat     = String
"%H時%M分%S秒"
  , rawDateTimeFormat :: String
rawDateTimeFormat = String
"%Y年%m月%d日 %H時%M分%S秒"
  }