module Monomer.Graph.GraphData
    ( GraphData(..)
    , graphPoint
    , graphPoints
    , graphColor
    , graphHoverColor
    , graphActiveColor
    , graphBorderColor
    , graphWidth
    , graphRadius
    , graphSeparate
    , graphSeparate_
    , graphFill
    , graphFill_
    , graphFillAlpha
    , graphDuration
    , graphOnFinished
    , graphOnFinishedReq
    , graphOnChange
    , graphOnChangeReq
    , graphOnEnter
    , graphOnEnterReq
    , graphOnLeave
    , graphOnLeaveReq
    , graphOnClick
    , graphOnClickReq
    ) where

import Control.Applicative ((<|>))
import Data.Default
import Monomer.Graphics.Types
import Monomer.Widgets.Single

{-|
Options for graph data:

- 'graphPoint': render single point.
- 'graphPoints': use multiple points.
- 'graphColor': set the color.
- 'graphHoverColor': set the color of hovered point.
- 'graphActiveColor': set the color of dragged point.
- 'graphBorderColor': set the color of point border.
- 'graphWidth': set the width of the line.
- 'graphRadius': set the radius of the points.
- 'graphSeparate': whether the points should be rendered separately.
- 'graphFill': whether to fill the area surrounded by points.
- 'graphFillAlpha': transparency level of the filled area.
- 'graphDuration': how long the animation lasts in ms.
- 'graphOnFinished': event to raise when animation is complete.
- 'graphOnFinishedReq': 'WidgetRequest' to generate when animation
is complete.
- 'graphOnChange': event to raise when a point is dragged.
- 'graphOnChangeReq': 'WidgetRequest' to generate when a point is
dragged.
- 'graphOnEnter': event to raise when mouse enters point area.
- 'graphOnEnterReq': 'WidgetRequest' to generate when mouse enters
point area.
- 'graphOnLeave': event to raise when mouse leaves point area.
- 'graphOnLeaveReq': 'WidgetRequest' to generate when mouse leaves
point area.
- 'graphOnClick': event to raise when a point is clicked.
- 'graphOnClickReq': 'WidgetRequest' to generate when a point is
clicked.
-}
data GraphData s e = GraphData
    { forall s e. GraphData s e -> [(Double, Double)]
_gdPoints :: [(Double, Double)]
    , forall s e. GraphData s e -> Maybe Color
_gdColor :: Maybe Color
    , forall s e. GraphData s e -> Maybe Color
_gdHoverColor :: Maybe Color
    , forall s e. GraphData s e -> Maybe Color
_gdActiveColor :: Maybe Color
    , forall s e. GraphData s e -> Maybe Color
_gdBorderColor :: Maybe Color
    , forall s e. GraphData s e -> Maybe Double
_gdWidth :: Maybe Double
    , forall s e. GraphData s e -> Maybe Double
_gdRadius :: Maybe Double
    , forall s e. GraphData s e -> Maybe Bool
_gdSeparate :: Maybe Bool
    , forall s e. GraphData s e -> Maybe Bool
_gdFill :: Maybe Bool
    , forall s e. GraphData s e -> Maybe Double
_gdFillAlpha :: Maybe Double
    , forall s e. GraphData s e -> Maybe Millisecond
_gdDuration :: Maybe Millisecond
    , forall s e. GraphData s e -> [WidgetRequest s e]
_gdFinishedReq :: [WidgetRequest s e]
    , forall s e.
GraphData s e -> [Int -> (Double, Double) -> WidgetRequest s e]
_gdChangeReq :: [Int -> (Double, Double) -> WidgetRequest s e]
    , forall s e. GraphData s e -> [Int -> WidgetRequest s e]
_gdEnterReq :: [Int -> WidgetRequest s e]
    , forall s e. GraphData s e -> [Int -> WidgetRequest s e]
_gdLeaveReq :: [Int -> WidgetRequest s e]
    , forall s e. GraphData s e -> [Int -> WidgetRequest s e]
_gdClickReq :: [Int -> WidgetRequest s e]
    }

instance Default (GraphData s e) where
    def :: GraphData s e
def = GraphData
        { _gdPoints :: [(Double, Double)]
_gdPoints = []
        , _gdColor :: Maybe Color
_gdColor = forall a. Maybe a
Nothing
        , _gdHoverColor :: Maybe Color
_gdHoverColor = forall a. Maybe a
Nothing
        , _gdActiveColor :: Maybe Color
_gdActiveColor = forall a. Maybe a
Nothing
        , _gdBorderColor :: Maybe Color
_gdBorderColor = forall a. Maybe a
Nothing
        , _gdWidth :: Maybe Double
_gdWidth = forall a. Maybe a
Nothing
        , _gdRadius :: Maybe Double
_gdRadius = forall a. Maybe a
Nothing
        , _gdSeparate :: Maybe Bool
_gdSeparate = forall a. Maybe a
Nothing
        , _gdFill :: Maybe Bool
_gdFill = forall a. Maybe a
Nothing
        , _gdFillAlpha :: Maybe Double
_gdFillAlpha = forall a. Maybe a
Nothing
        , _gdDuration :: Maybe Millisecond
_gdDuration = forall a. Maybe a
Nothing
        , _gdFinishedReq :: [WidgetRequest s e]
_gdFinishedReq = []
        , _gdChangeReq :: [Int -> (Double, Double) -> WidgetRequest s e]
_gdChangeReq = []
        , _gdEnterReq :: [Int -> WidgetRequest s e]
_gdEnterReq = []
        , _gdLeaveReq :: [Int -> WidgetRequest s e]
_gdLeaveReq = []
        , _gdClickReq :: [Int -> WidgetRequest s e]
_gdClickReq = []
        }

instance Semigroup (GraphData s e) where
    <> :: GraphData s e -> GraphData s e -> GraphData s e
(<>) GraphData s e
a1 GraphData s e
a2 = forall a. Default a => a
def
        { _gdPoints :: [(Double, Double)]
_gdPoints = forall s e. GraphData s e -> [(Double, Double)]
_gdPoints GraphData s e
a1 forall a. Semigroup a => a -> a -> a
<> forall s e. GraphData s e -> [(Double, Double)]
_gdPoints GraphData s e
a2
        , _gdColor :: Maybe Color
_gdColor = forall s e. GraphData s e -> Maybe Color
_gdColor GraphData s e
a2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e. GraphData s e -> Maybe Color
_gdColor GraphData s e
a1
        , _gdHoverColor :: Maybe Color
_gdHoverColor = forall s e. GraphData s e -> Maybe Color
_gdHoverColor GraphData s e
a2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e. GraphData s e -> Maybe Color
_gdHoverColor GraphData s e
a1
        , _gdActiveColor :: Maybe Color
_gdActiveColor = forall s e. GraphData s e -> Maybe Color
_gdActiveColor GraphData s e
a2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e. GraphData s e -> Maybe Color
_gdActiveColor GraphData s e
a1
        , _gdBorderColor :: Maybe Color
_gdBorderColor = forall s e. GraphData s e -> Maybe Color
_gdBorderColor GraphData s e
a2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e. GraphData s e -> Maybe Color
_gdBorderColor GraphData s e
a1
        , _gdWidth :: Maybe Double
_gdWidth = forall s e. GraphData s e -> Maybe Double
_gdWidth GraphData s e
a2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e. GraphData s e -> Maybe Double
_gdWidth GraphData s e
a1
        , _gdRadius :: Maybe Double
_gdRadius = forall s e. GraphData s e -> Maybe Double
_gdRadius GraphData s e
a2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e. GraphData s e -> Maybe Double
_gdRadius GraphData s e
a1
        , _gdSeparate :: Maybe Bool
_gdSeparate = forall s e. GraphData s e -> Maybe Bool
_gdSeparate GraphData s e
a2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e. GraphData s e -> Maybe Bool
_gdSeparate GraphData s e
a1
        , _gdFill :: Maybe Bool
_gdFill = forall s e. GraphData s e -> Maybe Bool
_gdFill GraphData s e
a2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e. GraphData s e -> Maybe Bool
_gdFill GraphData s e
a1
        , _gdFillAlpha :: Maybe Double
_gdFillAlpha = forall s e. GraphData s e -> Maybe Double
_gdFillAlpha GraphData s e
a2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e. GraphData s e -> Maybe Double
_gdFillAlpha GraphData s e
a1
        , _gdDuration :: Maybe Millisecond
_gdDuration = forall s e. GraphData s e -> Maybe Millisecond
_gdDuration GraphData s e
a2 forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> forall s e. GraphData s e -> Maybe Millisecond
_gdDuration GraphData s e
a1
        , _gdFinishedReq :: [WidgetRequest s e]
_gdFinishedReq = forall s e. GraphData s e -> [WidgetRequest s e]
_gdFinishedReq GraphData s e
a1 forall a. Semigroup a => a -> a -> a
<> forall s e. GraphData s e -> [WidgetRequest s e]
_gdFinishedReq GraphData s e
a2
        , _gdChangeReq :: [Int -> (Double, Double) -> WidgetRequest s e]
_gdChangeReq = forall s e.
GraphData s e -> [Int -> (Double, Double) -> WidgetRequest s e]
_gdChangeReq GraphData s e
a1 forall a. Semigroup a => a -> a -> a
<> forall s e.
GraphData s e -> [Int -> (Double, Double) -> WidgetRequest s e]
_gdChangeReq GraphData s e
a2
        , _gdEnterReq :: [Int -> WidgetRequest s e]
_gdEnterReq = forall s e. GraphData s e -> [Int -> WidgetRequest s e]
_gdEnterReq GraphData s e
a1 forall a. Semigroup a => a -> a -> a
<> forall s e. GraphData s e -> [Int -> WidgetRequest s e]
_gdEnterReq GraphData s e
a2
        , _gdLeaveReq :: [Int -> WidgetRequest s e]
_gdLeaveReq = forall s e. GraphData s e -> [Int -> WidgetRequest s e]
_gdLeaveReq GraphData s e
a1 forall a. Semigroup a => a -> a -> a
<> forall s e. GraphData s e -> [Int -> WidgetRequest s e]
_gdLeaveReq GraphData s e
a2
        , _gdClickReq :: [Int -> WidgetRequest s e]
_gdClickReq = forall s e. GraphData s e -> [Int -> WidgetRequest s e]
_gdClickReq GraphData s e
a1 forall a. Semigroup a => a -> a -> a
<> forall s e. GraphData s e -> [Int -> WidgetRequest s e]
_gdClickReq GraphData s e
a2
        }

instance Monoid (GraphData s e) where
    mempty :: GraphData s e
mempty = forall a. Default a => a
def

{-|
Render single point.
-}
graphPoint :: (Double, Double) -> GraphData s e
graphPoint :: forall s e. (Double, Double) -> GraphData s e
graphPoint (Double, Double)
point = forall s e. [(Double, Double)] -> GraphData s e
graphPoints [(Double, Double)
point]

{-|
Use multiple points.
-}
graphPoints :: [(Double, Double)] -> GraphData s e
graphPoints :: forall s e. [(Double, Double)] -> GraphData s e
graphPoints [(Double, Double)]
points = forall a. Default a => a
def
    { _gdPoints :: [(Double, Double)]
_gdPoints = [(Double, Double)]
points
    }

{-|
Set the color (if this option is not used then the graph will not be
rendered).
-}
graphColor :: Color -> GraphData s e
graphColor :: forall s e. Color -> GraphData s e
graphColor Color
color = forall a. Default a => a
def
    { _gdColor :: Maybe Color
_gdColor = forall a. a -> Maybe a
Just Color
color
    }

{-|
Set the color of hovered point (if this option is not used then
the color set by 'graphColor' is used).
-}
graphHoverColor :: Color -> GraphData s e
graphHoverColor :: forall s e. Color -> GraphData s e
graphHoverColor Color
color = forall a. Default a => a
def
    { _gdHoverColor :: Maybe Color
_gdHoverColor = forall a. a -> Maybe a
Just Color
color
    }

{-|
Set the color of dragged point (if this option is not used then
the color set by 'graphColor' is used).
-}
graphActiveColor :: Color -> GraphData s e
graphActiveColor :: forall s e. Color -> GraphData s e
graphActiveColor Color
color = forall a. Default a => a
def
    { _gdActiveColor :: Maybe Color
_gdActiveColor = forall a. a -> Maybe a
Just Color
color
    }

{-|
Set the color of point border. The width of the border will be half
the width set by 'graphWidth'.
-}
graphBorderColor :: Color -> GraphData s e
graphBorderColor :: forall s e. Color -> GraphData s e
graphBorderColor Color
color = forall a. Default a => a
def
    { _gdBorderColor :: Maybe Color
_gdBorderColor = forall a. a -> Maybe a
Just Color
color
    }

{-|
Width of the line connecting provided points. If only single point
is rendered then its radius will be twice the width.
-}
graphWidth :: Double -> GraphData s e
graphWidth :: forall s e. Double -> GraphData s e
graphWidth Double
w = forall a. Default a => a
def
    { _gdWidth :: Maybe Double
_gdWidth = forall a. a -> Maybe a
Just Double
w
    }

{-|
Radius of the provided points if they are rendered separately. The
difference between `graphWidth` and `graphRadius` is that the former
is given in pixels and renders the same when the scale changes while
the latter is given in units of the Cartesian coordinate system and
hence the points become bigger or smaller when the scale changes.
-}
graphRadius :: Double -> GraphData s e
graphRadius :: forall s e. Double -> GraphData s e
graphRadius Double
r = forall a. Default a => a
def
    { _gdRadius :: Maybe Double
_gdRadius = forall a. a -> Maybe a
Just Double
r
    }

{-|
Do not connect the points and render them separately. Used when all
points in the collection must have the same color.
-}
graphSeparate :: GraphData s e
graphSeparate :: forall s e. GraphData s e
graphSeparate = forall s e. Bool -> GraphData s e
graphSeparate_ Bool
True

{-|
Whether the points should be rendered separately.
-}
graphSeparate_ :: Bool -> GraphData s e
graphSeparate_ :: forall s e. Bool -> GraphData s e
graphSeparate_ Bool
separate = forall a. Default a => a
def
    { _gdSeparate :: Maybe Bool
_gdSeparate = forall a. a -> Maybe a
Just Bool
separate
    }

{-|
Fill the area surrounded by provided points with the color.
-}
graphFill :: GraphData s e
graphFill :: forall s e. GraphData s e
graphFill = forall s e. Bool -> GraphData s e
graphFill_ Bool
True

{-|
Whether to fill the area surrounded by provided points.
-}
graphFill_ :: Bool -> GraphData s e
graphFill_ :: forall s e. Bool -> GraphData s e
graphFill_ Bool
v = forall a. Default a => a
def
    { _gdFill :: Maybe Bool
_gdFill = forall a. a -> Maybe a
Just Bool
v
    }

{-|
Transparency level of the filled area.
-}
graphFillAlpha :: Double -> GraphData s e
graphFillAlpha :: forall s e. Double -> GraphData s e
graphFillAlpha Double
alpha = forall a. Default a => a
def
    { _gdFillAlpha :: Maybe Double
_gdFillAlpha = forall a. a -> Maybe a
Just Double
alpha
    }

{-|
How long the animation lasts in ms. Animation starts when graph data
changes (for example, point positions or color).
-}
graphDuration :: Millisecond -> GraphData s e
graphDuration :: forall s e. Millisecond -> GraphData s e
graphDuration Millisecond
dur = forall a. Default a => a
def
    { _gdDuration :: Maybe Millisecond
_gdDuration = forall a. a -> Maybe a
Just Millisecond
dur
    }

{-|
Raises an event when animation is complete.
-}
graphOnFinished :: WidgetEvent e => e -> GraphData s e
graphOnFinished :: forall e s. WidgetEvent e => e -> GraphData s e
graphOnFinished e
handler = forall a. Default a => a
def
    { _gdFinishedReq :: [WidgetRequest s e]
_gdFinishedReq = [forall s e. WidgetEvent e => e -> WidgetRequest s e
RaiseEvent e
handler]
    }

{-|
Generates a 'WidgetRequest' when animation is complete.
-}
graphOnFinishedReq :: WidgetRequest s e -> GraphData s e
graphOnFinishedReq :: forall s e. WidgetRequest s e -> GraphData s e
graphOnFinishedReq WidgetRequest s e
req = forall a. Default a => a
def
    { _gdFinishedReq :: [WidgetRequest s e]
_gdFinishedReq = [WidgetRequest s e
req]
    }

{-|
Raises an event when a point is dragged by passing its index and
new coordinates. This option is ignored if 'graphSeparate' is not
enabled.
-}
graphOnChange
    :: WidgetEvent e
    => (Int -> (Double, Double) -> e)
    -> GraphData s e
graphOnChange :: forall e s.
WidgetEvent e =>
(Int -> (Double, Double) -> e) -> GraphData s e
graphOnChange Int -> (Double, Double) -> e
f = forall a. Default a => a
def
    { _gdChangeReq :: [Int -> (Double, Double) -> WidgetRequest s e]
_gdChangeReq = [(forall s e. WidgetEvent e => e -> WidgetRequest s e
RaiseEvent forall b c a. (b -> c) -> (a -> b) -> a -> c
.) forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> (Double, Double) -> e
f]
    }

{-|
Generates a 'WidgetRequest' when a point is dragged by passing its
index and new coordinates. This option is ignored if 'graphSeparate'
is not enabled.
-}
graphOnChangeReq
    :: (Int -> (Double, Double) -> WidgetRequest s e)
    -> GraphData s e
graphOnChangeReq :: forall s e.
(Int -> (Double, Double) -> WidgetRequest s e) -> GraphData s e
graphOnChangeReq Int -> (Double, Double) -> WidgetRequest s e
req = forall a. Default a => a
def
    { _gdChangeReq :: [Int -> (Double, Double) -> WidgetRequest s e]
_gdChangeReq = [Int -> (Double, Double) -> WidgetRequest s e
req]
    }

{-|
Raises an event when mouse enters point area by passing its index.
This option is ignored if 'graphSeparate' is not enabled.
-}
graphOnEnter :: WidgetEvent e => (Int -> e) -> GraphData s e
graphOnEnter :: forall e s. WidgetEvent e => (Int -> e) -> GraphData s e
graphOnEnter Int -> e
f = forall a. Default a => a
def
    { _gdEnterReq :: [Int -> WidgetRequest s e]
_gdEnterReq = [forall s e. WidgetEvent e => e -> WidgetRequest s e
RaiseEvent forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> e
f]
    }

{-|
Generates a 'WidgetRequest' when mouse enters point area by passing
its index. This option is ignored if 'graphSeparate' is not enabled.
-}
graphOnEnterReq :: (Int -> WidgetRequest s e) -> GraphData s e
graphOnEnterReq :: forall s e. (Int -> WidgetRequest s e) -> GraphData s e
graphOnEnterReq Int -> WidgetRequest s e
req = forall a. Default a => a
def
    { _gdEnterReq :: [Int -> WidgetRequest s e]
_gdEnterReq = [Int -> WidgetRequest s e
req]
    }

{-|
Raises an event when mouse leaves point area by passing its index.
This option is ignored if 'graphSeparate' is not enabled.
-}
graphOnLeave :: WidgetEvent e => (Int -> e) -> GraphData s e
graphOnLeave :: forall e s. WidgetEvent e => (Int -> e) -> GraphData s e
graphOnLeave Int -> e
f = forall a. Default a => a
def
    { _gdLeaveReq :: [Int -> WidgetRequest s e]
_gdLeaveReq = [forall s e. WidgetEvent e => e -> WidgetRequest s e
RaiseEvent forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> e
f]
    }

{-|
Generates a 'WidgetRequest' when mouse leaves point area by passing
its index. This option is ignored if 'graphSeparate' is not enabled.
-}
graphOnLeaveReq :: (Int -> WidgetRequest s e) -> GraphData s e
graphOnLeaveReq :: forall s e. (Int -> WidgetRequest s e) -> GraphData s e
graphOnLeaveReq Int -> WidgetRequest s e
req = forall a. Default a => a
def
    { _gdLeaveReq :: [Int -> WidgetRequest s e]
_gdLeaveReq = [Int -> WidgetRequest s e
req]
    }

{-|
Raises an event when a point is clicked by passing its index. This
option is ignored if 'graphSeparate' is not enabled.
-}
graphOnClick :: WidgetEvent e => (Int -> e) -> GraphData s e
graphOnClick :: forall e s. WidgetEvent e => (Int -> e) -> GraphData s e
graphOnClick Int -> e
f = forall a. Default a => a
def
    { _gdClickReq :: [Int -> WidgetRequest s e]
_gdClickReq = [forall s e. WidgetEvent e => e -> WidgetRequest s e
RaiseEvent forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> e
f]
    }

{-|
Generates a 'WidgetRequest' when a point is clicked by passing its
index. This option is ignored if 'graphSeparate' is not enabled.
-}
graphOnClickReq :: (Int -> WidgetRequest s e) -> GraphData s e
graphOnClickReq :: forall s e. (Int -> WidgetRequest s e) -> GraphData s e
graphOnClickReq Int -> WidgetRequest s e
req = forall a. Default a => a
def
    { _gdClickReq :: [Int -> WidgetRequest s e]
_gdClickReq = [Int -> WidgetRequest s e
req]
    }