{-# LANGUAGE DeriveAnyClass  #-}
{-# LANGUAGE DeriveGeneric   #-}
{-# LANGUAGE TemplateHaskell #-}
-------------------------------------------------------------------
-- |
-- Module       : Data.Geospatial.Internal.Geometry.GeoMultiPoint
-- Copyright    : (C) 2014-2019 HS-GeoJSON Project
-- License      : BSD-style (see the file LICENSE.md)
-- Maintainer   : Andrew Newman
--
-------------------------------------------------------------------
module Data.Geospatial.Internal.Geometry.GeoMultiPoint (
    -- * Type
        GeoMultiPoint(..)
    -- * Lenses
    ,   unGeoMultiPoint
    -- * To Points
    ,   splitGeoMultiPoint, mergeGeoPoints
    ) where

import           Data.Geospatial.Internal.BasicTypes
import           Data.Geospatial.Internal.Geometry.Aeson
import           Data.Geospatial.Internal.Geometry.GeoPoint

import           Control.DeepSeq
import           Control.Lens                               (makeLenses)
import           Control.Monad                              (mzero)
import qualified Data.Aeson                                 as Aeson
import qualified Data.Sequence                              as Sequence
import           GHC.Generics                               (Generic)

newtype GeoMultiPoint = GeoMultiPoint { GeoMultiPoint -> Seq GeoPositionWithoutCRS
_unGeoMultiPoint :: Sequence.Seq GeoPositionWithoutCRS } deriving (Int -> GeoMultiPoint -> ShowS
[GeoMultiPoint] -> ShowS
GeoMultiPoint -> String
(Int -> GeoMultiPoint -> ShowS)
-> (GeoMultiPoint -> String)
-> ([GeoMultiPoint] -> ShowS)
-> Show GeoMultiPoint
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [GeoMultiPoint] -> ShowS
$cshowList :: [GeoMultiPoint] -> ShowS
show :: GeoMultiPoint -> String
$cshow :: GeoMultiPoint -> String
showsPrec :: Int -> GeoMultiPoint -> ShowS
$cshowsPrec :: Int -> GeoMultiPoint -> ShowS
Show, GeoMultiPoint -> GeoMultiPoint -> Bool
(GeoMultiPoint -> GeoMultiPoint -> Bool)
-> (GeoMultiPoint -> GeoMultiPoint -> Bool) -> Eq GeoMultiPoint
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GeoMultiPoint -> GeoMultiPoint -> Bool
$c/= :: GeoMultiPoint -> GeoMultiPoint -> Bool
== :: GeoMultiPoint -> GeoMultiPoint -> Bool
$c== :: GeoMultiPoint -> GeoMultiPoint -> Bool
Eq, (forall x. GeoMultiPoint -> Rep GeoMultiPoint x)
-> (forall x. Rep GeoMultiPoint x -> GeoMultiPoint)
-> Generic GeoMultiPoint
forall x. Rep GeoMultiPoint x -> GeoMultiPoint
forall x. GeoMultiPoint -> Rep GeoMultiPoint x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep GeoMultiPoint x -> GeoMultiPoint
$cfrom :: forall x. GeoMultiPoint -> Rep GeoMultiPoint x
Generic, GeoMultiPoint -> ()
(GeoMultiPoint -> ()) -> NFData GeoMultiPoint
forall a. (a -> ()) -> NFData a
rnf :: GeoMultiPoint -> ()
$crnf :: GeoMultiPoint -> ()
NFData)

makeLenses ''GeoMultiPoint

-- | Split GeoMultiPoint coordinates into multiple GeoPoints
splitGeoMultiPoint:: GeoMultiPoint -> Sequence.Seq GeoPoint
splitGeoMultiPoint :: GeoMultiPoint -> Seq GeoPoint
splitGeoMultiPoint = (GeoPositionWithoutCRS -> GeoPoint)
-> Seq GeoPositionWithoutCRS -> Seq GeoPoint
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap GeoPositionWithoutCRS -> GeoPoint
GeoPoint (Seq GeoPositionWithoutCRS -> Seq GeoPoint)
-> (GeoMultiPoint -> Seq GeoPositionWithoutCRS)
-> GeoMultiPoint
-> Seq GeoPoint
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GeoMultiPoint -> Seq GeoPositionWithoutCRS
_unGeoMultiPoint

-- | Merge multiple GeoPoints into one GeoMultiPoint
mergeGeoPoints :: Sequence.Seq GeoPoint -> GeoMultiPoint
mergeGeoPoints :: Seq GeoPoint -> GeoMultiPoint
mergeGeoPoints = Seq GeoPositionWithoutCRS -> GeoMultiPoint
GeoMultiPoint (Seq GeoPositionWithoutCRS -> GeoMultiPoint)
-> (Seq GeoPoint -> Seq GeoPositionWithoutCRS)
-> Seq GeoPoint
-> GeoMultiPoint
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GeoPoint -> GeoPositionWithoutCRS)
-> Seq GeoPoint -> Seq GeoPositionWithoutCRS
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap GeoPoint -> GeoPositionWithoutCRS
_unGeoPoint

-- instances

instance Aeson.ToJSON GeoMultiPoint where
  --  toJSON :: a -> Value
  toJSON :: GeoMultiPoint -> Value
toJSON = String -> Seq GeoPositionWithoutCRS -> Value
forall a. ToJSON a => String -> a -> Value
makeGeometryGeoAeson String
"MultiPoint" (Seq GeoPositionWithoutCRS -> Value)
-> (GeoMultiPoint -> Seq GeoPositionWithoutCRS)
-> GeoMultiPoint
-> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GeoMultiPoint -> Seq GeoPositionWithoutCRS
_unGeoMultiPoint

instance Aeson.FromJSON GeoMultiPoint where
  --  parseJSON :: Value -> Parser a
  parseJSON :: Value -> Parser GeoMultiPoint
parseJSON (Aeson.Object Object
o) = String
-> (Seq GeoPositionWithoutCRS -> GeoMultiPoint)
-> Object
-> Parser GeoMultiPoint
forall a b.
(FromJSON a, FromJSON b) =>
String -> (a -> b) -> Object -> Parser b
readGeometryGeoAeson String
"MultiPoint" Seq GeoPositionWithoutCRS -> GeoMultiPoint
GeoMultiPoint Object
o
  parseJSON Value
_          = Parser GeoMultiPoint
forall (m :: * -> *) a. MonadPlus m => m a
mzero