// Copyright 2010 The Freetype-Go Authors. All rights reserved.
// Use of this source code is governed by your choice of either the
// FreeType License or the GNU General Public License version 2 (or
// any later version), both of which can be found in the LICENSE file.

package raster

import (
	"fmt"
	"math"
)

// A Fix32 is a 24.8 fixed point number.
type Fix32 int32

// A Fix64 is a 48.16 fixed point number.
type Fix64 int64

// String returns a human-readable representation of a 24.8 fixed point number.
// For example, the number one-and-a-quarter becomes "1:064".
func (x Fix32) String() string {
	if x < 0 {
		x = -x
		return fmt.Sprintf("-%d:%03d", int32(x/256), int32(x%256))
	}
	return fmt.Sprintf("%d:%03d", int32(x/256), int32(x%256))
}

// String returns a human-readable representation of a 48.16 fixed point number.
// For example, the number one-and-a-quarter becomes "1:16384".
func (x Fix64) String() string {
	if x < 0 {
		x = -x
		return fmt.Sprintf("-%d:%05d", int64(x/65536), int64(x%65536))
	}
	return fmt.Sprintf("%d:%05d", int64(x/65536), int64(x%65536))
}

// maxAbs returns the maximum of abs(a) and abs(b).
func maxAbs(a, b Fix32) Fix32 {
	if a < 0 {
		a = -a
	}
	if b < 0 {
		b = -b
	}
	if a < b {
		return b
	}
	return a
}

// A Point represents a two-dimensional point or vector, in 24.8 fixed point
// format.
type Point struct {
	X, Y Fix32
}

// String returns a human-readable representation of a Point.
func (p Point) String() string {
	return "(" + p.X.String() + ", " + p.Y.String() + ")"
}

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

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

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

// Neg returns the vector -p, or equivalently p rotated by 180 degrees.
func (p Point) Neg() Point {
	return Point{-p.X, -p.Y}
}

// Dot returns the dot product p·q.
func (p Point) Dot(q Point) Fix64 {
	px, py := int64(p.X), int64(p.Y)
	qx, qy := int64(q.X), int64(q.Y)
	return Fix64(px*qx + py*qy)
}

// Len returns the length of the vector p.
func (p Point) Len() Fix32 {
	// TODO(nigeltao): use fixed point math.
	x := float64(p.X)
	y := float64(p.Y)
	return Fix32(math.Sqrt(x*x + y*y))
}

// Norm returns the vector p normalized to the given length, or the zero Point
// if p is degenerate.
func (p Point) Norm(length Fix32) Point {
	d := p.Len()
	if d == 0 {
		return Point{0, 0}
	}
	s, t := int64(length), int64(d)
	x := int64(p.X) * s / t
	y := int64(p.Y) * s / t
	return Point{Fix32(x), Fix32(y)}
}

// Rot45CW returns the vector p rotated clockwise by 45 degrees.
// Note that the Y-axis grows downwards, so {1, 0}.Rot45CW is {1/√2, 1/√2}.
func (p Point) Rot45CW() Point {
	// 181/256 is approximately 1/√2, or sin(π/4).
	px, py := int64(p.X), int64(p.Y)
	qx := (+px - py) * 181 / 256
	qy := (+px + py) * 181 / 256
	return Point{Fix32(qx), Fix32(qy)}
}

// Rot90CW returns the vector p rotated clockwise by 90 degrees.
// Note that the Y-axis grows downwards, so {1, 0}.Rot90CW is {0, 1}.
func (p Point) Rot90CW() Point {
	return Point{-p.Y, p.X}
}

// Rot135CW returns the vector p rotated clockwise by 135 degrees.
// Note that the Y-axis grows downwards, so {1, 0}.Rot135CW is {-1/√2, 1/√2}.
func (p Point) Rot135CW() Point {
	// 181/256 is approximately 1/√2, or sin(π/4).
	px, py := int64(p.X), int64(p.Y)
	qx := (-px - py) * 181 / 256
	qy := (+px - py) * 181 / 256
	return Point{Fix32(qx), Fix32(qy)}
}

// Rot45CCW returns the vector p rotated counter-clockwise by 45 degrees.
// Note that the Y-axis grows downwards, so {1, 0}.Rot45CCW is {1/√2, -1/√2}.
func (p Point) Rot45CCW() Point {
	// 181/256 is approximately 1/√2, or sin(π/4).
	px, py := int64(p.X), int64(p.Y)
	qx := (+px + py) * 181 / 256
	qy := (-px + py) * 181 / 256
	return Point{Fix32(qx), Fix32(qy)}
}

// Rot90CCW returns the vector p rotated counter-clockwise by 90 degrees.
// Note that the Y-axis grows downwards, so {1, 0}.Rot90CCW is {0, -1}.
func (p Point) Rot90CCW() Point {
	return Point{p.Y, -p.X}
}

// Rot135CCW returns the vector p rotated counter-clockwise by 135 degrees.
// Note that the Y-axis grows downwards, so {1, 0}.Rot135CCW is {-1/√2, -1/√2}.
func (p Point) Rot135CCW() Point {
	// 181/256 is approximately 1/√2, or sin(π/4).
	px, py := int64(p.X), int64(p.Y)
	qx := (-px + py) * 181 / 256
	qy := (-px - py) * 181 / 256
	return Point{Fix32(qx), Fix32(qy)}
}

// An Adder accumulates points on a curve.
type Adder interface {
	// Start starts a new curve at the given point.
	Start(a Point)
	// Add1 adds a linear segment to the current curve.
	Add1(b Point)
	// Add2 adds a quadratic segment to the current curve.
	Add2(b, c Point)
	// Add3 adds a cubic segment to the current curve.
	Add3(b, c, d Point)
}

// A Path is a sequence of curves, and a curve is a start point followed by a
// sequence of linear, quadratic or cubic segments.
type Path []Fix32

// String returns a human-readable representation of a Path.
func (p Path) String() string {
	s := ""
	for i := 0; i < len(p); {
		if i != 0 {
			s += " "
		}
		switch p[i] {
		case 0:
			s += "S0" + fmt.Sprint([]Fix32(p[i+1:i+3]))
			i += 4
		case 1:
			s += "A1" + fmt.Sprint([]Fix32(p[i+1:i+3]))
			i += 4
		case 2:
			s += "A2" + fmt.Sprint([]Fix32(p[i+1:i+5]))
			i += 6
		case 3:
			s += "A3" + fmt.Sprint([]Fix32(p[i+1:i+7]))
			i += 8
		default:
			panic("freetype/raster: bad path")
		}
	}
	return s
}

// grow adds n elements to p.
func (p *Path) grow(n int) {
	n += len(*p)
	if n > cap(*p) {
		old := *p
		*p = make([]Fix32, n, 2*n+8)
		copy(*p, old)
		return
	}
	*p = (*p)[0:n]
}

// Clear cancels any previous calls to p.Start or p.AddXxx.
func (p *Path) Clear() {
	*p = (*p)[0:0]
}

// Start starts a new curve at the given point.
func (p *Path) Start(a Point) {
	n := len(*p)
	p.grow(4)
	(*p)[n] = 0
	(*p)[n+1] = a.X
	(*p)[n+2] = a.Y
	(*p)[n+3] = 0
}

// Add1 adds a linear segment to the current curve.
func (p *Path) Add1(b Point) {
	n := len(*p)
	p.grow(4)
	(*p)[n] = 1
	(*p)[n+1] = b.X
	(*p)[n+2] = b.Y
	(*p)[n+3] = 1
}

// Add2 adds a quadratic segment to the current curve.
func (p *Path) Add2(b, c Point) {
	n := len(*p)
	p.grow(6)
	(*p)[n] = 2
	(*p)[n+1] = b.X
	(*p)[n+2] = b.Y
	(*p)[n+3] = c.X
	(*p)[n+4] = c.Y
	(*p)[n+5] = 2
}

// Add3 adds a cubic segment to the current curve.
func (p *Path) Add3(b, c, d Point) {
	n := len(*p)
	p.grow(8)
	(*p)[n] = 3
	(*p)[n+1] = b.X
	(*p)[n+2] = b.Y
	(*p)[n+3] = c.X
	(*p)[n+4] = c.Y
	(*p)[n+5] = d.X
	(*p)[n+6] = d.Y
	(*p)[n+7] = 3
}

// AddPath adds the Path q to p.
func (p *Path) AddPath(q Path) {
	n, m := len(*p), len(q)
	p.grow(m)
	copy((*p)[n:n+m], q)
}

// AddStroke adds a stroked Path.
func (p *Path) AddStroke(q Path, width Fix32, cr Capper, jr Joiner) {
	Stroke(p, q, width, cr, jr)
}

// firstPoint returns the first point in a non-empty Path.
func (p Path) firstPoint() Point {
	return Point{p[1], p[2]}
}

// lastPoint returns the last point in a non-empty Path.
func (p Path) lastPoint() Point {
	return Point{p[len(p)-3], p[len(p)-2]}
}

// addPathReversed adds q reversed to p.
// For example, if q consists of a linear segment from A to B followed by a
// quadratic segment from B to C to D, then the values of q looks like:
// index: 01234567890123
// value: 0AA01BB12CCDD2
// So, when adding q backwards to p, we want to Add2(C, B) followed by Add1(A).
func addPathReversed(p Adder, q Path) {
	if len(q) == 0 {
		return
	}
	i := len(q) - 1
	for {
		switch q[i] {
		case 0:
			return
		case 1:
			i -= 4
			p.Add1(Point{q[i-2], q[i-1]})
		case 2:
			i -= 6
			p.Add2(Point{q[i+2], q[i+3]}, Point{q[i-2], q[i-1]})
		case 3:
			i -= 8
			p.Add3(Point{q[i+4], q[i+5]}, Point{q[i+2], q[i+3]}, Point{q[i-2], q[i-1]})
		default:
			panic("freetype/raster: bad path")
		}
	}
}
