{-# language DeriveDataTypeable #-}
{-# language DeriveGeneric #-}
{-# language DeriveAnyClass #-}
{-# language PatternSynonyms #-}
{-# language TypeFamilies #-}
{-# language ViewPatterns #-}

module CodeWorld.Tasks.Picture (
  ReifyPicture,
  Picture(
    Rectangle,
    ThickRectangle,
    SolidRectangle,
    Circle,
    ThickCircle,
    SolidCircle,
    Arc,
    ThickArc,
    Sector,
    Polyline,
    ThickPolyline,
    Polygon,
    ThickPolygon,
    SolidPolygon,
    Curve,
    ThickCurve,
    ClosedCurve,
    ThickClosedCurve,
    SolidClosedCurve,
    Lettering,
    StyledLettering,
    Translate,
    Scale,
    Dilate,
    Color,
    Rotate,
    Reflect,
    Clip,
    And,
    Pictures,
    CoordinatePlane,
    Blank,
    Logo,

    AnyRectangle,
    AnyCircle,
    AnyArc,
    AnyPolyline,
    AnyCurve
  ),
  share,
  toInterface,
  innerPicture,
  hasInnerPicture,
  rectangle,
  thickRectangle,
  solidRectangle,
  circle,
  thickCircle,
  solidCircle,
  arc,
  sector,
  thickArc,
  curve,
  thickCurve,
  closedCurve,
  thickClosedCurve,
  solidClosedCurve,
  polyline,
  thickPolyline,
  polygon,
  thickPolygon,
  solidPolygon,
  lettering,
  styledLettering,
  colored,
  coloured,
  translated,
  scaled,
  dilated,
  rotated,
  reflected,
  clipped,
  pictures,
  (&),
  coordinatePlane,
  codeWorldLogo,
  blank,
  isIn,
  ) where


import Control.DeepSeq                  (NFData)
import Data.Data                        (Data)
import Data.Foldable                    (toList)
import Data.IntMap                      (IntMap, Key)
import Data.List.Extra                  (headDef)
import Data.Reify                       (Graph(..), MuRef(..), reifyGraph)
import Data.Text                        (Text)
import Data.Tuple.Extra                 (both)
import Data.Generics.Uniplate.Data      (children)
import GHC.Generics                     (Generic)
import qualified Data.IntMap            as IM
import qualified Data.Text              as T

import qualified CodeWorld.Tasks.API    as API
import qualified CodeWorld.Tasks.Types  as T
import CodeWorld.Tasks.Color            (Color)
import CodeWorld.Tasks.Types (
  Font,
  ReifyPicture,
  TextStyle,
  Shape(..),
  Style(..)
  )
import CodeWorld.Tasks.VectorSpace (
  Point,
  dilatedPoint,
  vectorDifference,
  rotatedPoint,
  crossProduct,
  dotProduct,
  scaledPoint,
  reflectedPoint,
  vectorLength
  )



{- |
Student facing, basic picture type.
A value of this type can be build using the CodeWorld API.

"CodeWorld.Test" also exports pattern synonyms for all contained constructors.
This allows for easier pattern matching in generic traversals.
-}
newtype Picture = PRec (ReifyPicture Picture)
  {- ^
  The recursive structure of the type is necessary
  for [Reify CSE detection](https://hackage.haskell.org/package/data-reify).
  -}
  deriving (Picture -> Picture -> Bool
(Picture -> Picture -> Bool)
-> (Picture -> Picture -> Bool) -> Eq Picture
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Picture -> Picture -> Bool
== :: Picture -> Picture -> Bool
$c/= :: Picture -> Picture -> Bool
/= :: Picture -> Picture -> Bool
Eq,Eq Picture
Eq Picture =>
(Picture -> Picture -> Ordering)
-> (Picture -> Picture -> Bool)
-> (Picture -> Picture -> Bool)
-> (Picture -> Picture -> Bool)
-> (Picture -> Picture -> Bool)
-> (Picture -> Picture -> Picture)
-> (Picture -> Picture -> Picture)
-> Ord Picture
Picture -> Picture -> Bool
Picture -> Picture -> Ordering
Picture -> Picture -> Picture
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
$ccompare :: Picture -> Picture -> Ordering
compare :: Picture -> Picture -> Ordering
$c< :: Picture -> Picture -> Bool
< :: Picture -> Picture -> Bool
$c<= :: Picture -> Picture -> Bool
<= :: Picture -> Picture -> Bool
$c> :: Picture -> Picture -> Bool
> :: Picture -> Picture -> Bool
$c>= :: Picture -> Picture -> Bool
>= :: Picture -> Picture -> Bool
$cmax :: Picture -> Picture -> Picture
max :: Picture -> Picture -> Picture
$cmin :: Picture -> Picture -> Picture
min :: Picture -> Picture -> Picture
Ord,(forall x. Picture -> Rep Picture x)
-> (forall x. Rep Picture x -> Picture) -> Generic Picture
forall x. Rep Picture x -> Picture
forall x. Picture -> Rep Picture x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Picture -> Rep Picture x
from :: forall x. Picture -> Rep Picture x
$cto :: forall x. Rep Picture x -> Picture
to :: forall x. Rep Picture x -> Picture
Generic,Picture -> ()
(Picture -> ()) -> NFData Picture
forall a. (a -> ()) -> NFData a
$crnf :: Picture -> ()
rnf :: Picture -> ()
NFData,Typeable Picture
Typeable Picture =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> Picture -> c Picture)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Picture)
-> (Picture -> Constr)
-> (Picture -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Picture))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Picture))
-> ((forall b. Data b => b -> b) -> Picture -> Picture)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Picture -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Picture -> r)
-> (forall u. (forall d. Data d => d -> u) -> Picture -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Picture -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Picture -> m Picture)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Picture -> m Picture)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Picture -> m Picture)
-> Data Picture
Picture -> Constr
Picture -> DataType
(forall b. Data b => b -> b) -> Picture -> Picture
forall a.
Typeable a =>
(forall (c :: * -> *).
 (forall d b. Data d => c (d -> b) -> d -> c b)
 -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Picture -> u
forall u. (forall d. Data d => d -> u) -> Picture -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Picture -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Picture -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Picture -> m Picture
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Picture -> m Picture
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Picture
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Picture -> c Picture
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Picture)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Picture)
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Picture -> c Picture
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Picture -> c Picture
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Picture
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Picture
$ctoConstr :: Picture -> Constr
toConstr :: Picture -> Constr
$cdataTypeOf :: Picture -> DataType
dataTypeOf :: Picture -> DataType
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Picture)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Picture)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Picture)
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Picture)
$cgmapT :: (forall b. Data b => b -> b) -> Picture -> Picture
gmapT :: (forall b. Data b => b -> b) -> Picture -> Picture
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Picture -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Picture -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Picture -> r
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Picture -> r
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Picture -> [u]
gmapQ :: forall u. (forall d. Data d => d -> u) -> Picture -> [u]
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Picture -> u
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Picture -> u
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Picture -> m Picture
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Picture -> m Picture
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Picture -> m Picture
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Picture -> m Picture
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Picture -> m Picture
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Picture -> m Picture
Data)

instance Show Picture where
  show :: Picture -> String
show (PRec ReifyPicture Picture
p) = ReifyPicture Picture -> String
forall a. Show a => a -> String
show ReifyPicture Picture
p


pattern Rectangle :: Double -> Double -> Picture
pattern $bRectangle :: Double -> Double -> Picture
$mRectangle :: forall {r}. Picture -> (Double -> Double -> r) -> ((# #) -> r) -> r
Rectangle x y = PRec (T.Rectangle (Outline Nothing) x y)

pattern ThickRectangle :: Double -> Double -> Double -> Picture
pattern $bThickRectangle :: Double -> Double -> Double -> Picture
$mThickRectangle :: forall {r}.
Picture -> (Double -> Double -> Double -> r) -> ((# #) -> r) -> r
ThickRectangle t x y = PRec (T.Rectangle (Outline (Just t)) x y)

pattern SolidRectangle :: Double -> Double -> Picture
pattern $bSolidRectangle :: Double -> Double -> Picture
$mSolidRectangle :: forall {r}. Picture -> (Double -> Double -> r) -> ((# #) -> r) -> r
SolidRectangle x y = PRec (T.Rectangle Solid x y)

pattern Circle :: Double -> Picture
pattern $bCircle :: Double -> Picture
$mCircle :: forall {r}. Picture -> (Double -> r) -> ((# #) -> r) -> r
Circle r = PRec (T.Circle (Outline Nothing) r)

pattern ThickCircle :: Double -> Double -> Picture
pattern $bThickCircle :: Double -> Double -> Picture
$mThickCircle :: forall {r}. Picture -> (Double -> Double -> r) -> ((# #) -> r) -> r
ThickCircle t r = PRec (T.Circle (Outline (Just t)) r)

pattern SolidCircle :: Double -> Picture
pattern $bSolidCircle :: Double -> Picture
$mSolidCircle :: forall {r}. Picture -> (Double -> r) -> ((# #) -> r) -> r
SolidCircle r = PRec (T.Circle Solid r)

pattern Polygon :: [Point] -> Picture
pattern $bPolygon :: [Point] -> Picture
$mPolygon :: forall {r}. Picture -> ([Point] -> r) -> ((# #) -> r) -> r
Polygon ps = PRec (T.Polyline (Closed (Outline Nothing)) ps)

pattern SolidPolygon :: [Point] -> Picture
pattern $bSolidPolygon :: [Point] -> Picture
$mSolidPolygon :: forall {r}. Picture -> ([Point] -> r) -> ((# #) -> r) -> r
SolidPolygon ps = PRec (T.Polyline (Closed Solid) ps)

pattern ThickPolygon :: Double -> [Point] -> Picture
pattern $bThickPolygon :: Double -> [Point] -> Picture
$mThickPolygon :: forall {r}.
Picture -> (Double -> [Point] -> r) -> ((# #) -> r) -> r
ThickPolygon t ps = PRec (T.Polyline (Closed (Outline (Just t))) ps)

pattern Polyline :: [Point] -> Picture
pattern $bPolyline :: [Point] -> Picture
$mPolyline :: forall {r}. Picture -> ([Point] -> r) -> ((# #) -> r) -> r
Polyline ps = PRec (T.Polyline (Open Nothing) ps)

pattern ThickPolyline :: Double -> [Point] -> Picture
pattern $bThickPolyline :: Double -> [Point] -> Picture
$mThickPolyline :: forall {r}.
Picture -> (Double -> [Point] -> r) -> ((# #) -> r) -> r
ThickPolyline t ps = PRec (T.Polyline (Open (Just t)) ps)

pattern Sector :: Double -> Double -> Double -> Picture
pattern $bSector :: Double -> Double -> Double -> Picture
$mSector :: forall {r}.
Picture -> (Double -> Double -> Double -> r) -> ((# #) -> r) -> r
Sector a1 a2 r = PRec (T.Arc Solid a1 a2 r)

pattern Arc :: Double -> Double -> Double -> Picture
pattern $bArc :: Double -> Double -> Double -> Picture
$mArc :: forall {r}.
Picture -> (Double -> Double -> Double -> r) -> ((# #) -> r) -> r
Arc a1 a2 r = PRec (T.Arc (Outline Nothing) a1 a2 r)

pattern ThickArc :: Double -> Double -> Double -> Double -> Picture
pattern $bThickArc :: Double -> Double -> Double -> Double -> Picture
$mThickArc :: forall {r}.
Picture
-> (Double -> Double -> Double -> Double -> r) -> ((# #) -> r) -> r
ThickArc t a1 a2 r = PRec (T.Arc (Outline (Just t)) a1 a2 r)

pattern Curve :: [Point] -> Picture
pattern $bCurve :: [Point] -> Picture
$mCurve :: forall {r}. Picture -> ([Point] -> r) -> ((# #) -> r) -> r
Curve ps = PRec (T.Curve (Open Nothing) ps)

pattern ThickCurve :: Double -> [Point] -> Picture
pattern $bThickCurve :: Double -> [Point] -> Picture
$mThickCurve :: forall {r}.
Picture -> (Double -> [Point] -> r) -> ((# #) -> r) -> r
ThickCurve t ps = PRec (T.Curve (Open (Just t)) ps)

pattern ClosedCurve :: [Point] -> Picture
pattern $bClosedCurve :: [Point] -> Picture
$mClosedCurve :: forall {r}. Picture -> ([Point] -> r) -> ((# #) -> r) -> r
ClosedCurve ps = PRec (T.Curve (Closed (Outline Nothing)) ps)

pattern SolidClosedCurve :: [Point] -> Picture
pattern $bSolidClosedCurve :: [Point] -> Picture
$mSolidClosedCurve :: forall {r}. Picture -> ([Point] -> r) -> ((# #) -> r) -> r
SolidClosedCurve ps = PRec (T.Curve (Closed Solid)ps)

pattern ThickClosedCurve :: Double -> [Point] -> Picture
pattern $bThickClosedCurve :: Double -> [Point] -> Picture
$mThickClosedCurve :: forall {r}.
Picture -> (Double -> [Point] -> r) -> ((# #) -> r) -> r
ThickClosedCurve t ps = PRec (T.Curve (Closed (Outline (Just t))) ps)

pattern Lettering :: Text -> Picture
pattern $bLettering :: Text -> Picture
$mLettering :: forall {r}. Picture -> (Text -> r) -> ((# #) -> r) -> r
Lettering t = PRec (T.Lettering t)

pattern StyledLettering :: TextStyle -> Font -> Text -> Picture
pattern $bStyledLettering :: TextStyle -> Font -> Text -> Picture
$mStyledLettering :: forall {r}.
Picture -> (TextStyle -> Font -> Text -> r) -> ((# #) -> r) -> r
StyledLettering ts f t = PRec (T.StyledLettering ts f t)

pattern Color :: Color -> Picture -> Picture
pattern $bColor :: Color -> Picture -> Picture
$mColor :: forall {r}. Picture -> (Color -> Picture -> r) -> ((# #) -> r) -> r
Color c p = PRec (T.Color c p)

pattern Translate :: Double -> Double -> Picture -> Picture
pattern $bTranslate :: Double -> Double -> Picture -> Picture
$mTranslate :: forall {r}.
Picture -> (Double -> Double -> Picture -> r) -> ((# #) -> r) -> r
Translate x y p = PRec (T.Translate x y p)

pattern Scale :: Double -> Double -> Picture -> Picture
pattern $bScale :: Double -> Double -> Picture -> Picture
$mScale :: forall {r}.
Picture -> (Double -> Double -> Picture -> r) -> ((# #) -> r) -> r
Scale fac1 fac2 p = PRec (T.Scale fac1 fac2 p)

pattern Dilate :: Double -> Picture -> Picture
pattern $bDilate :: Double -> Picture -> Picture
$mDilate :: forall {r}.
Picture -> (Double -> Picture -> r) -> ((# #) -> r) -> r
Dilate fac p = PRec (T.Dilate fac p)

pattern Rotate :: Double -> Picture -> Picture
pattern $bRotate :: Double -> Picture -> Picture
$mRotate :: forall {r}.
Picture -> (Double -> Picture -> r) -> ((# #) -> r) -> r
Rotate a p = PRec (T.Rotate a p)

pattern Reflect :: Double -> Picture -> Picture
pattern $bReflect :: Double -> Picture -> Picture
$mReflect :: forall {r}.
Picture -> (Double -> Picture -> r) -> ((# #) -> r) -> r
Reflect a p = PRec (T.Reflect a p)

pattern Clip :: Double -> Double -> Picture -> Picture
pattern $bClip :: Double -> Double -> Picture -> Picture
$mClip :: forall {r}.
Picture -> (Double -> Double -> Picture -> r) -> ((# #) -> r) -> r
Clip x y p = PRec (T.Clip x y p)

pattern Pictures :: [Picture] -> Picture
pattern $bPictures :: [Picture] -> Picture
$mPictures :: forall {r}. Picture -> ([Picture] -> r) -> ((# #) -> r) -> r
Pictures ps = PRec (T.Pictures ps)

pattern And :: Picture -> Picture -> Picture
pattern $bAnd :: Picture -> Picture -> Picture
$mAnd :: forall {r}.
Picture -> (Picture -> Picture -> r) -> ((# #) -> r) -> r
And p1 p2 = PRec (T.And p1 p2)

pattern CoordinatePlane :: Picture
pattern $bCoordinatePlane :: Picture
$mCoordinatePlane :: forall {r}. Picture -> ((# #) -> r) -> ((# #) -> r) -> r
CoordinatePlane = PRec T.CoordinatePlane

pattern Logo :: Picture
pattern  = PRec T.Logo

pattern Blank :: Picture
pattern $bBlank :: Picture
$mBlank :: forall {r}. Picture -> ((# #) -> r) -> ((# #) -> r) -> r
Blank = PRec T.Blank

-- Tells the compiler that covering these patterns is exhaustive in a pattern match
{-# COMPLETE
  Rectangle,
  ThickRectangle,
  SolidRectangle,
  Circle,
  ThickCircle,
  SolidCircle,
  Arc,
  ThickArc,
  Sector,
  Polyline,
  ThickPolyline,
  Polygon,
  ThickPolygon,
  SolidPolygon,
  Curve,
  ThickCurve,
  ClosedCurve,
  ThickClosedCurve,
  SolidClosedCurve,
  Lettering,
  StyledLettering,
  Translate,
  Scale,
  Dilate,
  Color,
  Rotate,
  Reflect,
  Clip,
  And,
  Pictures,
  CoordinatePlane,
  Blank,
  Logo
  #-}

-- For internal use
pattern AnyRectangle :: Style -> Double -> Double -> Picture
pattern $bAnyRectangle :: Style -> Double -> Double -> Picture
$mAnyRectangle :: forall {r}.
Picture -> (Style -> Double -> Double -> r) -> ((# #) -> r) -> r
AnyRectangle s x y = PRec (T.Rectangle s x y)

pattern AnyCircle :: Style -> Double -> Picture
pattern $bAnyCircle :: Style -> Double -> Picture
$mAnyCircle :: forall {r}. Picture -> (Style -> Double -> r) -> ((# #) -> r) -> r
AnyCircle s r = PRec (T.Circle s r)

pattern AnyArc :: Style -> Double -> Double-> Double -> Picture
pattern $bAnyArc :: Style -> Double -> Double -> Double -> Picture
$mAnyArc :: forall {r}.
Picture
-> (Style -> Double -> Double -> Double -> r) -> ((# #) -> r) -> r
AnyArc s a1 a2 r = PRec (T.Arc s a1 a2 r)

pattern AnyPolyline :: Shape -> [Point] -> Picture
pattern $bAnyPolyline :: Shape -> [Point] -> Picture
$mAnyPolyline :: forall {r}. Picture -> (Shape -> [Point] -> r) -> ((# #) -> r) -> r
AnyPolyline s ps = PRec (T.Polyline s ps)

pattern AnyCurve :: Shape -> [Point] -> Picture
pattern $bAnyCurve :: Shape -> [Point] -> Picture
$mAnyCurve :: forall {r}. Picture -> (Shape -> [Point] -> r) -> ((# #) -> r) -> r
AnyCurve s ps = PRec (T.Curve s ps)

{-# COMPLETE
  AnyRectangle,
  AnyCircle,
  AnyArc,
  AnyPolyline,
  AnyCurve,
  Lettering,
  StyledLettering,
  Translate,
  Scale,
  Dilate,
  Color,
  Rotate,
  Reflect,
  Clip,
  And,
  Pictures,
  CoordinatePlane,
  Blank,
  Logo
  #-}


{-|
Draw a hollow, thin rectangle with this length and height.
-}
rectangle :: Double -> Double -> Picture
rectangle :: Double -> Double -> Picture
rectangle = Double -> Double -> Picture
Rectangle

{-|
Draw a hollow rectangle with this line width, length and height.
Specifying a negative line width causes a runtime error (mirrors behaviour in CodeWorld editor).
-}
thickRectangle :: Double -> Double -> Double -> Picture
thickRectangle :: Double -> Double -> Double -> Picture
thickRectangle (Double -> Double
validThickness -> Double
t) = Double -> Double -> Double -> Picture
ThickRectangle Double
t

{-|
Draw a filled in rectangle with this length and height.
-}
solidRectangle :: Double -> Double -> Picture
solidRectangle :: Double -> Double -> Picture
solidRectangle = Double -> Double -> Picture
SolidRectangle

{-|
Draw a hollow, thin circle with this radius.
-}
circle :: Double -> Picture
circle :: Double -> Picture
circle = Double -> Picture
Circle

{-|
Draw a hollow circle with this line width and radius.
Specifying a negative line width or a line width greater than the circles diameter
causes a runtime error (mirrors behaviour in CodeWorld editor).
-}
thickCircle :: Double -> Double -> Picture
thickCircle :: Double -> Double -> Picture
thickCircle (Double -> Double
validThickness -> Double
t) Double
r
  | Double
t Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<= Double
2 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double -> Double
forall a. Num a => a -> a
abs Double
r = Double -> Double -> Picture
ThickCircle Double
t Double
r
  | Bool
otherwise  = String -> Picture
forall a. HasCallStack => String -> a
error String
"The line width of a thickCircle must not be greater than the diameter."

{-|
Draw a filled in circle with this radius.
-}
solidCircle :: Double -> Picture
solidCircle :: Double -> Picture
solidCircle = Double -> Picture
SolidCircle

{-|
Draw a thin, hollow circle segment with these start and end angles and radius.
-}
arc :: Double -> Double -> Double -> Picture
arc :: Double -> Double -> Double -> Picture
arc = Double -> Double -> Double -> Picture
Arc

{-|
Draw a filled in circle segment with these start and end angles and radius.
This would be @solidArc@ following the usual naming scheme.
-}
sector :: Double -> Double -> Double -> Picture
sector :: Double -> Double -> Double -> Picture
sector = Double -> Double -> Double -> Picture
Sector

{-|
Draw a hollow circle segment with this line width, these start and end angles and radius.
Specifying a negative line width causes a runtime error (mirrors behaviour in CodeWorld editor).
-}
thickArc :: Double -> Double -> Double -> Double -> Picture
thickArc :: Double -> Double -> Double -> Double -> Picture
thickArc (Double -> Double
validThickness -> Double
t) = Double -> Double -> Double -> Double -> Picture
ThickArc Double
t

{-|
Draw a thin curve passing through the provided points via a number of Bézier splices.
-}
curve :: [Point] -> Picture
curve :: [Point] -> Picture
curve = [Point] -> Picture
Curve

{-|
Draw a curve with this line width passing through the provided points via a number of Bézier splices.
Specifying a negative line width causes a runtime error (mirrors behaviour in CodeWorld editor).
-}
thickCurve :: Double -> [Point] -> Picture
thickCurve :: Double -> [Point] -> Picture
thickCurve (Double -> Double
validThickness -> Double
t) = Double -> [Point] -> Picture
ThickCurve Double
t

{-|
Same as `curve` but adds another splice between the start and end points to close the shape.
-}
closedCurve :: [Point] -> Picture
closedCurve :: [Point] -> Picture
closedCurve = [Point] -> Picture
ClosedCurve

{-|
Same as `thickCurve` but adds another splice between the start and end points to close the shape.
-}
thickClosedCurve :: Double -> [Point] -> Picture
thickClosedCurve :: Double -> [Point] -> Picture
thickClosedCurve (Double -> Double
validThickness -> Double
t) = Double -> [Point] -> Picture
ThickClosedCurve Double
t

{-|
Draw a curve passing through the provided points via a number of Bézier splices.
Adds another splice between the start and end points to close the shape and completely fills the enclosed area.
-}
solidClosedCurve :: [Point] -> Picture
solidClosedCurve :: [Point] -> Picture
solidClosedCurve = [Point] -> Picture
SolidClosedCurve

{-|
Draw a sequence of thin line segments passing through the provided points.
-}
polyline :: [Point] -> Picture
polyline :: [Point] -> Picture
polyline = [Point] -> Picture
Polyline

{-|
Draw a sequence of line segments with this line width passing through the provided points.
Specifying a negative line width causes a runtime error (mirrors behaviour in CodeWorld editor).
-}
thickPolyline :: Double -> [Point] -> Picture
thickPolyline :: Double -> [Point] -> Picture
thickPolyline (Double -> Double
validThickness -> Double
t) = Double -> [Point] -> Picture
ThickPolyline Double
t

{-|
Same as `polyline` but adds another segment between the start and end points to close the shape.
-}
polygon :: [Point] -> Picture
polygon :: [Point] -> Picture
polygon = [Point] -> Picture
Polygon

{-|
Same as `thickPolyline` but adds another segment between the start and end points to close the shape.
-}
thickPolygon :: Double -> [Point] -> Picture
thickPolygon :: Double -> [Point] -> Picture
thickPolygon (Double -> Double
validThickness -> Double
t) = Double -> [Point] -> Picture
ThickPolygon Double
t

{-|
Draw a sequence of line segments with this line width passing through the provided points
and completely fill the enclosed area.
-}
solidPolygon :: [Point] -> Picture
solidPolygon :: [Point] -> Picture
solidPolygon = [Point] -> Picture
SolidPolygon

{-|
Render this text into an image.
-}
lettering :: Text -> Picture
lettering :: Text -> Picture
lettering = Text -> Picture
Lettering

{-|
Render this text into an image using the provided `TextStyle` and `Font`.
-}
styledLettering :: TextStyle -> Font -> Text -> Picture
styledLettering :: TextStyle -> Font -> Text -> Picture
styledLettering = TextStyle -> Font -> Text -> Picture
StyledLettering

{-|
Apply this `Color` to the image.
-}
colored :: Color -> Picture -> Picture
colored :: Color -> Picture -> Picture
colored = Color -> Picture -> Picture
Color

{-|
Alias for `colored`.
-}
coloured :: Color -> Picture -> Picture
coloured :: Color -> Picture -> Picture
coloured = Color -> Picture -> Picture
colored

{-|
Move the image in x and y-direction.
-}
translated :: Double -> Double -> Picture -> Picture
translated :: Double -> Double -> Picture -> Picture
translated = Double -> Double -> Picture -> Picture
Translate

{-|
Scale the image in x and y-directions using these modifiers.
-}
scaled :: Double -> Double -> Picture -> Picture
scaled :: Double -> Double -> Picture -> Picture
scaled= Double -> Double -> Picture -> Picture
Scale

{-|
Scale the image in both directions using the same modifier.
-}
dilated :: Double -> Picture -> Picture
dilated :: Double -> Picture -> Picture
dilated = Double -> Picture -> Picture
Dilate

{-|
Rotate the image around the origin using this angle in radians.
-}
rotated :: Double -> Picture -> Picture
rotated :: Double -> Picture -> Picture
rotated = Double -> Picture -> Picture
Rotate

{-|
Reflect the image across a line through the origin with this angle to the x-axis.
-}
reflected :: Double -> Picture -> Picture
reflected :: Double -> Picture -> Picture
reflected = Double -> Picture -> Picture
Reflect

{-|
Clip the image in a rectangle with this length and height.
-}
clipped :: Double -> Double -> Picture -> Picture
clipped :: Double -> Double -> Picture -> Picture
clipped = Double -> Double -> Picture -> Picture
Clip

{-|
Compose a list of `Picture`s.
Equivalent to @foldr (&) blank@.
-}
pictures :: [Picture] -> Picture
pictures :: [Picture] -> Picture
pictures = [Picture] -> Picture
Pictures

{-|
Compose two `Picture`s.
The left argument will be drawn on top of the right argument if they overlap.
-}
(&) :: Picture -> Picture -> Picture
Picture
a & :: Picture -> Picture -> Picture
& Picture
b = Picture -> Picture -> Picture
And Picture
a Picture
b

{-|
A static image of a coordinate plane extending 5 units in all directions.
-}
coordinatePlane :: Picture
coordinatePlane :: Picture
coordinatePlane = Picture
CoordinatePlane

{-|
A static image of the CodeWorld logo.
-}
codeWorldLogo :: Picture
 = Picture
Logo

{-|
An empty `Picture`.
This is the identity element of `&`.
-}
blank :: Picture
blank :: Picture
blank = Picture
Blank


instance MuRef Picture where
  type DeRef Picture = ReifyPicture
  -- above pattern synonyms are not useable here.
  -- ReifyPicture's type variable needs to be free.
  mapDeRef :: forall (f :: * -> *) u.
Applicative f =>
(forall b. (MuRef b, DeRef Picture ~ DeRef b) => b -> f u)
-> Picture -> f (DeRef Picture u)
mapDeRef forall b. (MuRef b, DeRef Picture ~ DeRef b) => b -> f u
f (PRec ReifyPicture Picture
body) = case ReifyPicture Picture
body of
    T.Color Color
c Picture
p             -> Color -> u -> ReifyPicture u
forall a. Color -> a -> ReifyPicture a
T.Color Color
c (u -> ReifyPicture u) -> f u -> f (ReifyPicture u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Picture -> f u
forall b. (MuRef b, DeRef Picture ~ DeRef b) => b -> f u
f Picture
p
    T.Translate Double
x Double
y Picture
p       -> Double -> Double -> u -> ReifyPicture u
forall a. Double -> Double -> a -> ReifyPicture a
T.Translate Double
x Double
y (u -> ReifyPicture u) -> f u -> f (ReifyPicture u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Picture -> f u
forall b. (MuRef b, DeRef Picture ~ DeRef b) => b -> f u
f Picture
p
    T.Scale Double
x Double
y Picture
p           -> Double -> Double -> u -> ReifyPicture u
forall a. Double -> Double -> a -> ReifyPicture a
T.Scale Double
x Double
y (u -> ReifyPicture u) -> f u -> f (ReifyPicture u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Picture -> f u
forall b. (MuRef b, DeRef Picture ~ DeRef b) => b -> f u
f Picture
p
    T.Dilate Double
x Picture
p            -> Double -> u -> ReifyPicture u
forall a. Double -> a -> ReifyPicture a
T.Dilate Double
x (u -> ReifyPicture u) -> f u -> f (ReifyPicture u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Picture -> f u
forall b. (MuRef b, DeRef Picture ~ DeRef b) => b -> f u
f Picture
p
    T.Rotate Double
a Picture
p            -> Double -> u -> ReifyPicture u
forall a. Double -> a -> ReifyPicture a
T.Rotate Double
a (u -> ReifyPicture u) -> f u -> f (ReifyPicture u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Picture -> f u
forall b. (MuRef b, DeRef Picture ~ DeRef b) => b -> f u
f Picture
p
    T.Reflect Double
a Picture
p           -> Double -> u -> ReifyPicture u
forall a. Double -> a -> ReifyPicture a
T.Reflect Double
a (u -> ReifyPicture u) -> f u -> f (ReifyPicture u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Picture -> f u
forall b. (MuRef b, DeRef Picture ~ DeRef b) => b -> f u
f Picture
p
    T.Clip Double
x Double
y Picture
p            -> Double -> Double -> u -> ReifyPicture u
forall a. Double -> Double -> a -> ReifyPicture a
T.Clip Double
x Double
y (u -> ReifyPicture u) -> f u -> f (ReifyPicture u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Picture -> f u
forall b. (MuRef b, DeRef Picture ~ DeRef b) => b -> f u
f Picture
p
    T.And Picture
a Picture
b               -> u -> u -> ReifyPicture u
forall a. a -> a -> ReifyPicture a
T.And (u -> u -> ReifyPicture u) -> f u -> f (u -> ReifyPicture u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Picture -> f u
forall b. (MuRef b, DeRef Picture ~ DeRef b) => b -> f u
f Picture
a f (u -> ReifyPicture u) -> f u -> f (ReifyPicture u)
forall a b. f (a -> b) -> f a -> f b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Picture -> f u
forall b. (MuRef b, DeRef Picture ~ DeRef b) => b -> f u
f Picture
b
    T.Pictures [Picture]
ps           -> [u] -> ReifyPicture u
forall a. [a] -> ReifyPicture a
T.Pictures ([u] -> ReifyPicture u) -> f [u] -> f (ReifyPicture u)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Picture -> f u) -> [Picture] -> f [u]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Picture -> f u
forall b. (MuRef b, DeRef Picture ~ DeRef b) => b -> f u
f [Picture]
ps
    ReifyPicture Picture
p                     -> DeRef Picture u -> f (DeRef Picture u)
forall a. a -> f a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (DeRef Picture u -> f (DeRef Picture u))
-> DeRef Picture u -> f (DeRef Picture u)
forall a b. (a -> b) -> a -> b
$ case ReifyPicture Picture
p of
      T.Rectangle Style
s Double
x Double
y       -> Style -> Double -> Double -> ReifyPicture u
forall a. Style -> Double -> Double -> ReifyPicture a
T.Rectangle Style
s Double
x Double
y
      T.Circle Style
s Double
r              -> Style -> Double -> ReifyPicture u
forall a. Style -> Double -> ReifyPicture a
T.Circle Style
s Double
r
      T.Lettering Text
t           -> Text -> ReifyPicture u
forall a. Text -> ReifyPicture a
T.Lettering Text
t
      T.StyledLettering TextStyle
s Font
w Text
t -> TextStyle -> Font -> Text -> ReifyPicture u
forall a. TextStyle -> Font -> Text -> ReifyPicture a
T.StyledLettering TextStyle
s Font
w Text
t
      T.Curve Shape
s [Point]
xs              -> Shape -> [Point] -> ReifyPicture u
forall a. Shape -> [Point] -> ReifyPicture a
T.Curve Shape
s [Point]
xs
      T.Polyline Shape
s [Point]
xs           -> Shape -> [Point] -> ReifyPicture u
forall a. Shape -> [Point] -> ReifyPicture a
T.Polyline Shape
s [Point]
xs
      T.Arc Style
s Double
a1 Double
a2 Double
r           -> Style -> Double -> Double -> Double -> ReifyPicture u
forall a. Style -> Double -> Double -> Double -> ReifyPicture a
T.Arc Style
s Double
a1 Double
a2 Double
r
      ReifyPicture Picture
T.CoordinatePlane       -> ReifyPicture u
DeRef Picture u
forall a. ReifyPicture a
T.CoordinatePlane
      ReifyPicture Picture
T.Logo                  -> ReifyPicture u
DeRef Picture u
forall a. ReifyPicture a
T.Logo
      ReifyPicture Picture
T.Blank                 -> ReifyPicture u
DeRef Picture u
forall a. ReifyPicture a
T.Blank


share :: Picture -> IO (IntMap (ReifyPicture Int), IntMap (ReifyPicture Int))
share :: Picture
-> IO (IntMap (ReifyPicture Int), IntMap (ReifyPicture Int))
share Picture
d = do
  Graph nodes s <- Picture -> IO (Graph (DeRef Picture))
forall s. MuRef s => s -> IO (Graph (DeRef s))
reifyGraph Picture
d
  let universe = [(Int, ReifyPicture Int)] -> IntMap (ReifyPicture Int)
forall a. [(Int, a)] -> IntMap a
IM.fromList [(Int, ReifyPicture Int)]
nodes
      refs = (Int -> Int -> Int) -> Int -> Int -> IntMap Int -> IntMap Int
forall a. (a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
IM.insertWith Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) Int
s Int
1 (IntMap Int -> IntMap Int) -> IntMap Int -> IntMap Int
forall a b. (a -> b) -> a -> b
$ ((Int, ReifyPicture Int) -> IntMap Int -> IntMap Int)
-> IntMap Int -> [(Int, ReifyPicture Int)] -> IntMap Int
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ([Int] -> IntMap Int -> IntMap Int
mapInsertWith ([Int] -> IntMap Int -> IntMap Int)
-> ((Int, ReifyPicture Int) -> [Int])
-> (Int, ReifyPicture Int)
-> IntMap Int
-> IntMap Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ReifyPicture Int -> [Int]
forall a. ReifyPicture a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (ReifyPicture Int -> [Int])
-> ((Int, ReifyPicture Int) -> ReifyPicture Int)
-> (Int, ReifyPicture Int)
-> [Int]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, ReifyPicture Int) -> ReifyPicture Int
forall a b. (a, b) -> b
snd) IntMap Int
forall a. Monoid a => a
mempty [(Int, ReifyPicture Int)]
nodes
      multiRefs = IntMap (ReifyPicture Int)
-> IntMap Int -> IntMap (ReifyPicture Int)
forall a b. IntMap a -> IntMap b -> IntMap a
IM.intersection IntMap (ReifyPicture Int)
universe (IntMap Int -> IntMap (ReifyPicture Int))
-> IntMap Int -> IntMap (ReifyPicture Int)
forall a b. (a -> b) -> a -> b
$ (Int -> Bool) -> IntMap Int -> IntMap Int
forall a. (a -> Bool) -> IntMap a -> IntMap a
IM.filter (Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>Int
1) IntMap Int
refs
      lut = IntMap (ReifyPicture Int)
-> IntMap Int -> IntMap (ReifyPicture Int)
forall a b. IntMap a -> IntMap b -> IntMap a
IM.intersection IntMap (ReifyPicture Int)
universe IntMap Int
refs
  pure (multiRefs, lut)


mapInsertWith :: [Key] -> IntMap Int -> IntMap Int
mapInsertWith :: [Int] -> IntMap Int -> IntMap Int
mapInsertWith [Int]
b IntMap Int
m = (Int -> IntMap Int -> IntMap Int)
-> IntMap Int -> [Int] -> IntMap Int
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
Prelude.foldr (\Int
x IntMap Int
acc-> (Int -> Int -> Int) -> Int -> Int -> IntMap Int -> IntMap Int
forall a. (a -> a -> a) -> Int -> a -> IntMap a -> IntMap a
IM.insertWith Int -> Int -> Int
forall a. Num a => a -> a -> a
(+) Int
x (Int
1 :: Int) IntMap Int
acc) IntMap Int
m [Int]
b


toInterface :: API.Drawable a => Picture -> a
toInterface :: forall a. Drawable a => Picture -> a
toInterface Picture
p = case Picture
p of
  Rectangle Double
x Double
y -> Double -> Double -> a
forall a. Drawable a => Double -> Double -> a
API.rectangle Double
x Double
y
  ThickRectangle Double
t Double
x Double
y -> Double -> Double -> Double -> a
forall a. Drawable a => Double -> Double -> Double -> a
API.thickRectangle Double
t Double
x Double
y
  SolidRectangle Double
x Double
y -> Double -> Double -> a
forall a. Drawable a => Double -> Double -> a
API.solidRectangle Double
x Double
y
  Circle Double
r -> Double -> a
forall a. Drawable a => Double -> a
API.circle Double
r
  ThickCircle Double
t Double
r -> Double -> Double -> a
forall a. Drawable a => Double -> Double -> a
API.thickCircle Double
t Double
r
  SolidCircle Double
r -> Double -> a
forall a. Drawable a => Double -> a
API.solidCircle Double
r
  Polygon [Point]
ps -> [Point] -> a
forall a. Drawable a => [Point] -> a
API.polygon [Point]
ps
  SolidPolygon [Point]
ps -> [Point] -> a
forall a. Drawable a => [Point] -> a
API.solidPolygon [Point]
ps
  ThickPolygon Double
t [Point]
ps -> Double -> [Point] -> a
forall a. Drawable a => Double -> [Point] -> a
API.thickPolygon Double
t [Point]
ps
  ClosedCurve [Point]
ps -> [Point] -> a
forall a. Drawable a => [Point] -> a
API.closedCurve [Point]
ps
  SolidClosedCurve [Point]
ps -> [Point] -> a
forall a. Drawable a => [Point] -> a
API.solidClosedCurve [Point]
ps
  ThickClosedCurve Double
t [Point]
ps -> Double -> [Point] -> a
forall a. Drawable a => Double -> [Point] -> a
API.thickClosedCurve Double
t [Point]
ps
  Polyline [Point]
ps -> [Point] -> a
forall a. Drawable a => [Point] -> a
API.polyline [Point]
ps
  ThickPolyline Double
t [Point]
ps -> Double -> [Point] -> a
forall a. Drawable a => Double -> [Point] -> a
API.thickPolyline Double
t [Point]
ps
  Curve [Point]
ps -> [Point] -> a
forall a. Drawable a => [Point] -> a
API.curve [Point]
ps
  ThickCurve Double
t [Point]
ps -> Double -> [Point] -> a
forall a. Drawable a => Double -> [Point] -> a
API.thickCurve Double
t [Point]
ps
  Sector Double
a1 Double
a2 Double
r -> Double -> Double -> Double -> a
forall a. Drawable a => Double -> Double -> Double -> a
API.sector Double
a1 Double
a2 Double
r
  Arc Double
a1 Double
a2 Double
r -> Double -> Double -> Double -> a
forall a. Drawable a => Double -> Double -> Double -> a
API.arc Double
a1 Double
a2 Double
r
  ThickArc Double
t Double
a1 Double
a2 Double
r -> Double -> Double -> Double -> Double -> a
forall a. Drawable a => Double -> Double -> Double -> Double -> a
API.thickArc Double
t Double
a1 Double
a2 Double
r
  Lettering Text
t -> Text -> a
forall a. Drawable a => Text -> a
API.lettering Text
t
  StyledLettering TextStyle
ts Font
f Text
t -> TextStyle -> Font -> Text -> a
forall a. Drawable a => TextStyle -> Font -> Text -> a
API.styledLettering TextStyle
ts Font
f Text
t
  Color Color
c Picture
q -> Color -> a -> a
forall a. Drawable a => Color -> a -> a
API.colored Color
c (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Picture -> a
forall a. Drawable a => Picture -> a
toInterface Picture
q
  Translate Double
x Double
y Picture
q -> Double -> Double -> a -> a
forall a. Drawable a => Double -> Double -> a -> a
API.translated Double
x Double
y (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Picture -> a
forall a. Drawable a => Picture -> a
toInterface Picture
q
  Scale Double
x Double
y Picture
q -> Double -> Double -> a -> a
forall a. Drawable a => Double -> Double -> a -> a
API.scaled Double
x Double
y (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Picture -> a
forall a. Drawable a => Picture -> a
toInterface Picture
q
  Dilate Double
fac Picture
q -> Double -> a -> a
forall a. Drawable a => Double -> a -> a
API.dilated Double
fac (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Picture -> a
forall a. Drawable a => Picture -> a
toInterface Picture
q
  Rotate Double
a Picture
q -> Double -> a -> a
forall a. Drawable a => Double -> a -> a
API.rotated Double
a (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Picture -> a
forall a. Drawable a => Picture -> a
toInterface Picture
q
  Reflect Double
a Picture
q -> Double -> a -> a
forall a. Drawable a => Double -> a -> a
API.reflected Double
a (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Picture -> a
forall a. Drawable a => Picture -> a
toInterface Picture
q
  Clip Double
x Double
y Picture
q -> Double -> Double -> a -> a
forall a. Drawable a => Double -> Double -> a -> a
API.clipped Double
x Double
y (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ Picture -> a
forall a. Drawable a => Picture -> a
toInterface Picture
q
  Pictures [Picture]
ps -> [a] -> a
forall a. Drawable a => [a] -> a
API.pictures ([a] -> a) -> [a] -> a
forall a b. (a -> b) -> a -> b
$ (Picture -> a) -> [Picture] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map Picture -> a
forall a. Drawable a => Picture -> a
toInterface [Picture]
ps
  And Picture
p1 Picture
p2 -> Picture -> a
forall a. Drawable a => Picture -> a
toInterface Picture
p1 a -> a -> a
forall a. Drawable a => a -> a -> a
API.& Picture -> a
forall a. Drawable a => Picture -> a
toInterface Picture
p2
  Picture
CoordinatePlane -> a
forall a. Drawable a => a
API.coordinatePlane
  Picture
Logo -> a
forall a. Drawable a => a
API.codeWorldLogo
  Picture
Blank -> a
forall a. Drawable a => a
API.blank


{-
The next two functions should never be used on `And` or `Pictures` for this to make any sense.
This is currently the case, but could be problematic if this is used on non-reduced trees
where those constructors could appear somewhere inside the structure.
TODO: Change return type to [Picture] and adjust the tests.
-}

{- |
Returns the contained `Picture` if the argument is not a basic shape and the argument itself if it is.

__Warning: This is intended to be used on non-composite pictures only.__
`Pictures` and `And` will be treated as a basic picture (i.e. the function will behave like `id`)
if used as an argument.
-}
innerPicture :: Picture -> Picture
innerPicture :: Picture -> Picture
innerPicture p :: Picture
p@(Pictures {}) = Picture
p
innerPicture p :: Picture
p@(And {})      = Picture
p
innerPicture Picture
p               = Picture -> [Picture] -> Picture
forall a. a -> [a] -> a
headDef Picture
p ([Picture] -> Picture) -> [Picture] -> Picture
forall a b. (a -> b) -> a -> b
$ Picture -> [Picture]
forall on. Uniplate on => on -> [on]
children Picture
p

{- |
Returns `True` if the argument is not a basic shape.

__Warning: This is intended to be used on non-composite pictures only.__
`Pictures` and `And` will be treated as a basic picture (i.e. returning `False`) if used as an argument.
-}
hasInnerPicture :: Picture -> Bool
hasInnerPicture :: Picture -> Bool
hasInnerPicture (Pictures {}) = Bool
False
hasInnerPicture (And {})      = Bool
False
hasInnerPicture Picture
p             = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ [Picture] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Picture] -> Bool) -> [Picture] -> Bool
forall a b. (a -> b) -> a -> b
$ Picture -> [Picture]
forall on. Uniplate on => on -> [on]
children Picture
p


{- |
Checks if the argument is contained completely inside a box.
The coordinates of the box are given as two points with the following format:

  1. (minimum x-value, maximum x-value)
  2. (minimum y-value, maximum y-value)
-}
isIn :: Picture -> (Point,Point) -> Bool
isIn :: Picture -> (Point, Point) -> Bool
isIn Picture
pic ((Double
lowerX, Double
upperX), (Double
lowerY, Double
upperY)) =
  Picture -> (Point, Point, Point, Point) -> Bool
handle Picture
pic ((Double
lowerX,Double
lowerY),(Double
lowerX,Double
upperY),(Double
upperX,Double
upperY),(Double
upperX,Double
lowerY))

handle :: Picture -> (Point,Point,Point,Point) -> Bool
handle :: Picture -> (Point, Point, Point, Point) -> Bool
handle Picture
p corners :: (Point, Point, Point, Point)
corners@(Point
a,Point
b,Point
c,Point
d) = case Picture
p of
  Rectangle Double
x Double
y -> Double -> Double -> Bool
rectangleCheck Double
x Double
y
  ThickRectangle Double
t Double
x Double
y -> Double -> Double -> Bool
rectangleCheck (Double
xDouble -> Double -> Double
forall a. Num a => a -> a -> a
+Double
tDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2) (Double
yDouble -> Double -> Double
forall a. Num a => a -> a -> a
+Double
tDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2)
  SolidRectangle Double
x Double
y -> Double -> Double -> Bool
rectangleCheck Double
x Double
y
  Circle Double
r -> Double -> Bool
circleCheck Double
r
  ThickCircle Double
t Double
r -> Double -> Bool
circleCheck (Double
rDouble -> Double -> Double
forall a. Num a => a -> a -> a
+Double
tDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2)
  SolidCircle Double
r -> Double -> Bool
circleCheck Double
r
  Polygon [Point]
ps -> [Point] -> Bool
pointCheck [Point]
ps
  SolidPolygon [Point]
ps -> [Point] -> Bool
pointCheck [Point]
ps
  ThickPolygon Double
t [Point]
ps -> [Point] -> Bool
pointCheck ([Point] -> Bool) -> [Point] -> Bool
forall a b. (a -> b) -> a -> b
$ Double -> [Point] -> [Point]
forall {b}. Fractional b => b -> [(b, b)] -> [(b, b)]
thickenLine Double
t [Point]
ps
  ClosedCurve [Point]
ps -> [Point] -> Bool
pointCheck [Point]
ps
  SolidClosedCurve [Point]
ps -> [Point] -> Bool
pointCheck [Point]
ps
  ThickClosedCurve Double
t [Point]
ps -> [Point] -> Bool
pointCheck ([Point] -> Bool) -> [Point] -> Bool
forall a b. (a -> b) -> a -> b
$ Double -> [Point] -> [Point]
forall {b}. Fractional b => b -> [(b, b)] -> [(b, b)]
thickenLine Double
t [Point]
ps
  Polyline [Point]
ps -> [Point] -> Bool
pointCheck [Point]
ps
  ThickPolyline Double
t [Point]
ps -> [Point] -> Bool
pointCheck ([Point] -> Bool) -> [Point] -> Bool
forall a b. (a -> b) -> a -> b
$ Double -> [Point] -> [Point]
forall {b}. Fractional b => b -> [(b, b)] -> [(b, b)]
thickenLine Double
t [Point]
ps
  Curve [Point]
ps -> [Point] -> Bool
pointCheck [Point]
ps
  ThickCurve Double
t [Point]
ps -> [Point] -> Bool
pointCheck ([Point] -> Bool) -> [Point] -> Bool
forall a b. (a -> b) -> a -> b
$ Double -> [Point] -> [Point]
forall {b}. Fractional b => b -> [(b, b)] -> [(b, b)]
thickenLine Double
t [Point]
ps
  Sector Double
_ Double
_ Double
r -> Double -> Bool
circleCheck Double
r
  Arc Double
_ Double
_ Double
r -> Double -> Bool
circleCheck Double
r
  ThickArc Double
t Double
_ Double
_ Double
r -> Double -> Bool
circleCheck (Double
rDouble -> Double -> Double
forall a. Num a => a -> a -> a
+Double
tDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2)
  Lettering Text
t -> Text -> Bool
textCheck Text
t
  StyledLettering TextStyle
_ Font
_ Text
t ->  Text -> Bool
textCheck Text
t
  Color Color
_ Picture
q -> Picture
q Picture -> (Point, Point, Point, Point) -> Bool
`handle` (Point, Point, Point, Point)
corners
  Translate Double
x Double
y Picture
q -> Picture
q Picture -> (Point, Point, Point, Point) -> Bool
`handle` (Point -> Point)
-> (Point, Point, Point, Point) -> (Point, Point, Point, Point)
forall {t} {d}. (t -> d) -> (t, t, t, t) -> (d, d, d, d)
mapAll4 (Point -> Point -> Point
vectorDifference (Double
x,Double
y)) (Point, Point, Point, Point)
corners
  Scale Double
x Double
y Picture
q -> Picture
q Picture -> (Point, Point, Point, Point) -> Bool
`handle` (Point -> Point)
-> (Point, Point, Point, Point) -> (Point, Point, Point, Point)
forall {t} {d}. (t -> d) -> (t, t, t, t) -> (d, d, d, d)
mapAll4 (Double -> Double -> Point -> Point
scaledPoint (Double
1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
x) (Double
1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
y)) (Point, Point, Point, Point)
corners
  Dilate Double
fac Picture
q -> Picture
q Picture -> (Point, Point, Point, Point) -> Bool
`handle` (Point -> Point)
-> (Point, Point, Point, Point) -> (Point, Point, Point, Point)
forall {t} {d}. (t -> d) -> (t, t, t, t) -> (d, d, d, d)
mapAll4 (Double -> Point -> Point
dilatedPoint (Double
1Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
fac)) (Point, Point, Point, Point)
corners
  Rotate Double
angle Picture
q -> Picture
q Picture -> (Point, Point, Point, Point) -> Bool
`handle` (Point -> Point)
-> (Point, Point, Point, Point) -> (Point, Point, Point, Point)
forall {t} {d}. (t -> d) -> (t, t, t, t) -> (d, d, d, d)
mapAll4 (Double -> Point -> Point
rotatedPoint (-Double
angle)) (Point, Point, Point, Point)
corners
  Reflect Double
angle Picture
q -> Picture
q Picture -> (Point, Point, Point, Point) -> Bool
`handle` (Point -> Point)
-> (Point, Point, Point, Point) -> (Point, Point, Point, Point)
forall {t} {d}. (t -> d) -> (t, t, t, t) -> (d, d, d, d)
mapAll4 (Double -> Point -> Point
reflectedPoint Double
angle) (Point, Point, Point, Point)
corners
  Clip Double
x Double
y Picture
_ -> Double -> Double -> Bool
rectangleCheck Double
x Double
y
  Pictures [Picture]
ps -> (Picture -> Bool) -> [Picture] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Picture -> (Point, Point, Point, Point) -> Bool
`handle` (Point, Point, Point, Point)
corners) [Picture]
ps
  And Picture
p1 Picture
p2 -> Picture
p1 Picture -> (Point, Point, Point, Point) -> Bool
`handle` (Point, Point, Point, Point)
corners Bool -> Bool -> Bool
&& Picture
p2 Picture -> (Point, Point, Point, Point) -> Bool
`handle` (Point, Point, Point, Point)
corners
  Picture
CoordinatePlane -> Double -> Double -> Bool
rectangleCheck Double
20 Double
20
  Picture
Logo -> Double -> Double -> Bool
rectangleCheck Double
18 Double
7
  Picture
Blank -> Bool
True
  where
    epsilon :: Double
epsilon = Double
0.005
    pointCheck :: [Point] -> Bool
pointCheck = (Point -> Bool) -> [Point] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Point -> Bool
inRect
    thickenLine :: b -> [(b, b)] -> [(b, b)]
thickenLine b
t = ((b, b) -> (b, b)) -> [(b, b)] -> [(b, b)]
forall a b. (a -> b) -> [a] -> [b]
map ((b -> b) -> (b, b) -> (b, b)
forall a b. (a -> b) -> (a, a) -> (b, b)
both (b -> b -> b
forall a. Num a => a -> a -> a
+b
tb -> b -> b
forall a. Fractional a => a -> a -> a
/b
2))
    distance :: Point -> Point -> Double
distance Point
v1 Point
v2 =
      let diff :: Point
diff = Point -> Point -> Point
vectorDifference Point
v2 Point
v1
      in  Point -> Point -> Double
crossProduct Point
diff Point
v1 Double -> Double -> Double
forall a. Fractional a => a -> a -> a
/ Point -> Double
vectorLength Point
diff

    circleCheck :: Double -> Bool
circleCheck Double
r = Point -> Bool
inRect (Double
0,Double
0) Bool -> Bool -> Bool
&& ((Point, Point) -> Bool) -> [(Point, Point)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\(Point
v1,Point
v2) -> Point -> Point -> Double
distance Point
v1 Point
v2 Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
epsilon Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
>= Double
r) [(Point
a,Point
b),(Point
b,Point
c),(Point
c,Point
d),(Point
d,Point
a)]

    rectangleCheck :: Double -> Double -> Bool
rectangleCheck Double
x Double
y = [Point] -> Bool
pointCheck [(-(Double
xDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2),-(Double
yDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2)), (-(Double
xDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2),Double
yDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2), (Double
xDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2,Double
yDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2), (Double
xDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2,-(Double
yDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
2))]
    textCheck :: Text -> Bool
textCheck Text
t = Double -> Double -> Bool
rectangleCheck (Int -> Double
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> Double) -> Int -> Double
forall a b. (a -> b) -> a -> b
$ Text -> Int
T.length Text
t) Double
1

    inRect :: Point -> Bool
inRect Point
point =
      let
        ab :: Point
ab = Point -> Point -> Point
vectorDifference Point
b Point
a
        ad :: Point
ad = Point -> Point -> Point
vectorDifference Point
d Point
a
        ap :: Point
ap = Point -> Point -> Point
vectorDifference Point
point Point
a
      in
        -Double
epsilon Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<= Point -> Point -> Double
dotProduct Point
ap Point
ab Bool -> Bool -> Bool
&& Point -> Point -> Double
dotProduct Point
ap Point
ab Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<= Point -> Point -> Double
dotProduct Point
ab Point
ab Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
epsilon Bool -> Bool -> Bool
&&
        -Double
epsilon Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<= Point -> Point -> Double
dotProduct Point
ap Point
ad Bool -> Bool -> Bool
&& Point -> Point -> Double
dotProduct Point
ap Point
ad Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
<= Point -> Point -> Double
dotProduct Point
ad Point
ad Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
epsilon

    mapAll4 :: (t -> d) -> (t, t, t, t) -> (d, d, d, d)
mapAll4 t -> d
f (t
w,t
x,t
y,t
z) = (t -> d
f t
w, t -> d
f t
x, t -> d
f t
y, t -> d
f t
z)


validThickness :: Double -> Double
validThickness :: Double -> Double
validThickness Double
t
  | Double
t Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
0     = String -> Double
forall a. HasCallStack => String -> a
error String
"The line width must be non-negative."
  | Bool
otherwise = Double
t