// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package image

import (
	
	
	
)

// A Point is an X, Y coordinate pair. The axes increase right and down.
type Point struct {
	X, Y int
}

// String returns a string representation of p like "(3,4)".
func ( Point) () string {
	return "(" + strconv.Itoa(.X) + "," + strconv.Itoa(.Y) + ")"
}

// Add returns the vector p+q.
func ( Point) ( Point) Point {
	return Point{.X + .X, .Y + .Y}
}

// Sub returns the vector p-q.
func ( Point) ( Point) Point {
	return Point{.X - .X, .Y - .Y}
}

// Mul returns the vector p*k.
func ( Point) ( int) Point {
	return Point{.X * , .Y * }
}

// Div returns the vector p/k.
func ( Point) ( int) Point {
	return Point{.X / , .Y / }
}

// In reports whether p is in r.
func ( Point) ( Rectangle) bool {
	return .Min.X <= .X && .X < .Max.X &&
		.Min.Y <= .Y && .Y < .Max.Y
}

// Mod returns the point q in r such that p.X-q.X is a multiple of r's width
// and p.Y-q.Y is a multiple of r's height.
func ( Point) ( Rectangle) Point {
	,  := .Dx(), .Dy()
	 = .Sub(.Min)
	.X = .X % 
	if .X < 0 {
		.X += 
	}
	.Y = .Y % 
	if .Y < 0 {
		.Y += 
	}
	return .Add(.Min)
}

// Eq reports whether p and q are equal.
func ( Point) ( Point) bool {
	return  == 
}

// ZP is the zero Point.
//
// Deprecated: Use a literal image.Point{} instead.
var ZP Point

// Pt is shorthand for Point{X, Y}.
func (,  int) Point {
	return Point{, }
}

// A Rectangle contains the points with Min.X <= X < Max.X, Min.Y <= Y < Max.Y.
// It is well-formed if Min.X <= Max.X and likewise for Y. Points are always
// well-formed. A rectangle's methods always return well-formed outputs for
// well-formed inputs.
//
// A Rectangle is also an Image whose bounds are the rectangle itself. At
// returns color.Opaque for points in the rectangle and color.Transparent
// otherwise.
type Rectangle struct {
	Min, Max Point
}

// String returns a string representation of r like "(3,4)-(6,5)".
func ( Rectangle) () string {
	return .Min.String() + "-" + .Max.String()
}

// Dx returns r's width.
func ( Rectangle) () int {
	return .Max.X - .Min.X
}

// Dy returns r's height.
func ( Rectangle) () int {
	return .Max.Y - .Min.Y
}

// Size returns r's width and height.
func ( Rectangle) () Point {
	return Point{
		.Max.X - .Min.X,
		.Max.Y - .Min.Y,
	}
}

// Add returns the rectangle r translated by p.
func ( Rectangle) ( Point) Rectangle {
	return Rectangle{
		Point{.Min.X + .X, .Min.Y + .Y},
		Point{.Max.X + .X, .Max.Y + .Y},
	}
}

// Sub returns the rectangle r translated by -p.
func ( Rectangle) ( Point) Rectangle {
	return Rectangle{
		Point{.Min.X - .X, .Min.Y - .Y},
		Point{.Max.X - .X, .Max.Y - .Y},
	}
}

// Inset returns the rectangle r inset by n, which may be negative. If either
// of r's dimensions is less than 2*n then an empty rectangle near the center
// of r will be returned.
func ( Rectangle) ( int) Rectangle {
	if .Dx() < 2* {
		.Min.X = (.Min.X + .Max.X) / 2
		.Max.X = .Min.X
	} else {
		.Min.X += 
		.Max.X -= 
	}
	if .Dy() < 2* {
		.Min.Y = (.Min.Y + .Max.Y) / 2
		.Max.Y = .Min.Y
	} else {
		.Min.Y += 
		.Max.Y -= 
	}
	return 
}

// Intersect returns the largest rectangle contained by both r and s. If the
// two rectangles do not overlap then the zero rectangle will be returned.
func ( Rectangle) ( Rectangle) Rectangle {
	if .Min.X < .Min.X {
		.Min.X = .Min.X
	}
	if .Min.Y < .Min.Y {
		.Min.Y = .Min.Y
	}
	if .Max.X > .Max.X {
		.Max.X = .Max.X
	}
	if .Max.Y > .Max.Y {
		.Max.Y = .Max.Y
	}
	// Letting r0 and s0 be the values of r and s at the time that the method
	// is called, this next line is equivalent to:
	//
	// if max(r0.Min.X, s0.Min.X) >= min(r0.Max.X, s0.Max.X) || likewiseForY { etc }
	if .Empty() {
		return ZR
	}
	return 
}

// Union returns the smallest rectangle that contains both r and s.
func ( Rectangle) ( Rectangle) Rectangle {
	if .Empty() {
		return 
	}
	if .Empty() {
		return 
	}
	if .Min.X > .Min.X {
		.Min.X = .Min.X
	}
	if .Min.Y > .Min.Y {
		.Min.Y = .Min.Y
	}
	if .Max.X < .Max.X {
		.Max.X = .Max.X
	}
	if .Max.Y < .Max.Y {
		.Max.Y = .Max.Y
	}
	return 
}

// Empty reports whether the rectangle contains no points.
func ( Rectangle) () bool {
	return .Min.X >= .Max.X || .Min.Y >= .Max.Y
}

// Eq reports whether r and s contain the same set of points. All empty
// rectangles are considered equal.
func ( Rectangle) ( Rectangle) bool {
	return  ==  || .Empty() && .Empty()
}

// Overlaps reports whether r and s have a non-empty intersection.
func ( Rectangle) ( Rectangle) bool {
	return !.Empty() && !.Empty() &&
		.Min.X < .Max.X && .Min.X < .Max.X &&
		.Min.Y < .Max.Y && .Min.Y < .Max.Y
}

// In reports whether every point in r is in s.
func ( Rectangle) ( Rectangle) bool {
	if .Empty() {
		return true
	}
	// Note that r.Max is an exclusive bound for r, so that r.In(s)
	// does not require that r.Max.In(s).
	return .Min.X <= .Min.X && .Max.X <= .Max.X &&
		.Min.Y <= .Min.Y && .Max.Y <= .Max.Y
}

// Canon returns the canonical version of r. The returned rectangle has minimum
// and maximum coordinates swapped if necessary so that it is well-formed.
func ( Rectangle) () Rectangle {
	if .Max.X < .Min.X {
		.Min.X, .Max.X = .Max.X, .Min.X
	}
	if .Max.Y < .Min.Y {
		.Min.Y, .Max.Y = .Max.Y, .Min.Y
	}
	return 
}

// At implements the Image interface.
func ( Rectangle) (,  int) color.Color {
	if (Point{, }).In() {
		return color.Opaque
	}
	return color.Transparent
}

// Bounds implements the Image interface.
func ( Rectangle) () Rectangle {
	return 
}

// ColorModel implements the Image interface.
func ( Rectangle) () color.Model {
	return color.Alpha16Model
}

// ZR is the zero Rectangle.
//
// Deprecated: Use a literal image.Rectangle{} instead.
var ZR Rectangle

// Rect is shorthand for Rectangle{Pt(x0, y0), Pt(x1, y1)}. The returned
// rectangle has minimum and maximum coordinates swapped if necessary so that
// it is well-formed.
func (, , ,  int) Rectangle {
	if  >  {
		,  = , 
	}
	if  >  {
		,  = , 
	}
	return Rectangle{Point{, }, Point{, }}
}

// mul3NonNeg returns (x * y * z), unless at least one argument is negative or
// if the computation overflows the int type, in which case it returns -1.
func mul3NonNeg( int,  int,  int) int {
	if ( < 0) || ( < 0) || ( < 0) {
		return -1
	}
	,  := bits.Mul64(uint64(), uint64())
	if  != 0 {
		return -1
	}
	,  = bits.Mul64(, uint64())
	if  != 0 {
		return -1
	}
	 := int()
	if ( < 0) || (uint64() != ) {
		return -1
	}
	return 
}

// add2NonNeg returns (x + y), unless at least one argument is negative or if
// the computation overflows the int type, in which case it returns -1.
func add2NonNeg( int,  int) int {
	if ( < 0) || ( < 0) {
		return -1
	}
	 :=  + 
	if  < 0 {
		return -1
	}
	return 
}