-- Refer to the WKT Spec <http://www.opengeospatial.org/standards/wkt-crs>
--
-- Allows parsing of String or ByteString into a Wkt object.
--
-------------------------------------------------------------------
module Data.Wkt
  ( parseByteString
  , parseString
  , WktGeometryCollection.geometryCollection
  , WktGeometryCollection.emptyGeometryCollection
  , WktBox.box
  , WktLine.emptyLine
  , WktLine.emptyMultiLine
  , WktLine.lineString
  , WktLine.multiLineString
  , WktPoint.emptyPoint
  , WktPoint.emptyMultiPoint
  , WktPoint.point
  , WktPoint.multiPoint
  , WktPolygon.emptyPolygon
  , WktPolygon.emptyMultiPolygon
  , WktPolygon.polygon
  , WktPolygon.multiPolygon
  ) where

import qualified Data.ByteString                      as ByteString
import qualified Data.ByteString.UTF8                 as UTF8
import qualified Data.Char                            as Char
import qualified Text.Trifecta                        as Trifecta
import qualified Text.Trifecta.Delta                  as TrifectaDelta

import qualified Data.Internal.Wkt.Box                as WktBox
import qualified Data.Internal.Wkt.GeometryCollection as WktGeometryCollection
import qualified Data.Internal.Wkt.Line               as WktLine
import qualified Data.Internal.Wkt.Point              as WktPoint
import qualified Data.Internal.Wkt.Polygon            as WktPolygon

delta :: String -> TrifectaDelta.Delta
delta :: String -> Delta
delta String
str = ByteString -> Int64 -> Int64 -> Int64 -> Int64 -> Delta
TrifectaDelta.Directed (String -> ByteString
UTF8.fromString String
str) Int64
0 Int64
0 Int64
0 Int64
0

parseByteString :: Trifecta.Parser a -> ByteString.ByteString -> Trifecta.Result a
parseByteString :: Parser a -> ByteString -> Result a
parseByteString Parser a
p ByteString
bs = Parser a -> Delta -> ByteString -> Result a
forall a. Parser a -> Delta -> ByteString -> Result a
Trifecta.parseByteString Parser a
p (ByteString -> Int64 -> Int64 -> Int64 -> Int64 -> Delta
TrifectaDelta.Directed ByteString
lowerBs Int64
0 Int64
0 Int64
0 Int64
0) ByteString
lowerBs
  where
    lowerBs :: ByteString
lowerBs = ByteString -> ByteString
d8ToLower ByteString
bs
    d8ToLower :: ByteString -> ByteString
d8ToLower = (Word8 -> Word8) -> ByteString -> ByteString
ByteString.map Word8 -> Word8
forall p. (Ord p, Num p) => p -> p
f
      where
        f :: p -> p
f p
w | p
w p -> p -> Bool
forall a. Ord a => a -> a -> Bool
>= p
65 Bool -> Bool -> Bool
&& p
w p -> p -> Bool
forall a. Ord a => a -> a -> Bool
<= p
90 = p
w p -> p -> p
forall a. Num a => a -> a -> a
+ p
32
            | Bool
otherwise = p
w

parseString :: Trifecta.Parser a -> String -> Trifecta.Result a
parseString :: Parser a -> String -> Result a
parseString Parser a
p String
s = Parser a -> Delta -> String -> Result a
forall a. Parser a -> Delta -> String -> Result a
Trifecta.parseString Parser a
p (String -> Delta
Data.Wkt.delta String
lowerS) String
lowerS
  where
    lowerS :: String
lowerS = String -> String
asciiToLower String
s
    asciiToLower :: String -> String
asciiToLower = (Char -> Char) -> String -> String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Char -> Char
f
      where
        f :: Char -> Char
f Char
c | Char -> Bool
Char.isAsciiUpper Char
c = Int -> Char
Char.chr (Char -> Int
Char.ord Char
c Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
32)
            | Bool
otherwise = Char
c