module CodeWorld.Test.Abstract where


import Data.Tuple.Extra                 (both)
import CodeWorld.Tasks.API              (Drawable(..))
import CodeWorld.Tasks.Color            (Color(..))
import CodeWorld.Test.Normalize         (NormalizedPicture)



{- |
Draw an abstract, hollow square.
-}
someSquare :: NormalizedPicture
someSquare :: NormalizedPicture
someSquare = Double -> Double -> NormalizedPicture
forall a. Drawable a => Double -> Double -> a
rectangle Double
1 Double
1

{- |
Draw an abstract, filled in square.
-}
someSolidSquare :: NormalizedPicture
someSolidSquare :: NormalizedPicture
someSolidSquare = Double -> Double -> NormalizedPicture
forall a. Drawable a => Double -> Double -> a
solidRectangle Double
1 Double
1

{- |
Draw an abstract, hollow rectangle.
This is an alias for `someSquare`.
-}
someRectangle :: NormalizedPicture
someRectangle :: NormalizedPicture
someRectangle = NormalizedPicture
someSquare

{- |
Draw an abstract, filled in rectangle.
This is an alias for `someSolidSquare`.
-}
someSolidRectangle :: NormalizedPicture
someSolidRectangle :: NormalizedPicture
someSolidRectangle = NormalizedPicture
someSolidSquare

{- |
Draw an abstract, hollow rectangle that is wider than tall.
-}
someWideRectangle :: NormalizedPicture
someWideRectangle :: NormalizedPicture
someWideRectangle = Double -> Double -> NormalizedPicture
forall a. Drawable a => Double -> Double -> a
rectangle Double
2 Double
1

{- |
Draw an abstract, filled in rectangle that is wider than tall.
-}
someWideSolidRectangle :: NormalizedPicture
someWideSolidRectangle :: NormalizedPicture
someWideSolidRectangle = Double -> Double -> NormalizedPicture
forall a. Drawable a => Double -> Double -> a
solidRectangle Double
2 Double
1

{- |
Draw an abstract, hollow rectangle that is taller than wide.
-}
someTallRectangle :: NormalizedPicture
someTallRectangle :: NormalizedPicture
someTallRectangle = Double -> Double -> NormalizedPicture
forall a. Drawable a => Double -> Double -> a
rectangle Double
1 Double
2

{- |
Draw an abstract, filled in rectangle that is taller than wide.
-}
someTallSolidRectangle :: NormalizedPicture
someTallSolidRectangle :: NormalizedPicture
someTallSolidRectangle = Double -> Double -> NormalizedPicture
forall a. Drawable a => Double -> Double -> a
solidRectangle Double
1 Double
2

{- |
Draw an abstract, hollow circle.
-}
someCircle :: NormalizedPicture
someCircle :: NormalizedPicture
someCircle = Double -> NormalizedPicture
forall a. Drawable a => Double -> a
circle Double
1

{- |
Draw an abstract, filled in circle.
-}
someSolidCircle :: NormalizedPicture
someSolidCircle :: NormalizedPicture
someSolidCircle = Double -> NormalizedPicture
forall a. Drawable a => Double -> a
solidCircle Double
1

{- |
Provide an abstract shape with a color.
The color will be treated as equal with any other color.
-}
someColor :: NormalizedPicture -> NormalizedPicture
someColor :: NormalizedPicture -> NormalizedPicture
someColor = Color -> NormalizedPicture -> NormalizedPicture
forall a. Drawable a => Color -> a -> a
colored Color
AnyColor

{- |
Rotate an abstract shape by up to a quarter turn.
-}
rotatedQuarter :: NormalizedPicture -> NormalizedPicture
rotatedQuarter :: NormalizedPicture -> NormalizedPicture
rotatedQuarter = Double -> NormalizedPicture -> NormalizedPicture
forall a. Drawable a => Double -> a -> a
rotated (Double -> NormalizedPicture -> NormalizedPicture)
-> Double -> NormalizedPicture -> NormalizedPicture
forall a b. (a -> b) -> a -> b
$ Double
forall a. Floating a => a
piDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
4

{- |
Rotate an abstract shape by between a quarter and half turn.
-}
rotatedHalf :: NormalizedPicture -> NormalizedPicture
rotatedHalf :: NormalizedPicture -> NormalizedPicture
rotatedHalf = Double -> NormalizedPicture -> NormalizedPicture
forall a. Drawable a => Double -> a -> a
rotated (Double -> NormalizedPicture -> NormalizedPicture)
-> Double -> NormalizedPicture -> NormalizedPicture
forall a b. (a -> b) -> a -> b
$ Double
3Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
forall a. Floating a => a
piDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
4

{- |
Rotate an abstract shape by between a half and three quarters turn.
-}
rotatedThreeQuarters :: NormalizedPicture -> NormalizedPicture
rotatedThreeQuarters :: NormalizedPicture -> NormalizedPicture
rotatedThreeQuarters = Double -> NormalizedPicture -> NormalizedPicture
forall a. Drawable a => Double -> a -> a
rotated (Double -> NormalizedPicture -> NormalizedPicture)
-> Double -> NormalizedPicture -> NormalizedPicture
forall a b. (a -> b) -> a -> b
$ Double
5Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
forall a. Floating a => a
piDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
4

{- |
Rotate an abstract shape by between a three quarters and up to a full turn.
The full turn itself is excluded.
-}
rotatedUpToFull :: NormalizedPicture -> NormalizedPicture
rotatedUpToFull :: NormalizedPicture -> NormalizedPicture
rotatedUpToFull = Double -> NormalizedPicture -> NormalizedPicture
forall a. Drawable a => Double -> a -> a
rotated (Double -> NormalizedPicture -> NormalizedPicture)
-> Double -> NormalizedPicture -> NormalizedPicture
forall a b. (a -> b) -> a -> b
$ Double
7Double -> Double -> Double
forall a. Num a => a -> a -> a
*Double
forall a. Floating a => a
piDouble -> Double -> Double
forall a. Fractional a => a -> a -> a
/Double
4

{- |
Shrink an abstract shape.
Both directions are scaled an equal amount.
-}
smaller :: NormalizedPicture -> NormalizedPicture
smaller :: NormalizedPicture -> NormalizedPicture
smaller = Double -> NormalizedPicture -> NormalizedPicture
forall a. Drawable a => Double -> a -> a
dilated Double
0.5

{- |
Enlarge an abstract shape.
Both directions are scaled an equal amount.
-}
larger :: NormalizedPicture -> NormalizedPicture
larger :: NormalizedPicture -> NormalizedPicture
larger = Double -> NormalizedPicture -> NormalizedPicture
forall a. Drawable a => Double -> a -> a
dilated Double
2

{- |
Shrink an abstract shape in X-direction.
The Y-direction is unchanged.
-}
smallerX :: NormalizedPicture -> NormalizedPicture
smallerX :: NormalizedPicture -> NormalizedPicture
smallerX = Double -> Double -> NormalizedPicture -> NormalizedPicture
forall a. Drawable a => Double -> Double -> a -> a
scaled Double
0.5 Double
1

{- |
Enlarge an abstract shape in X-direction.
The Y-direction is unchanged.
-}
largerX :: NormalizedPicture -> NormalizedPicture
largerX :: NormalizedPicture -> NormalizedPicture
largerX = Double -> Double -> NormalizedPicture -> NormalizedPicture
forall a. Drawable a => Double -> Double -> a -> a
scaled Double
2 Double
1

{- |
Shrink an abstract shape in Y-direction.
The X-direction is unchanged.
-}
smallerY :: NormalizedPicture -> NormalizedPicture
smallerY :: NormalizedPicture -> NormalizedPicture
smallerY = Double -> Double -> NormalizedPicture -> NormalizedPicture
forall a. Drawable a => Double -> Double -> a -> a
scaled Double
1 Double
0.5

{- |
Enlarge an abstract shape in Y-direction.
The X-direction is unchanged.
-}
largerY :: NormalizedPicture -> NormalizedPicture
largerY :: NormalizedPicture -> NormalizedPicture
largerY = Double -> Double -> NormalizedPicture -> NormalizedPicture
forall a. Drawable a => Double -> Double -> a -> a
scaled Double
1 Double
2

{- |
Draw an abstract, open curve with this many segments.
-}
someCurve :: Int -> NormalizedPicture
someCurve :: Int -> NormalizedPicture
someCurve Int
points = [Point] -> NormalizedPicture
forall a. Drawable a => [Point] -> a
curve ([Point] -> NormalizedPicture) -> [Point] -> NormalizedPicture
forall a b. (a -> b) -> a -> b
$ Int -> [Point] -> [Point]
forall a. Int -> [a] -> [a]
take (Int
pointsInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) ([Point] -> [Point]) -> [Point] -> [Point]
forall a b. (a -> b) -> a -> b
$ (Point -> Point) -> Point -> [Point]
forall a. (a -> a) -> a -> [a]
iterate ((Double -> Double) -> Point -> Point
forall a b. (a -> b) -> (a, a) -> (b, b)
both (Double -> Double -> Double
forall a. Num a => a -> a -> a
+Double
0.1)) (Double
1,Double
0)

{- |
Draw an abstract, filled in and closed curve with this many segments.
-}
someSolidCurve :: Int -> NormalizedPicture
someSolidCurve :: Int -> NormalizedPicture
someSolidCurve Int
points = [Point] -> NormalizedPicture
forall a. Drawable a => [Point] -> a
solidClosedCurve ([Point] -> NormalizedPicture) -> [Point] -> NormalizedPicture
forall a b. (a -> b) -> a -> b
$ Int -> [Point] -> [Point]
forall a. Int -> [a] -> [a]
take (Int
pointsInt -> Int -> Int
forall a. Num a => a -> a -> a
+Int
1) ([Point] -> [Point]) -> [Point] -> [Point]
forall a b. (a -> b) -> a -> b
$ (Point -> Point) -> Point -> [Point]
forall a. (a -> a) -> a -> [a]
iterate ((Double -> Double) -> Point -> Point
forall a b. (a -> b) -> (a, a) -> (b, b)
both (Double -> Double -> Double
forall a. Num a => a -> a -> a
+Double
0.1)) (Double
1,Double
0)