package shape

import (
	

	
	
	
)

// The percentage values of the cloud's wide inner box
const CLOUD_WIDE_INNER_X = 0.085
const CLOUD_WIDE_INNER_Y = 0.409
const CLOUD_WIDE_INNER_WIDTH = 0.819
const CLOUD_WIDE_INNER_HEIGHT = 0.548
const CLOUD_WIDE_ASPECT_BOUNDARY = (1 + CLOUD_WIDE_INNER_WIDTH/CLOUD_WIDE_INNER_HEIGHT) / 2

// The percentage values of the cloud's tall inner box
const CLOUD_TALL_INNER_X = 0.228
const CLOUD_TALL_INNER_Y = 0.179
const CLOUD_TALL_INNER_WIDTH = 0.549
const CLOUD_TALL_INNER_HEIGHT = 0.820
const CLOUD_TALL_ASPECT_BOUNDARY = (1 + CLOUD_TALL_INNER_WIDTH/CLOUD_TALL_INNER_HEIGHT) / 2

// The percentage values of the cloud's square inner box
const CLOUD_SQUARE_INNER_X = 0.167
const CLOUD_SQUARE_INNER_Y = 0.335
const CLOUD_SQUARE_INNER_WIDTH = 0.663
const CLOUD_SQUARE_INNER_HEIGHT = 0.663

type shapeCloud struct {
	*baseShape
	innerBoxAspectRatio *float64
}

func ( *geo.Box) Shape {
	 := shapeCloud{
		baseShape: &baseShape{
			Type: CLOUD_TYPE,
			Box:  ,
		},
		innerBoxAspectRatio: go2.Pointer(0.),
	}
	.FullShape = go2.Pointer(Shape())
	return 
}

func ( shapeCloud) () *geo.Box {
	if .innerBoxAspectRatio != nil && *.innerBoxAspectRatio != 0. {
		return .GetInnerBoxForContent(*.innerBoxAspectRatio, 1)
	} else {
		return .GetInnerBoxForContent(.Box.Width, .Box.Height)
	}
}

// we need this since the content's aspect ratio determines which placement is used
func ( shapeCloud) (,  float64) *geo.Box {
	 := .GetInsidePlacement(, , 0, 0)
	 :=  / 
	// aspect ratio and position are computed with given dimensions, but final box size is determined by shape size
	,  = .Box.Width, .Box.Height
	if  > CLOUD_WIDE_ASPECT_BOUNDARY {
		 *= CLOUD_WIDE_INNER_WIDTH
		 *= CLOUD_WIDE_INNER_HEIGHT
	} else if  < CLOUD_TALL_ASPECT_BOUNDARY {
		 *= CLOUD_TALL_INNER_WIDTH
		 *= CLOUD_TALL_INNER_HEIGHT
	} else {
		 *= CLOUD_SQUARE_INNER_WIDTH
		 *= CLOUD_SQUARE_INNER_HEIGHT
	}
	return geo.NewBox(&, , )
}

func ( shapeCloud) ( float64) {
	// only used for cloud
	*.innerBoxAspectRatio = 
}

func ( shapeCloud) (, , ,  float64) (float64, float64) {
	 += 
	 += 
	 :=  / 
	// use the inner box with the closest aspect ratio (wide, tall, or square box)
	if  > CLOUD_WIDE_ASPECT_BOUNDARY {
		return math.Ceil( / CLOUD_WIDE_INNER_WIDTH), math.Ceil( / CLOUD_WIDE_INNER_HEIGHT)
	} else if  < CLOUD_TALL_ASPECT_BOUNDARY {
		return math.Ceil( / CLOUD_TALL_INNER_WIDTH), math.Ceil( / CLOUD_TALL_INNER_HEIGHT)
	} else {
		return math.Ceil( / CLOUD_SQUARE_INNER_WIDTH), math.Ceil( / CLOUD_SQUARE_INNER_HEIGHT)
	}
}

func ( shapeCloud) (, , ,  float64) geo.Point {
	 := .Box
	 += 
	 += 
	 :=  / 
	if  > CLOUD_WIDE_ASPECT_BOUNDARY {
		return *geo.NewPoint(.TopLeft.X+math.Ceil(.Width*CLOUD_WIDE_INNER_X+/2), .TopLeft.Y+math.Ceil(.Height*CLOUD_WIDE_INNER_Y+/2))
	} else if  < CLOUD_TALL_ASPECT_BOUNDARY {
		return *geo.NewPoint(.TopLeft.X+math.Ceil(.Width*CLOUD_TALL_INNER_X+/2), .TopLeft.Y+math.Ceil(.Height*CLOUD_TALL_INNER_Y+/2))
	} else {
		return *geo.NewPoint(.TopLeft.X+math.Ceil(.Width*CLOUD_SQUARE_INNER_X+/2), .TopLeft.Y+math.Ceil(.Height*CLOUD_SQUARE_INNER_Y+/2))
	}
}

func cloudPath( *geo.Box) *svg.SvgPathContext {
	 := svg.NewSVGPathContext(.TopLeft, .Width/834, .Height/523)
	// Note: original path TopLeft=(83, 238), absolute values updated so top left is at 0,0
	.StartAt(.Absolute(137.833, 182.833))
	.C(true, 0, 5.556, -5.556, 11.111, -11.111, 11.111)
	.C(true, -70.833, 6.944, -126.389, 77.778, -126.389, 163.889)
	.C(true, 0, 91.667, 62.5, 165.278, 141.667, 165.278)
	.H(true, 537.5)
	.C(true, 84.723, 0, 154.167, -79.167, 154.167, -175)
	.C(true, 0, -91.667, -63.89, -168.056, -144.444, -173.611)
	.C(true, -5.556, 0, -11.111, -4.167, -12.5, -11.111)
	.C(true, -18.056, -93.055, -101.39, -162.5, -198.611, -162.5)
	.C(true, -63.889, 0, -120.834, 29.167, -156.944, 75)
	.C(true, -4.167, 5.556, -11.111, 6.945, -15.278, 5.556)
	.C(true, -13.889, -5.556, -29.166, -8.333, -45.833, -8.333)
	.C(false, 196.167, 71.722, 143.389, 120.333, 137.833, 182.833)
	.Z()
	return 
}

func ( shapeCloud) () []geo.Intersectable {
	return cloudPath(.Box).Path
}

func ( shapeCloud) () []string {
	return []string{
		cloudPath(.Box).PathData(),
	}
}

func ( shapeCloud) () (,  float64) {
	return defaultPadding, defaultPadding / 2
}