package geo

import 

type Box struct {
	TopLeft *Point
	Width   float64
	Height  float64
}

func ( *Point, ,  float64) *Box {
	return &Box{
		TopLeft: ,
		Width:   ,
		Height:  ,
	}
}

func ( *Box) () *Box {
	if  == nil {
		return nil
	}
	return NewBox(.TopLeft.Copy(), .Width, .Height)
}

func ( *Box) () *Point {
	return NewPoint(.TopLeft.X+.Width/2, .TopLeft.Y+.Height/2)
}

// Intersects returns true if the segment comes within buffer of the box
func ( *Box) ( Segment,  float64) bool {
	 := NewPoint(.TopLeft.X-, .TopLeft.Y-)
	 := NewPoint(.X+.Width+*2, .Y)
	 := NewPoint(.X, .Y+.Height+*2)
	 := NewPoint(.X, .Y)

	if  := IntersectionPoint(.Start, .End, , );  != nil {
		return true
	}
	if  := IntersectionPoint(.Start, .End, , );  != nil {
		return true
	}
	if  := IntersectionPoint(.Start, .End, , );  != nil {
		return true
	}
	if  := IntersectionPoint(.Start, .End, , );  != nil {
		return true
	}
	return false
}

func ( *Box) ( Segment) []*Point {
	 := []*Point{}

	 := .TopLeft
	 := NewPoint(.X+.Width, .Y)
	 := NewPoint(.X, .Y+.Height)
	 := NewPoint(.X, .Y)

	if  := IntersectionPoint(.Start, .End, , );  != nil {
		 = append(, )
	}
	if  := IntersectionPoint(.Start, .End, , );  != nil {
		 = append(, )
	}
	if  := IntersectionPoint(.Start, .End, , );  != nil {
		 = append(, )
	}
	if  := IntersectionPoint(.Start, .End, , );  != nil {
		 = append(, )
	}
	return 
}

func ( *Box) () string {
	if  == nil {
		return ""
	}
	return fmt.Sprintf("{TopLeft: %s, Width: %.0f, Height: %.0f}", .TopLeft.ToString(), .Width, .Height)
}

func ( *Box) ( *Point) bool {
	return !(.X < .TopLeft.X || .TopLeft.X+.Width < .X ||
		.Y < .TopLeft.Y || .TopLeft.Y+.Height < .Y)
}

func ( Box) ( Box) bool {
	// https://silentmatt.com/rectangle-intersection/
	return (.TopLeft.X < (.TopLeft.X + .Width)) && ((.TopLeft.X + .Width) > .TopLeft.X) &&
		(.TopLeft.Y < (.TopLeft.Y + .Height)) && ((.TopLeft.Y + .Height) > .TopLeft.Y)
}