// Copyright 2009 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.

// The image package implements a basic 2-D image library.
package image

// An Image is a rectangular grid of Colors drawn from a ColorModel.
type Image interface {
	ColorModel() ColorModel;
	Width() int;
	Height() int;
	// At(0, 0) returns the upper-left pixel of the grid.
	// At(Width()-1, Height()-1) returns the lower-right pixel.
	At(x, y int) Color;
}

// An RGBA is an in-memory image backed by a 2-D slice of RGBAColor values.
type RGBA struct {
	// The Pixel field's indices are y first, then x, so that At(x, y) == Pixel[y][x].
	Pixel [][]RGBAColor;
}

func (p *RGBA) ColorModel() ColorModel {
	return RGBAColorModel;
}

func (p *RGBA) Width() int {
	if len(p.Pixel) == 0 {
		return 0;
	}
	return len(p.Pixel[0]);
}

func (p *RGBA) Height() int {
	return len(p.Pixel);
}

func (p *RGBA) At(x, y int) Color {
	return p.Pixel[y][x];
}

func (p *RGBA) Set(x, y int, c Color) {
	p.Pixel[y][x] = toRGBAColor(c).(RGBAColor);
}

// NewRGBA returns a new RGBA with the given width and height.
func NewRGBA(w, h int) *RGBA {
	pixel := make([][]RGBAColor, h);
	for y := 0; y < int(h); y++ {
		pixel[y] = make([]RGBAColor, w);
	}
	return &RGBA{ pixel };
}

// An RGBA64 is an in-memory image backed by a 2-D slice of RGBA64Color values.
type RGBA64 struct {
	// The Pixel field's indices are y first, then x, so that At(x, y) == Pixel[y][x].
	Pixel [][]RGBA64Color;
}

func (p *RGBA64) ColorModel() ColorModel {
	return RGBA64ColorModel;
}

func (p *RGBA64) Width() int {
	if len(p.Pixel) == 0 {
		return 0;
	}
	return len(p.Pixel[0]);
}

func (p *RGBA64) Height() int {
	return len(p.Pixel);
}

func (p *RGBA64) At(x, y int) Color {
	return p.Pixel[y][x];
}

func (p *RGBA64) Set(x, y int, c Color) {
	p.Pixel[y][x] = toRGBA64Color(c).(RGBA64Color);
}

// NewRGBA64 returns a new RGBA64 with the given width and height.
func NewRGBA64(w, h int) *RGBA64 {
	pixel := make([][]RGBA64Color, h);
	for y := 0; y < int(h); y++ {
		pixel[y] = make([]RGBA64Color, w);
	}
	return &RGBA64{ pixel };
}

// A NRGBA is an in-memory image backed by a 2-D slice of NRGBAColor values.
type NRGBA struct {
	// The Pixel field's indices are y first, then x, so that At(x, y) == Pixel[y][x].
	Pixel [][]NRGBAColor;
}

func (p *NRGBA) ColorModel() ColorModel {
	return NRGBAColorModel;
}

func (p *NRGBA) Width() int {
	if len(p.Pixel) == 0 {
		return 0;
	}
	return len(p.Pixel[0]);
}

func (p *NRGBA) Height() int {
	return len(p.Pixel);
}

func (p *NRGBA) At(x, y int) Color {
	return p.Pixel[y][x];
}

func (p *NRGBA) Set(x, y int, c Color) {
	p.Pixel[y][x] = toNRGBAColor(c).(NRGBAColor);
}

// NewNRGBA returns a new NRGBA with the given width and height.
func NewNRGBA(w, h int) *NRGBA {
	pixel := make([][]NRGBAColor, h);
	for y := 0; y < int(h); y++ {
		pixel[y] = make([]NRGBAColor, w);
	}
	return &NRGBA{ pixel };
}

// A NRGBA64 is an in-memory image backed by a 2-D slice of NRGBA64Color values.
type NRGBA64 struct {
	// The Pixel field's indices are y first, then x, so that At(x, y) == Pixel[y][x].
	Pixel [][]NRGBA64Color;
}

func (p *NRGBA64) ColorModel() ColorModel {
	return NRGBA64ColorModel;
}

func (p *NRGBA64) Width() int {
	if len(p.Pixel) == 0 {
		return 0;
	}
	return len(p.Pixel[0]);
}

func (p *NRGBA64) Height() int {
	return len(p.Pixel);
}

func (p *NRGBA64) At(x, y int) Color {
	return p.Pixel[y][x];
}

func (p *NRGBA64) Set(x, y int, c Color) {
	p.Pixel[y][x] = toNRGBA64Color(c).(NRGBA64Color);
}

// NewNRGBA64 returns a new NRGBA64 with the given width and height.
func NewNRGBA64(w, h int) *NRGBA64 {
	pixel := make([][]NRGBA64Color, h);
	for y := 0; y < int(h); y++ {
		pixel[y] = make([]NRGBA64Color, w);
	}
	return &NRGBA64{ pixel };
}

// A PalettedColorModel represents a fixed palette of colors.
type PalettedColorModel []Color;

func diff(a, b uint32) uint32 {
	if a > b {
		return a - b;
	}
	return b - a;
}

// Convert returns the palette color closest to c in Euclidean R,G,B space.
func (p PalettedColorModel) Convert(c Color) Color {
	if len(p) == 0 {
		return nil;
	}
	// TODO(nigeltao): Revisit the "pick the palette color which minimizes sum-squared-difference"
	// algorithm when the premultiplied vs unpremultiplied issue is resolved.
	// Currently, we only compare the R, G and B values, and ignore A.
	cr, cg, cb, _ := c.RGBA();
	// Shift by 17 bits to avoid potential uint32 overflow in sum-squared-difference.
	cr >>= 17;
	cg >>= 17;
	cb >>= 17;
	result := Color(nil);
	bestSSD := uint32(1<<32 - 1);
	for _, v := range p {
		vr, vg, vb, _ := v.RGBA();
		vr >>= 17;
		vg >>= 17;
		vb >>= 17;
		dr, dg, db := diff(cr, vr), diff(cg, vg), diff(cb, vb);
		ssd := (dr * dr) + (dg * dg) + (db * db);
		if ssd < bestSSD {
			bestSSD = ssd;
			result = v;
		}
	}
	return result;
}

// A Paletted is an in-memory image backed by a 2-D slice of uint8 values and a PalettedColorModel.
type Paletted struct {
	// The Pixel field's indices are y first, then x, so that At(x, y) == Palette[Pixel[y][x]].
	Pixel [][]uint8;
	Palette PalettedColorModel;
}

func (p *Paletted) ColorModel() ColorModel {
	return p.Palette;
}

func (p *Paletted) Width() int {
	if len(p.Pixel) == 0 {
		return 0;
	}
	return len(p.Pixel[0]);
}

func (p *Paletted) Height() int {
	return len(p.Pixel);
}

func (p *Paletted) At(x, y int) Color {
	return p.Palette[p.Pixel[y][x]];
}

func (p *Paletted) SetColorIndex(x, y int, index uint8) {
	p.Pixel[y][x] = index;
}

// NewPaletted returns a new Paletted with the given width, height and palette.
func NewPaletted(w, h int, m PalettedColorModel) *Paletted {
	pixel := make([][]uint8, h);
	for y := 0; y < int(h); y++ {
		pixel[y] = make([]uint8, w);
	}
	return &Paletted{ pixel, m };
}

