// 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"
	"math"
)

// buffer holds an encoded IconVG graphic.
//
// The decodeXxx methods return the decoded value and an integer n, the number
// of bytes that value was encoded in. They return n == 0 if an error occurred.
//
// The encodeXxx methods append to the buffer, modifying the slice in place.
type buffer []byte

func (b buffer) decodeNatural() (u uint32, n int) {
	if len(b) < 1 {
		return 0, 0
	}
	x := b[0]
	if x&0x01 == 0 {
		return uint32(x) >> 1, 1
	}
	if x&0x02 == 0 {
		if len(b) >= 2 {
			y := uint16(b[0]) | uint16(b[1])<<8
			return uint32(y) >> 2, 2
		}
		return 0, 0
	}
	if len(b) >= 4 {
		y := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
		return y >> 2, 4
	}
	return 0, 0
}

// decodeNaturalFFV1 is like decodeNatural but for File Format Version 1. See
// https://github.com/google/iconvg/issues/33
func (b buffer) decodeNaturalFFV1() (u uint32, n int) {
	if len(b) < 1 {
		return 0, 0
	}
	x := b[0]
	if x&0x01 != 0 {
		return uint32(x) >> 1, 1
	}
	if x&0x02 != 0 {
		if len(b) >= 2 {
			y := uint16(b[0]) | uint16(b[1])<<8
			return uint32(y) >> 2, 2
		}
		return 0, 0
	}
	if len(b) >= 4 {
		y := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
		return y >> 2, 4
	}
	return 0, 0
}

func (b buffer) decodeReal() (f float32, n int) {
	switch u, n := b.decodeNatural(); n {
	case 0:
		return 0, n
	case 1:
		return float32(u), n
	case 2:
		return float32(u), n
	default:
		return math.Float32frombits(u << 2), n
	}
}

func (b buffer) decodeCoordinate() (f float32, n int) {
	switch u, n := b.decodeNatural(); n {
	case 0:
		return 0, n
	case 1:
		return float32(int32(u) - 64), n
	case 2:
		return float32(int32(u)-64*128) / 64, n
	default:
		return math.Float32frombits(u << 2), n
	}
}

func (b buffer) decodeZeroToOne() (f float32, n int) {
	switch u, n := b.decodeNatural(); n {
	case 0:
		return 0, n
	case 1:
		return float32(u) / 120, n
	case 2:
		return float32(u) / 15120, n
	default:
		return math.Float32frombits(u << 2), n
	}
}

func (b buffer) decodeColor1() (c Color, n int) {
	if len(b) < 1 {
		return Color{}, 0
	}
	return decodeColor1(b[0]), 1
}

func (b buffer) decodeColor2() (c Color, n int) {
	if len(b) < 2 {
		return Color{}, 0
	}
	return RGBAColor(color.RGBA{
		R: 0x11 * (b[0] >> 4),
		G: 0x11 * (b[0] & 0x0f),
		B: 0x11 * (b[1] >> 4),
		A: 0x11 * (b[1] & 0x0f),
	}), 2
}

func (b buffer) decodeColor3Direct() (c Color, n int) {
	if len(b) < 3 {
		return Color{}, 0
	}
	return RGBAColor(color.RGBA{
		R: b[0],
		G: b[1],
		B: b[2],
		A: 0xff,
	}), 3
}

func (b buffer) decodeColor4() (c Color, n int) {
	if len(b) < 4 {
		return Color{}, 0
	}
	return RGBAColor(color.RGBA{
		R: b[0],
		G: b[1],
		B: b[2],
		A: b[3],
	}), 4
}

func (b buffer) decodeColor3Indirect() (c Color, n int) {
	if len(b) < 3 {
		return Color{}, 0
	}
	return BlendColor(b[0], b[1], b[2]), 3
}

func (b *buffer) encodeNatural(u uint32) {
	if u < 1<<7 {
		u = (u << 1)
		*b = append(*b, uint8(u))
		return
	}
	if u < 1<<14 {
		u = (u << 2) | 1
		*b = append(*b, uint8(u), uint8(u>>8))
		return
	}
	u = (u << 2) | 3
	*b = append(*b, uint8(u), uint8(u>>8), uint8(u>>16), uint8(u>>24))
}

// encodeNaturalFFV1 is like encodeNatural but for File Format Version 1. See
// https://github.com/google/iconvg/issues/33
func (b *buffer) encodeNaturalFFV1(u uint32) {
	if u < 1<<7 {
		u = (u << 1) | 0x01
		*b = append(*b, uint8(u))
		return
	}
	if u < 1<<14 {
		u = (u << 2) | 0x02
		*b = append(*b, uint8(u), uint8(u>>8))
		return
	}
	u = (u << 2)
	*b = append(*b, uint8(u), uint8(u>>8), uint8(u>>16), uint8(u>>24))
}

func (b *buffer) encodeReal(f float32) int {
	if u := uint32(f); float32(u) == f && u < 1<<14 {
		if u < 1<<7 {
			u = (u << 1)
			*b = append(*b, uint8(u))
			return 1
		}
		u = (u << 2) | 1
		*b = append(*b, uint8(u), uint8(u>>8))
		return 2
	}
	b.encode4ByteReal(f)
	return 4
}

func (b *buffer) encode4ByteReal(f float32) {
	u := math.Float32bits(f)

	// Round the fractional bits (the low 23 bits) to the nearest multiple of
	// 4, being careful not to overflow into the upper bits.
	v := u & 0x007fffff
	if v < 0x007ffffe {
		v += 2
	}
	u = (u & 0xff800000) | v

	// A 4 byte encoding has the low two bits set.
	u |= 0x03
	*b = append(*b, uint8(u), uint8(u>>8), uint8(u>>16), uint8(u>>24))
}

// encode4ByteRealFFV1 is like encode4ByteReal but for File Format Version 1.
// See https://github.com/google/iconvg/issues/33
func (b *buffer) encode4ByteRealFFV1(f float32) {
	u := math.Float32bits(f)

	// Round the fractional bits (the low 23 bits) to the nearest multiple of
	// 4, being careful not to overflow into the upper bits.
	v := u & 0x007fffff
	if v < 0x007ffffe {
		v += 2
	}
	u = (u & 0xff800000) | v

	// A 4 byte encoding has the low two bits unset.
	u &= 0xfffffffc
	*b = append(*b, uint8(u), uint8(u>>8), uint8(u>>16), uint8(u>>24))
}

func (b *buffer) encodeCoordinate(f float32) int {
	if i := int32(f); -64 <= i && i < +64 && float32(i) == f {
		u := uint32(i + 64)
		u = (u << 1)
		*b = append(*b, uint8(u))
		return 1
	}
	if i := int32(f * 64); -128*64 <= i && i < +128*64 && float32(i) == f*64 {
		u := uint32(i + 128*64)
		u = (u << 2) | 1
		*b = append(*b, uint8(u), uint8(u>>8))
		return 2
	}
	b.encode4ByteReal(f)
	return 4
}

// encodeCoordinateFFV1 is like encodeCoordinate but for File Format Version 1.
// See https://github.com/google/iconvg/issues/33
func (b *buffer) encodeCoordinateFFV1(f float32) int {
	if i := int32(f); -64 <= i && i < +64 && float32(i) == f {
		u := uint32(i + 64)
		u = (u << 1) | 0x01
		*b = append(*b, uint8(u))
		return 1
	}
	if i := int32(f * 64); -128*64 <= i && i < +128*64 && float32(i) == f*64 {
		u := uint32(i + 128*64)
		u = (u << 2) | 0x02
		*b = append(*b, uint8(u), uint8(u>>8))
		return 2
	}
	b.encode4ByteRealFFV1(f)
	return 4
}

func (b *buffer) encodeCoordinatePairFFV1(f [2]float32) int {
	n0 := b.encodeCoordinateFFV1(f[0])
	n1 := b.encodeCoordinateFFV1(f[1])
	return n0 + n1
}

func (b *buffer) encodeAngle(f float32) int {
	// Normalize f to the range [0, 1).
	g := float64(f)
	g -= math.Floor(g)
	return b.encodeZeroToOne(float32(g))
}

func (b *buffer) encodeZeroToOne(f float32) int {
	if u := uint32(f * 15120); float32(u) == f*15120 && u < 15120 {
		if u%126 == 0 {
			u = ((u / 126) << 1)
			*b = append(*b, uint8(u))
			return 1
		}
		u = (u << 2) | 1
		*b = append(*b, uint8(u), uint8(u>>8))
		return 2
	}
	b.encode4ByteReal(f)
	return 4
}

func (b *buffer) encodeColor1(c Color) {
	if x, ok := encodeColor1(c); ok {
		*b = append(*b, x)
		return
	}
	// Default to opaque black.
	*b = append(*b, 0x00)
}

func (b *buffer) encodeColor2(c Color) {
	if x, ok := encodeColor2(c); ok {
		*b = append(*b, x[0], x[1])
		return
	}
	// Default to opaque black.
	*b = append(*b, 0x00, 0x0f)
}

func (b *buffer) encodeColor3Direct(c Color) {
	if x, ok := encodeColor3Direct(c); ok {
		*b = append(*b, x[0], x[1], x[2])
		return
	}
	// Default to opaque black.
	*b = append(*b, 0x00, 0x00, 0x00)
}

func (b *buffer) encodeColor4(c Color) {
	if x, ok := encodeColor4(c); ok {
		*b = append(*b, x[0], x[1], x[2], x[3])
		return
	}
	// Default to opaque black.
	*b = append(*b, 0x00, 0x00, 0x00, 0xff)
}

func (b *buffer) encodeColor3Indirect(c Color) {
	if x, ok := encodeColor3Indirect(c); ok {
		*b = append(*b, x[0], x[1], x[2])
		return
	}
	// Default to opaque black.
	*b = append(*b, 0x00, 0x00, 0x00)
}
