// Copyright 2016 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 iconvg

import (
	"image/color"
)

func validAlphaPremulColor(c color.RGBA) bool {
	return c.R <= c.A && c.G <= c.A && c.B <= c.A
}

// ColorType distinguishes types of Colors.
type ColorType uint8

const (
	// ColorTypeRGBA is a direct RGBA color.
	ColorTypeRGBA ColorType = iota

	// ColorTypePaletteIndex is an indirect color, indexing the custom palette.
	ColorTypePaletteIndex

	// ColorTypeCReg is an indirect color, indexing the CREG color registers.
	ColorTypeCReg

	// ColorTypeBlend is an indirect color, blending two other colors.
	ColorTypeBlend
)

// Color is an IconVG color, whose RGBA values can depend on context. Some
// Colors are direct RGBA values. Other Colors are indirect, referring to an
// index of the custom palette, a color register of the decoder virtual
// machine, or a blend of two other Colors.
//
// See the "Colors" section in the package documentation for details.
type Color struct {
	typ  ColorType
	data color.RGBA
}

func (c Color) rgba() color.RGBA         { return c.data }
func (c Color) paletteIndex() uint8      { return c.data.R }
func (c Color) cReg() uint8              { return c.data.R }
func (c Color) blend() (t, c0, c1 uint8) { return c.data.R, c.data.G, c.data.B }

// Resolve resolves the Color's RGBA value, given its context: the custom
// palette and the color registers of the decoder virtual machine.
func (c Color) Resolve(pal *Palette, cReg *[64]color.RGBA) color.RGBA {
	switch c.typ {
	case ColorTypeRGBA:
		return c.rgba()
	case ColorTypePaletteIndex:
		return pal[c.paletteIndex()&0x3f]
	case ColorTypeCReg:
		return cReg[c.cReg()&0x3f]
	}
	t, c0, c1 := c.blend()
	p, q := uint32(255-t), uint32(t)
	rgba0 := decodeColor1(c0).Resolve(pal, cReg)
	rgba1 := decodeColor1(c1).Resolve(pal, cReg)
	return color.RGBA{
		uint8(((p * uint32(rgba0.R)) + q*uint32(rgba1.R) + 128) / 255),
		uint8(((p * uint32(rgba0.G)) + q*uint32(rgba1.G) + 128) / 255),
		uint8(((p * uint32(rgba0.B)) + q*uint32(rgba1.B) + 128) / 255),
		uint8(((p * uint32(rgba0.A)) + q*uint32(rgba1.A) + 128) / 255),
	}
}

// RGBAColor returns a direct Color.
func RGBAColor(c color.RGBA) Color { return Color{ColorTypeRGBA, c} }

// PaletteIndexColor returns an indirect Color referring to an index of the
// custom palette.
func PaletteIndexColor(i uint8) Color { return Color{ColorTypePaletteIndex, color.RGBA{R: i & 0x3f}} }

// CRegColor returns an indirect Color referring to a color register of the
// decoder virtual machine.
func CRegColor(i uint8) Color { return Color{ColorTypeCReg, color.RGBA{R: i & 0x3f}} }

// BlendColor returns an indirect Color that blends two other Colors. Those two
// other Colors must both be encodable as a 1 byte color.
//
// To blend a Color that is not encodable as a 1 byte color, first load that
// Color into a CREG color register, then call CRegColor to produce a Color
// that is encodable as a 1 byte color.
//
// See the "Colors" section in the package documentation for details.
func BlendColor(t, c0, c1 uint8) Color { return Color{ColorTypeBlend, color.RGBA{R: t, G: c0, B: c1}} }

func decodeColor1(x byte) Color {
	if x >= 0x80 {
		if x >= 0xc0 {
			return CRegColor(x)
		} else {
			return PaletteIndexColor(x)
		}
	}
	if x >= 125 {
		switch x - 125 {
		case 0:
			return RGBAColor(color.RGBA{0xc0, 0xc0, 0xc0, 0xc0})
		case 1:
			return RGBAColor(color.RGBA{0x80, 0x80, 0x80, 0x80})
		case 2:
			return RGBAColor(color.RGBA{0x00, 0x00, 0x00, 0x00})
		}
	}
	blue := dc1Table[x%5]
	x = x / 5
	green := dc1Table[x%5]
	x = x / 5
	red := dc1Table[x]
	return RGBAColor(color.RGBA{red, green, blue, 0xff})
}

var dc1Table = [5]byte{0x00, 0x40, 0x80, 0xc0, 0xff}

func is1(u uint8) bool { return u&0x3f == 0 || u == 0xff }

func encodeColor1(c Color) (x byte, ok bool) {
	switch c.typ {
	case ColorTypeRGBA:
		if c.data.A != 0xff {
			switch c.data {
			case color.RGBA{0x00, 0x00, 0x00, 0x00}:
				return 127, true
			case color.RGBA{0x80, 0x80, 0x80, 0x80}:
				return 126, true
			case color.RGBA{0xc0, 0xc0, 0xc0, 0xc0}:
				return 125, true
			}
		} else if is1(c.data.R) && is1(c.data.G) && is1(c.data.B) && is1(c.data.A) {
			r := c.data.R / 0x3f
			g := c.data.G / 0x3f
			b := c.data.B / 0x3f
			return 25*r + 5*g + b, true
		}
	case ColorTypePaletteIndex:
		return c.data.R | 0x80, true
	case ColorTypeCReg:
		return c.data.R | 0xc0, true
	}
	return 0, false
}

func is2(u uint8) bool { return u%0x11 == 0 }

func encodeColor2(c Color) (x [2]byte, ok bool) {
	if c.typ == ColorTypeRGBA && is2(c.data.R) && is2(c.data.G) && is2(c.data.B) && is2(c.data.A) {
		return [2]byte{
			(c.data.R/0x11)<<4 | (c.data.G / 0x11),
			(c.data.B/0x11)<<4 | (c.data.A / 0x11),
		}, true
	}
	return [2]byte{}, false
}

func encodeColor3Direct(c Color) (x [3]byte, ok bool) {
	if c.typ == ColorTypeRGBA && c.data.A == 0xff {
		return [3]byte{c.data.R, c.data.G, c.data.B}, true
	}
	return [3]byte{}, false
}

func encodeColor4(c Color) (x [4]byte, ok bool) {
	if c.typ == ColorTypeRGBA {
		return [4]byte{c.data.R, c.data.G, c.data.B, c.data.A}, true
	}
	return [4]byte{}, false
}

func encodeColor3Indirect(c Color) (x [3]byte, ok bool) {
	if c.typ == ColorTypeBlend {
		return [3]byte{c.data.R, c.data.G, c.data.B}, true
	}
	return [3]byte{}, false
}
