// 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 occured.
//
// 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
}

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))
}

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 < 0x007fffffe {
		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))
}

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
}

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)
}
