package shape

import (
	

	
	
)

const OVAL_AR_LIMIT = 3.

type shapeOval struct {
	*baseShape
}

func ( *geo.Box) Shape {
	 := shapeOval{
		baseShape: &baseShape{
			Type: OVAL_TYPE,
			Box:  ,
		},
	}
	.FullShape = go2.Pointer(Shape())
	return 
}

func ( shapeOval) () *geo.Box {
	 := .Box.Width
	 := .Box.Height
	 := .GetInsidePlacement(, , 0, 0)
	 := .Box.TopLeft.Copy()
	 -= 2 * (.X - .X)
	 -= 2 * (.Y - .Y)
	return geo.NewBox(&, , )
}

func ( shapeOval) (, , ,  float64) (float64, float64) {
	 := float64(float32(math.Atan2(, )))
	// add padding in direction of diagonal so there is padding distance between top left and border
	 :=  + *math.Cos()
	 :=  + *math.Sin()
	// see https://stackoverflow.com/questions/433371/ellipse-bounding-a-rectangle
	,  := math.Ceil(math.Sqrt2*), math.Ceil(math.Sqrt2*)

	// prevent oval from becoming too flat
	,  = LimitAR(, , OVAL_AR_LIMIT)
	return , 
}

func ( shapeOval) (, , ,  float64) geo.Point {
	// showing the top left arc of the ellipse (drawn with '*')
	// ┌──────────────────* ┬
	// │         *        │ │ry
	// │     *┌───────────┤ │ ┬
	// │  *   │           │ │ │sin*r
	// │*     │           │ │ │
	// *──────┴───────────┼ ┴ ┴
	// ├────────rx────────┤
	//        ├───cos*r───┤
	 := .Box.Width / 2
	 := .Box.Height / 2
	 := float64(float32(math.Atan2(, )))
	 := math.Sin()
	 := math.Cos()
	// r is the ellipse radius on the line between node.TopLeft and the ellipse center
	// see https://math.stackexchange.com/questions/432902/how-to-get-the-radius-of-an-ellipse-at-a-specific-angle-by-knowing-its-semi-majo
	 :=  *  / math.Sqrt(math.Pow(*, 2)+math.Pow(*, 2))
	// we want to offset r-padding/2 away from the center
	return *geo.NewPoint(.Box.TopLeft.X+math.Ceil(-*(-/2)), .Box.TopLeft.Y+math.Ceil(-*(-/2)))
}

func ( shapeOval) () []geo.Intersectable {
	return []geo.Intersectable{geo.NewEllipse(.Box.Center(), .Box.Width/2, .Box.Height/2)}
}