module Data.Internal.Wkt.Line
  ( line
  , lineString
  , multiLineString
  , emptyLine
  , emptyMultiLine
  , commandPoint
  ) where

import           Control.Applicative      ((<|>))
import qualified Data.Geospatial          as Geospatial
import qualified Data.LineString          as LineString
import qualified Data.Sequence            as Sequence
import qualified Text.Trifecta            as Trifecta

import qualified Data.Internal.Wkt.Common as Wkt
import qualified Data.Internal.Wkt.Point  as Point

lineString :: Trifecta.Parser Geospatial.GeoLine
lineString :: Parser GeoLine
lineString = do
  String
_ <- String -> Parser String
forall (m :: * -> *). CharParsing m => String -> m String
Trifecta.string String
"linestring"
  ()
_ <- Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces
  (String -> Parser String
forall (m :: * -> *). CharParsing m => String -> m String
Trifecta.string String
"empty" Parser String -> Parser GeoLine -> Parser GeoLine
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> GeoLine -> Parser GeoLine
forall (f :: * -> *) a. Applicative f => a -> f a
pure GeoLine
emptyLine) Parser GeoLine -> Parser GeoLine -> Parser GeoLine
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser GeoLine
nonEmptyLines

nonEmptyLines :: Trifecta.Parser Geospatial.GeoLine
nonEmptyLines :: Parser GeoLine
nonEmptyLines =
  (String -> Parser String
forall (m :: * -> *). CharParsing m => String -> m String
Trifecta.string String
"zm" Parser String -> Parser GeoLine -> Parser GeoLine
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> LineString GeoPositionWithoutCRS -> GeoLine
Geospatial.GeoLine (LineString GeoPositionWithoutCRS -> GeoLine)
-> Parser (LineString GeoPositionWithoutCRS) -> Parser GeoLine
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser GeoPositionWithoutCRS
-> Parser (LineString GeoPositionWithoutCRS)
line Parser GeoPositionWithoutCRS
Point.justPointsXYZM)
  Parser GeoLine -> Parser GeoLine -> Parser GeoLine
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (String -> Parser String
forall (m :: * -> *). CharParsing m => String -> m String
Trifecta.string String
"z" Parser String -> Parser GeoLine -> Parser GeoLine
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> LineString GeoPositionWithoutCRS -> GeoLine
Geospatial.GeoLine (LineString GeoPositionWithoutCRS -> GeoLine)
-> Parser (LineString GeoPositionWithoutCRS) -> Parser GeoLine
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser GeoPositionWithoutCRS
-> Parser (LineString GeoPositionWithoutCRS)
line Parser GeoPositionWithoutCRS
Point.justPointsXYZ)
  Parser GeoLine -> Parser GeoLine -> Parser GeoLine
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> LineString GeoPositionWithoutCRS -> GeoLine
Geospatial.GeoLine (LineString GeoPositionWithoutCRS -> GeoLine)
-> Parser (LineString GeoPositionWithoutCRS) -> Parser GeoLine
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser GeoPositionWithoutCRS
-> Parser (LineString GeoPositionWithoutCRS)
line Parser GeoPositionWithoutCRS
Point.justPointsXY

multiLineString :: Trifecta.Parser Geospatial.GeoMultiLine
multiLineString :: Parser GeoMultiLine
multiLineString = do
  String
_ <- String -> Parser String
forall (m :: * -> *). CharParsing m => String -> m String
Trifecta.string String
"multilinestring"
  ()
_ <- Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces
  Seq (LineString GeoPositionWithoutCRS)
x <- Parser (Seq (LineString GeoPositionWithoutCRS))
forall a. Parser (Seq a)
Wkt.emptySet Parser (Seq (LineString GeoPositionWithoutCRS))
-> Parser (Seq (LineString GeoPositionWithoutCRS))
-> Parser (Seq (LineString GeoPositionWithoutCRS))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser (Seq (LineString GeoPositionWithoutCRS))
nonEmptyMultiLines
  GeoMultiLine -> Parser GeoMultiLine
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GeoMultiLine -> Parser GeoMultiLine)
-> GeoMultiLine -> Parser GeoMultiLine
forall a b. (a -> b) -> a -> b
$ Seq (LineString GeoPositionWithoutCRS) -> GeoMultiLine
Geospatial.GeoMultiLine Seq (LineString GeoPositionWithoutCRS)
x

nonEmptyMultiLines :: Trifecta.Parser (Sequence.Seq (LineString.LineString Geospatial.GeoPositionWithoutCRS))
nonEmptyMultiLines :: Parser (Seq (LineString GeoPositionWithoutCRS))
nonEmptyMultiLines =
  (String -> Parser String
forall (m :: * -> *). CharParsing m => String -> m String
Trifecta.string String
"zm" Parser String
-> Parser (Seq (LineString GeoPositionWithoutCRS))
-> Parser (Seq (LineString GeoPositionWithoutCRS))
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser GeoPositionWithoutCRS
-> Parser (Seq (LineString GeoPositionWithoutCRS))
manyLines Parser GeoPositionWithoutCRS
Point.justPointsXYZM)
  Parser (Seq (LineString GeoPositionWithoutCRS))
-> Parser (Seq (LineString GeoPositionWithoutCRS))
-> Parser (Seq (LineString GeoPositionWithoutCRS))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (String -> Parser String
forall (m :: * -> *). CharParsing m => String -> m String
Trifecta.string String
"z" Parser String
-> Parser (Seq (LineString GeoPositionWithoutCRS))
-> Parser (Seq (LineString GeoPositionWithoutCRS))
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser GeoPositionWithoutCRS
-> Parser (Seq (LineString GeoPositionWithoutCRS))
manyLines Parser GeoPositionWithoutCRS
Point.justPointsXYZ)
  Parser (Seq (LineString GeoPositionWithoutCRS))
-> Parser (Seq (LineString GeoPositionWithoutCRS))
-> Parser (Seq (LineString GeoPositionWithoutCRS))
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser GeoPositionWithoutCRS
-> Parser (Seq (LineString GeoPositionWithoutCRS))
manyLines Parser GeoPositionWithoutCRS
Point.justPointsXY

manyLines :: Trifecta.Parser Geospatial.GeoPositionWithoutCRS ->  Trifecta.Parser (Sequence.Seq (LineString.LineString Geospatial.GeoPositionWithoutCRS))
manyLines :: Parser GeoPositionWithoutCRS
-> Parser (Seq (LineString GeoPositionWithoutCRS))
manyLines Parser GeoPositionWithoutCRS
pointParser = do
  Char
_ <- Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces Parser () -> Parser Char -> Parser Char
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> Parser Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Trifecta.char Char
'('
  LineString GeoPositionWithoutCRS
x <- Parser GeoPositionWithoutCRS
-> Parser (LineString GeoPositionWithoutCRS)
line Parser GeoPositionWithoutCRS
pointParser
  [LineString GeoPositionWithoutCRS]
xs <- Parser (LineString GeoPositionWithoutCRS)
-> Parser [LineString GeoPositionWithoutCRS]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
Trifecta.many (Char -> Parser Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Trifecta.char Char
',' Parser Char -> Parser () -> Parser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces Parser ()
-> Parser (LineString GeoPositionWithoutCRS)
-> Parser (LineString GeoPositionWithoutCRS)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser GeoPositionWithoutCRS
-> Parser (LineString GeoPositionWithoutCRS)
line Parser GeoPositionWithoutCRS
pointParser)
  ()
_ <-  Char -> Parser Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Trifecta.char Char
')' Parser Char -> Parser () -> Parser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces
  Seq (LineString GeoPositionWithoutCRS)
-> Parser (Seq (LineString GeoPositionWithoutCRS))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Seq (LineString GeoPositionWithoutCRS)
 -> Parser (Seq (LineString GeoPositionWithoutCRS)))
-> Seq (LineString GeoPositionWithoutCRS)
-> Parser (Seq (LineString GeoPositionWithoutCRS))
forall a b. (a -> b) -> a -> b
$ LineString GeoPositionWithoutCRS
x LineString GeoPositionWithoutCRS
-> Seq (LineString GeoPositionWithoutCRS)
-> Seq (LineString GeoPositionWithoutCRS)
forall a. a -> Seq a -> Seq a
Sequence.:<| [LineString GeoPositionWithoutCRS]
-> Seq (LineString GeoPositionWithoutCRS)
forall a. [a] -> Seq a
Sequence.fromList [LineString GeoPositionWithoutCRS]
xs

line :: Trifecta.Parser Geospatial.GeoPositionWithoutCRS -> Trifecta.Parser (LineString.LineString Geospatial.GeoPositionWithoutCRS)
line :: Parser GeoPositionWithoutCRS
-> Parser (LineString GeoPositionWithoutCRS)
line Parser GeoPositionWithoutCRS
pointParser = do
  ()
_ <- Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces Parser () -> Parser Char -> Parser Char
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Char -> Parser Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Trifecta.char Char
'(' Parser Char -> Parser () -> Parser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces
  GeoPositionWithoutCRS
first <- Parser GeoPositionWithoutCRS
pointParser
  GeoPositionWithoutCRS
second <- Parser GeoPositionWithoutCRS -> Parser GeoPositionWithoutCRS
commandPoint Parser GeoPositionWithoutCRS
pointParser
  [GeoPositionWithoutCRS]
rest <- Parser GeoPositionWithoutCRS -> Parser [GeoPositionWithoutCRS]
forall (f :: * -> *) a. Alternative f => f a -> f [a]
Trifecta.many (Parser GeoPositionWithoutCRS -> Parser GeoPositionWithoutCRS
commandPoint Parser GeoPositionWithoutCRS
pointParser)
  ()
_ <- Char -> Parser Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Trifecta.char Char
')' Parser Char -> Parser () -> Parser ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces
  LineString GeoPositionWithoutCRS
-> Parser (LineString GeoPositionWithoutCRS)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (LineString GeoPositionWithoutCRS
 -> Parser (LineString GeoPositionWithoutCRS))
-> LineString GeoPositionWithoutCRS
-> Parser (LineString GeoPositionWithoutCRS)
forall a b. (a -> b) -> a -> b
$ GeoPositionWithoutCRS
-> GeoPositionWithoutCRS
-> Seq GeoPositionWithoutCRS
-> LineString GeoPositionWithoutCRS
forall a. a -> a -> Seq a -> LineString a
LineString.makeLineString GeoPositionWithoutCRS
first GeoPositionWithoutCRS
second ([GeoPositionWithoutCRS] -> Seq GeoPositionWithoutCRS
forall a. [a] -> Seq a
Sequence.fromList [GeoPositionWithoutCRS]
rest)

commandPoint :: Trifecta.Parser Geospatial.GeoPositionWithoutCRS -> Trifecta.Parser Geospatial.GeoPositionWithoutCRS
commandPoint :: Parser GeoPositionWithoutCRS -> Parser GeoPositionWithoutCRS
commandPoint Parser GeoPositionWithoutCRS
pointParser = do
  Char
_ <- Char -> Parser Char
forall (m :: * -> *). CharParsing m => Char -> m Char
Trifecta.char Char
','
  ()
_ <- Parser ()
forall (m :: * -> *). CharParsing m => m ()
Trifecta.spaces
  Parser GeoPositionWithoutCRS
pointParser

emptyLine :: Geospatial.GeoLine
emptyLine :: GeoLine
emptyLine = LineString GeoPositionWithoutCRS -> GeoLine
Geospatial.GeoLine (LineString GeoPositionWithoutCRS -> GeoLine)
-> LineString GeoPositionWithoutCRS -> GeoLine
forall a b. (a -> b) -> a -> b
$ GeoPositionWithoutCRS
-> GeoPositionWithoutCRS
-> Seq GeoPositionWithoutCRS
-> LineString GeoPositionWithoutCRS
forall a. a -> a -> Seq a -> LineString a
LineString.makeLineString GeoPositionWithoutCRS
Geospatial.GeoEmpty GeoPositionWithoutCRS
Geospatial.GeoEmpty Seq GeoPositionWithoutCRS
forall a. Seq a
Sequence.empty

emptyMultiLine :: Geospatial.GeoMultiLine
emptyMultiLine :: GeoMultiLine
emptyMultiLine = Seq GeoLine -> GeoMultiLine
Geospatial.mergeGeoLines Seq GeoLine
forall a. Seq a
Sequence.empty