{-# LANGUAGE PackageImports #-}
# LANGUAGE RebindableSyntax #
# LANGUAGE NoImplicitPrelude #


   Copyright 2020 The CodeWorld Authors . All rights reserved . 

   Licensed under the Apache License , Version 2.0 ( the " License " ) ; 
   you may not use this file except in compliance with the License . 
   You may obtain a copy of the License at 

       -2.0 

   Unless required by applicable law or agreed to in writing , software 
   distributed under the License is distributed on an " AS IS " BASIS , 
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied . 
   See the License for the specific language governing permissions and 
   limitations under the License . 

  Copyright 2020 The CodeWorld Authors. All rights reserved.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      -2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-}
module Internal.Picture where

import qualified "codeworld-api" CodeWorld as CW
import GHC.Stack
import Internal.Color
import Internal.Num
import Internal.Text
import "base" Prelude (($), (.), map)

  | A point in two dimensions .   A point is written with the x coordinate
  first , and the y coordinate second .   For example , ( 3 , -2 ) is the point
  with x coordinate 3 a y coordinate -2 .
type Point = (Number, Number)

toCWPoint :: Point -> CW.Point
toCWPoint (x, y) = (toDouble x, toDouble y)

fromCWPoint :: CW.Point -> Point
fromCWPoint (x, y) = (fromDouble x, fromDouble y)

-- | Moves a given point by given x and y offsets
translatedPoint :: (Point, Number, Number) -> Point
translatedPoint (p, x, y) =
  fromCWPoint (CW.translatedPoint (toDouble x) (toDouble y) (toCWPoint p))

-- | Rotates a given point by given angle, in degrees
rotatedPoint :: (Point, Number) -> Point
rotatedPoint (p, a) =
  fromCWPoint (CW.rotatedPoint (toDouble (pi * a / 180)) (toCWPoint p))

reflectedPoint :: (Point, Number) -> Point
reflectedPoint (p, a) =
  fromCWPoint (CW.reflectedPoint (toDouble (pi * a / 180)) (toCWPoint p))

-- | Scales a given point by given x and y scaling factor.  Scaling by a
-- negative factor also reflects across that axis.
scaledPoint :: (Point, Number, Number) -> Point
scaledPoint (p, x, y) =
  fromCWPoint (CW.scaledPoint (toDouble x) (toDouble y) (toCWPoint p))

-- | Dilates a given point by given uniform scaling factor.  Dilating by a
-- negative factor also reflects across the origin.
dilatedPoint :: (Point, Number) -> Point
dilatedPoint (p, k) =
  fromCWPoint (CW.dilatedPoint (toDouble k) (toCWPoint p))

  | A two - dimensional vector
type Vector = (Number, Number)

toCWVect :: Vector -> CW.Vector
toCWVect = toCWPoint

fromCWVect :: CW.Vector -> Vector
fromCWVect = fromCWPoint

-- | The length of the given vector
vectorLength :: Vector -> Number
vectorLength v = fromDouble (CW.vectorLength (toCWVect v))

-- | The counter-clockwise angle, in degrees, that a given vector make with the X-axis
vectorDirection :: Vector -> Number
vectorDirection v = 180 / pi * fromDouble (CW.vectorDirection (toCWVect v))

  | The sum of two vectors
vectorSum :: (Vector, Vector) -> Vector
vectorSum (v, w) = fromCWVect (CW.vectorSum (toCWVect v) (toCWVect w))

  | The difference of two vectors
vectorDifference :: (Vector, Vector) -> Vector
vectorDifference (v, w) =
  fromCWVect (CW.vectorDifference (toCWVect v) (toCWVect w))

-- | Scales a given vector by a given scalar multiplier
scaledVector :: (Vector, Number) -> Vector
scaledVector (v, k) = fromCWVect (CW.scaledVector (toDouble k) (toCWVect v))

-- | Rotates a given vector by a given angle in degrees
rotatedVector :: (Vector, Number) -> Vector
rotatedVector (v, k) =
  fromCWVect (CW.rotatedVector (toDouble (pi * k / 180)) (toCWVect v))

  | The dot product of two vectors
dotProduct :: (Vector, Vector) -> Number
dotProduct (v, w) = fromDouble (CW.dotProduct (toCWVect v) (toCWVect w))

-- | A type for pictures.
--
-- Pictures can be created from geometry functions such as 'circle'
-- and 'rectangle'.  They can be combined by overlaying them with '&'.
-- They can be modified using transformations like 'translated',
-- 'rotated', 'dilated', 'colored', and 'scaled'.  Ultimately, a picture
  can be drawn on the screen using one of the CodeWorld entry points
-- such as 'drawingOf'.
newtype Picture = CWPic
  { toCWPic :: CW.Picture
  }

-- | A font in which lettering can be drawn.  Fonts are used with the
-- 'styledLettering' function.
--
  ' NamedFont ' may create a program that only works correctly on
-- computers where that font is installed, so you are encouraged to
-- use one of the other values.
data Font
  = Serif
  | SansSerif
  | Monospace
  | Handwriting
  | Fancy
  | NamedFont !Text

-- | A style in which lettering can be drawn.  Text styles are used
-- with the 'styledLettering' function.
data TextStyle
  = Plain
  | Italic
  | Bold

-- | A blank picture
blank :: HasCallStack => Picture
blank = withFrozenCallStack $ CWPic CW.blank

-- | A thin sequence of line segments with these endpoints
polyline :: HasCallStack => [Point] -> Picture
polyline ps = withFrozenCallStack $ CWPic (CW.polyline (map toCWVect ps))

-- | A thin sequence of line segments, with these endpoints and line width
thickPolyline :: HasCallStack => ([Point], Number) -> Picture
thickPolyline (ps, n) = withFrozenCallStack $ CWPic (CW.thickPolyline (toDouble n) (map toCWVect ps))

-- | A thin polygon with these points as vertices
polygon :: HasCallStack => [Point] -> Picture
polygon ps = withFrozenCallStack $ CWPic (CW.polygon (map toCWVect ps))

-- | A thin polygon with these points as vertices
thickPolygon :: HasCallStack => ([Point], Number) -> Picture
thickPolygon (ps, n) = withFrozenCallStack $ CWPic (CW.thickPolygon (toDouble n) (map toCWVect ps))

-- | A solid polygon with these points as vertices
solidPolygon :: HasCallStack => [Point] -> Picture
solidPolygon ps = withFrozenCallStack $ CWPic (CW.solidPolygon (map toCWVect ps))

-- | A thin curve passing through these points.
curve :: HasCallStack => [Point] -> Picture
curve ps = withFrozenCallStack $ CWPic (CW.curve (map toCWVect ps))

-- | A thick curve passing through these points, with this line width
thickCurve :: HasCallStack => ([Point], Number) -> Picture
thickCurve (ps, n) = withFrozenCallStack $ CWPic (CW.thickCurve (toDouble n) (map toCWVect ps))

-- | A thin closed curve passing through these points.
closedCurve :: HasCallStack => [Point] -> Picture
closedCurve ps = withFrozenCallStack $ CWPic (CW.closedCurve (map toCWVect ps))

-- | A thick closed curve passing through these points, with this line width.
thickClosedCurve :: HasCallStack => ([Point], Number) -> Picture
thickClosedCurve (ps, n) = withFrozenCallStack $ CWPic (CW.thickClosedCurve (toDouble n) (map toCWVect ps))

-- | A solid closed curve passing through these points.
solidClosedCurve :: HasCallStack => [Point] -> Picture
solidClosedCurve ps = CWPic (CW.solidClosedCurve (map toCWVect ps))

-- | A thin rectangle, with this width and height
rectangle :: HasCallStack => (Number, Number) -> Picture
rectangle (w, h) = withFrozenCallStack $ CWPic (CW.rectangle (toDouble w) (toDouble h))

-- | A solid rectangle, with this width and height
solidRectangle :: HasCallStack => (Number, Number) -> Picture
solidRectangle (w, h) = withFrozenCallStack $ CWPic (CW.solidRectangle (toDouble w) (toDouble h))

-- | A thick rectangle, with this width and height and line width
thickRectangle :: HasCallStack => (Number, Number, Number) -> Picture
thickRectangle (w, h, lw) =
  withFrozenCallStack $ CWPic (CW.thickRectangle (toDouble lw) (toDouble w) (toDouble h))

-- | A thin circle, with this radius
circle :: HasCallStack => Number -> Picture
circle r = withFrozenCallStack $ CWPic (CW.circle (toDouble r))

-- | A solid circle, with this radius
solidCircle :: HasCallStack => Number -> Picture
solidCircle r = withFrozenCallStack $ CWPic (CW.solidCircle (toDouble r))

-- | A thick circle, with this radius and line width
thickCircle :: HasCallStack => (Number, Number) -> Picture
thickCircle (r, w) = withFrozenCallStack $ CWPic (CW.thickCircle (toDouble w) (toDouble r))

-- | A thin arc, starting and ending at these angles, with this radius
arc :: HasCallStack => (Number, Number, Number) -> Picture
arc (b, e, r) =
  withFrozenCallStack $
    CWPic
      (CW.arc (toDouble (pi * b / 180)) (toDouble (pi * e / 180)) (toDouble r))

-- | A solid sector of a circle (i.e., a pie slice) starting and ending at these
-- angles, with this radius
sector :: HasCallStack => (Number, Number, Number) -> Picture
sector (b, e, r) =
  withFrozenCallStack $
    CWPic
      ( CW.sector
          (toDouble (pi * b / 180))
          (toDouble (pi * e / 180))
          (toDouble r)
      )

-- | A thick arc, starting and ending at these angles, with this radius and
-- line width
thickArc :: HasCallStack => (Number, Number, Number, Number) -> Picture
thickArc (b, e, r, w) =
  withFrozenCallStack $
    CWPic
      ( CW.thickArc
          (toDouble w)
          (toDouble (pi * b / 180))
          (toDouble (pi * e / 180))
          (toDouble r)
      )

-- | A rendering of text characters.
lettering :: HasCallStack => Text -> Picture
lettering t = withFrozenCallStack $ CWPic (CW.lettering (fromCWText t))

-- | A rendering of text characters, with a specific choice of font and style.
styledLettering :: HasCallStack => (Text, Font, TextStyle) -> Picture
styledLettering (t, f, s) =
  withFrozenCallStack $ CWPic (CW.styledLettering (fromCWStyle s) (fromCWFont f) (fromCWText t))
  where
    fromCWStyle Plain = CW.Plain
    fromCWStyle Bold = CW.Bold
    fromCWStyle Italic = CW.Italic
    fromCWFont Serif = CW.Serif
    fromCWFont SansSerif = CW.SansSerif
    fromCWFont Monospace = CW.Monospace
    fromCWFont Handwriting = CW.Handwriting
    fromCWFont Fancy = CW.Fancy
    fromCWFont (NamedFont fnt) = CW.NamedFont (fromCWText fnt)

-- | A picture drawn entirely in this color.
colored :: HasCallStack => (Picture, Color) -> Picture
colored (p, c) = withFrozenCallStack $ CWPic (CW.colored (toCWColor c) (toCWPic p))

-- | A picture drawn entirely in this color.
coloured :: HasCallStack => (Picture, Color) -> Picture
coloured args = withFrozenCallStack $ colored args

-- | A picture drawn translated in these directions.
translated :: HasCallStack => (Picture, Number, Number) -> Picture
translated (p, x, y) =
  withFrozenCallStack $ CWPic (CW.translated (toDouble x) (toDouble y) (toCWPic p))

-- | A picture scaled by these factors in the x and y directions.
-- Factors greater than @1@ stretch the picture larger in that direction, and
-- less than @1@ squish it smaller in that direction.
--
-- Negative factors also reflect the picture across that axis. For example, to mirror
  a picture over the x - axis : @scaled(p , -1 , 1)@.
scaled :: HasCallStack => (Picture, Number, Number) -> Picture
scaled (p, x, y) = withFrozenCallStack $ CWPic (CW.scaled (toDouble x) (toDouble y) (toCWPic p))

-- | A picture with both dimensions scaled by the given factor.
-- Factors greater than @1@ make the picture bigger and less than @1@
-- make it smaller.
--
-- Negative factors reflect the picture across the origin, which is the same as
  rotating it by 180 degrees .
dilated :: HasCallStack => (Picture, Number) -> Picture
dilated (p, k) = withFrozenCallStack $ CWPic (CW.dilated (toDouble k) (toCWPic p))

-- | A picture rotated by this angle.
rotated :: HasCallStack => (Picture, Number) -> Picture
rotated (p, th) = withFrozenCallStack $ CWPic (CW.rotated (toDouble (pi * th / 180)) (toCWPic p))

-- | A picture reflected across a line through the origin at this angle, in
-- degrees.  For example, an angle of 0 reflects the picture vertically
  across the x axis , while an angle of 90 reflects the picture
  horizontally across the y axis , and an agle of 45 reflects the picture
-- across the main diagonal.
reflected :: HasCallStack => (Picture, Number) -> Picture
reflected (p, th) = withFrozenCallStack $ CWPic (CW.reflected (toDouble (pi * th / 180)) (toCWPic p))

-- | A picture clipped to a rectangle of this width and height.
clipped :: HasCallStack => (Picture, Number, Number) -> Picture
clipped (p, w, h) =
  withFrozenCallStack $ CWPic (CW.clipped (toDouble w) (toDouble h) (toCWPic p))

-- | A picture made by drawing this list of pictures, ordered from front to back.
pictures :: HasCallStack => [Picture] -> Picture
pictures ps = withFrozenCallStack $ CWPic (CW.pictures (map toCWPic ps))

  | A binary operation that overlays one picture in from of the other .
(&) :: HasCallStack => Picture -> Picture -> Picture

infixr 0 &

a & b = withFrozenCallStack $ CWPic (toCWPic a CW.& toCWPic b)

-- | A coordinate plane.
--
-- Adding this to your pictures can help you measure distances
-- more accurately.
--
-- Example:
--
  > program = drawingOf(myPicture & coordinatePlane )
-- > myPicture = ...
coordinatePlane :: HasCallStack => Picture
coordinatePlane = withFrozenCallStack $ CWPic CW.coordinatePlane

  | The CodeWorld logo .
codeWorldLogo :: HasCallStack => Picture
codeWorldLogo = withFrozenCallStack $ CWPic CW.codeWorldLogo

# LANGUAGE PackageImports #
 | Moves a given point by given x and y offsets
 | Rotates a given point by given angle, in degrees
 | Scales a given point by given x and y scaling factor.  Scaling by a
 negative factor also reflects across that axis.
 | Dilates a given point by given uniform scaling factor.  Dilating by a
 negative factor also reflects across the origin.
 | The length of the given vector
 | The counter-clockwise angle, in degrees, that a given vector make with the X-axis
 | Scales a given vector by a given scalar multiplier
 | Rotates a given vector by a given angle in degrees
 | A type for pictures.

 Pictures can be created from geometry functions such as 'circle'
 and 'rectangle'.  They can be combined by overlaying them with '&'.
 They can be modified using transformations like 'translated',
 'rotated', 'dilated', 'colored', and 'scaled'.  Ultimately, a picture
 such as 'drawingOf'.
 | A font in which lettering can be drawn.  Fonts are used with the
 'styledLettering' function.

 computers where that font is installed, so you are encouraged to
 use one of the other values.
 | A style in which lettering can be drawn.  Text styles are used
 with the 'styledLettering' function.
 | A blank picture
 | A thin sequence of line segments with these endpoints
 | A thin sequence of line segments, with these endpoints and line width
 | A thin polygon with these points as vertices
 | A thin polygon with these points as vertices
 | A solid polygon with these points as vertices
 | A thin curve passing through these points.
 | A thick curve passing through these points, with this line width
 | A thin closed curve passing through these points.
 | A thick closed curve passing through these points, with this line width.
 | A solid closed curve passing through these points.
 | A thin rectangle, with this width and height
 | A solid rectangle, with this width and height
 | A thick rectangle, with this width and height and line width
 | A thin circle, with this radius
 | A solid circle, with this radius
 | A thick circle, with this radius and line width
 | A thin arc, starting and ending at these angles, with this radius
 | A solid sector of a circle (i.e., a pie slice) starting and ending at these
 angles, with this radius
 | A thick arc, starting and ending at these angles, with this radius and
 line width
 | A rendering of text characters.
 | A rendering of text characters, with a specific choice of font and style.
 | A picture drawn entirely in this color.
 | A picture drawn entirely in this color.
 | A picture drawn translated in these directions.
 | A picture scaled by these factors in the x and y directions.
 Factors greater than @1@ stretch the picture larger in that direction, and
 less than @1@ squish it smaller in that direction.

 Negative factors also reflect the picture across that axis. For example, to mirror
 | A picture with both dimensions scaled by the given factor.
 Factors greater than @1@ make the picture bigger and less than @1@
 make it smaller.

 Negative factors reflect the picture across the origin, which is the same as
 | A picture rotated by this angle.
 | A picture reflected across a line through the origin at this angle, in
 degrees.  For example, an angle of 0 reflects the picture vertically
 across the main diagonal.
 | A picture clipped to a rectangle of this width and height.
 | A picture made by drawing this list of pictures, ordered from front to back.
 | A coordinate plane.

 Adding this to your pictures can help you measure distances
 more accurately.

 Example:

 > myPicture = ...
# LANGUAGE RebindableSyntax #
# LANGUAGE NoImplicitPrelude #


   Copyright 2020 The CodeWorld Authors . All rights reserved . 

   Licensed under the Apache License , Version 2.0 ( the " License " ) ; 
   you may not use this file except in compliance with the License . 
   You may obtain a copy of the License at 

       -2.0 

   Unless required by applicable law or agreed to in writing , software 
   distributed under the License is distributed on an " AS IS " BASIS , 
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied . 
   See the License for the specific language governing permissions and 
   limitations under the License . 

  Copyright 2020 The CodeWorld Authors. All rights reserved.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      -2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-}
module Internal.Picture where

import qualified "codeworld-api" CodeWorld as CW
import GHC.Stack
import Internal.Color
import Internal.Num
import Internal.Text
import "base" Prelude (($), (.), map)

  | A point in two dimensions .   A point is written with the x coordinate
  first , and the y coordinate second .   For example , ( 3 , -2 ) is the point
  with x coordinate 3 a y coordinate -2 .
type Point = (Number, Number)

toCWPoint :: Point -> CW.Point
toCWPoint (x, y) = (toDouble x, toDouble y)

fromCWPoint :: CW.Point -> Point
fromCWPoint (x, y) = (fromDouble x, fromDouble y)

translatedPoint :: (Point, Number, Number) -> Point
translatedPoint (p, x, y) =
  fromCWPoint (CW.translatedPoint (toDouble x) (toDouble y) (toCWPoint p))

rotatedPoint :: (Point, Number) -> Point
rotatedPoint (p, a) =
  fromCWPoint (CW.rotatedPoint (toDouble (pi * a / 180)) (toCWPoint p))

reflectedPoint :: (Point, Number) -> Point
reflectedPoint (p, a) =
  fromCWPoint (CW.reflectedPoint (toDouble (pi * a / 180)) (toCWPoint p))

scaledPoint :: (Point, Number, Number) -> Point
scaledPoint (p, x, y) =
  fromCWPoint (CW.scaledPoint (toDouble x) (toDouble y) (toCWPoint p))

dilatedPoint :: (Point, Number) -> Point
dilatedPoint (p, k) =
  fromCWPoint (CW.dilatedPoint (toDouble k) (toCWPoint p))

  | A two - dimensional vector
type Vector = (Number, Number)

toCWVect :: Vector -> CW.Vector
toCWVect = toCWPoint

fromCWVect :: CW.Vector -> Vector
fromCWVect = fromCWPoint

vectorLength :: Vector -> Number
vectorLength v = fromDouble (CW.vectorLength (toCWVect v))

vectorDirection :: Vector -> Number
vectorDirection v = 180 / pi * fromDouble (CW.vectorDirection (toCWVect v))

  | The sum of two vectors
vectorSum :: (Vector, Vector) -> Vector
vectorSum (v, w) = fromCWVect (CW.vectorSum (toCWVect v) (toCWVect w))

  | The difference of two vectors
vectorDifference :: (Vector, Vector) -> Vector
vectorDifference (v, w) =
  fromCWVect (CW.vectorDifference (toCWVect v) (toCWVect w))

scaledVector :: (Vector, Number) -> Vector
scaledVector (v, k) = fromCWVect (CW.scaledVector (toDouble k) (toCWVect v))

rotatedVector :: (Vector, Number) -> Vector
rotatedVector (v, k) =
  fromCWVect (CW.rotatedVector (toDouble (pi * k / 180)) (toCWVect v))

  | The dot product of two vectors
dotProduct :: (Vector, Vector) -> Number
dotProduct (v, w) = fromDouble (CW.dotProduct (toCWVect v) (toCWVect w))

  can be drawn on the screen using one of the CodeWorld entry points
newtype Picture = CWPic
  { toCWPic :: CW.Picture
  }

  ' NamedFont ' may create a program that only works correctly on
data Font
  = Serif
  | SansSerif
  | Monospace
  | Handwriting
  | Fancy
  | NamedFont !Text

data TextStyle
  = Plain
  | Italic
  | Bold

blank :: HasCallStack => Picture
blank = withFrozenCallStack $ CWPic CW.blank

polyline :: HasCallStack => [Point] -> Picture
polyline ps = withFrozenCallStack $ CWPic (CW.polyline (map toCWVect ps))

thickPolyline :: HasCallStack => ([Point], Number) -> Picture
thickPolyline (ps, n) = withFrozenCallStack $ CWPic (CW.thickPolyline (toDouble n) (map toCWVect ps))

polygon :: HasCallStack => [Point] -> Picture
polygon ps = withFrozenCallStack $ CWPic (CW.polygon (map toCWVect ps))

thickPolygon :: HasCallStack => ([Point], Number) -> Picture
thickPolygon (ps, n) = withFrozenCallStack $ CWPic (CW.thickPolygon (toDouble n) (map toCWVect ps))

solidPolygon :: HasCallStack => [Point] -> Picture
solidPolygon ps = withFrozenCallStack $ CWPic (CW.solidPolygon (map toCWVect ps))

curve :: HasCallStack => [Point] -> Picture
curve ps = withFrozenCallStack $ CWPic (CW.curve (map toCWVect ps))

thickCurve :: HasCallStack => ([Point], Number) -> Picture
thickCurve (ps, n) = withFrozenCallStack $ CWPic (CW.thickCurve (toDouble n) (map toCWVect ps))

closedCurve :: HasCallStack => [Point] -> Picture
closedCurve ps = withFrozenCallStack $ CWPic (CW.closedCurve (map toCWVect ps))

thickClosedCurve :: HasCallStack => ([Point], Number) -> Picture
thickClosedCurve (ps, n) = withFrozenCallStack $ CWPic (CW.thickClosedCurve (toDouble n) (map toCWVect ps))

solidClosedCurve :: HasCallStack => [Point] -> Picture
solidClosedCurve ps = CWPic (CW.solidClosedCurve (map toCWVect ps))

rectangle :: HasCallStack => (Number, Number) -> Picture
rectangle (w, h) = withFrozenCallStack $ CWPic (CW.rectangle (toDouble w) (toDouble h))

solidRectangle :: HasCallStack => (Number, Number) -> Picture
solidRectangle (w, h) = withFrozenCallStack $ CWPic (CW.solidRectangle (toDouble w) (toDouble h))

thickRectangle :: HasCallStack => (Number, Number, Number) -> Picture
thickRectangle (w, h, lw) =
  withFrozenCallStack $ CWPic (CW.thickRectangle (toDouble lw) (toDouble w) (toDouble h))

circle :: HasCallStack => Number -> Picture
circle r = withFrozenCallStack $ CWPic (CW.circle (toDouble r))

solidCircle :: HasCallStack => Number -> Picture
solidCircle r = withFrozenCallStack $ CWPic (CW.solidCircle (toDouble r))

thickCircle :: HasCallStack => (Number, Number) -> Picture
thickCircle (r, w) = withFrozenCallStack $ CWPic (CW.thickCircle (toDouble w) (toDouble r))

arc :: HasCallStack => (Number, Number, Number) -> Picture
arc (b, e, r) =
  withFrozenCallStack $
    CWPic
      (CW.arc (toDouble (pi * b / 180)) (toDouble (pi * e / 180)) (toDouble r))

sector :: HasCallStack => (Number, Number, Number) -> Picture
sector (b, e, r) =
  withFrozenCallStack $
    CWPic
      ( CW.sector
          (toDouble (pi * b / 180))
          (toDouble (pi * e / 180))
          (toDouble r)
      )

thickArc :: HasCallStack => (Number, Number, Number, Number) -> Picture
thickArc (b, e, r, w) =
  withFrozenCallStack $
    CWPic
      ( CW.thickArc
          (toDouble w)
          (toDouble (pi * b / 180))
          (toDouble (pi * e / 180))
          (toDouble r)
      )

lettering :: HasCallStack => Text -> Picture
lettering t = withFrozenCallStack $ CWPic (CW.lettering (fromCWText t))

styledLettering :: HasCallStack => (Text, Font, TextStyle) -> Picture
styledLettering (t, f, s) =
  withFrozenCallStack $ CWPic (CW.styledLettering (fromCWStyle s) (fromCWFont f) (fromCWText t))
  where
    fromCWStyle Plain = CW.Plain
    fromCWStyle Bold = CW.Bold
    fromCWStyle Italic = CW.Italic
    fromCWFont Serif = CW.Serif
    fromCWFont SansSerif = CW.SansSerif
    fromCWFont Monospace = CW.Monospace
    fromCWFont Handwriting = CW.Handwriting
    fromCWFont Fancy = CW.Fancy
    fromCWFont (NamedFont fnt) = CW.NamedFont (fromCWText fnt)

colored :: HasCallStack => (Picture, Color) -> Picture
colored (p, c) = withFrozenCallStack $ CWPic (CW.colored (toCWColor c) (toCWPic p))

coloured :: HasCallStack => (Picture, Color) -> Picture
coloured args = withFrozenCallStack $ colored args

translated :: HasCallStack => (Picture, Number, Number) -> Picture
translated (p, x, y) =
  withFrozenCallStack $ CWPic (CW.translated (toDouble x) (toDouble y) (toCWPic p))

  a picture over the x - axis : @scaled(p , -1 , 1)@.
scaled :: HasCallStack => (Picture, Number, Number) -> Picture
scaled (p, x, y) = withFrozenCallStack $ CWPic (CW.scaled (toDouble x) (toDouble y) (toCWPic p))

  rotating it by 180 degrees .
dilated :: HasCallStack => (Picture, Number) -> Picture
dilated (p, k) = withFrozenCallStack $ CWPic (CW.dilated (toDouble k) (toCWPic p))

rotated :: HasCallStack => (Picture, Number) -> Picture
rotated (p, th) = withFrozenCallStack $ CWPic (CW.rotated (toDouble (pi * th / 180)) (toCWPic p))

  across the x axis , while an angle of 90 reflects the picture
  horizontally across the y axis , and an agle of 45 reflects the picture
reflected :: HasCallStack => (Picture, Number) -> Picture
reflected (p, th) = withFrozenCallStack $ CWPic (CW.reflected (toDouble (pi * th / 180)) (toCWPic p))

clipped :: HasCallStack => (Picture, Number, Number) -> Picture
clipped (p, w, h) =
  withFrozenCallStack $ CWPic (CW.clipped (toDouble w) (toDouble h) (toCWPic p))

pictures :: HasCallStack => [Picture] -> Picture
pictures ps = withFrozenCallStack $ CWPic (CW.pictures (map toCWPic ps))

  | A binary operation that overlays one picture in from of the other .
(&) :: HasCallStack => Picture -> Picture -> Picture

infixr 0 &

a & b = withFrozenCallStack $ CWPic (toCWPic a CW.& toCWPic b)

  > program = drawingOf(myPicture & coordinatePlane )
coordinatePlane :: HasCallStack => Picture
coordinatePlane = withFrozenCallStack $ CWPic CW.coordinatePlane

  | The CodeWorld logo .
codeWorldLogo :: HasCallStack => Picture
codeWorldLogo = withFrozenCallStack $ CWPic CW.codeWorldLogo
