package types

import (
	"encoding/binary"
	"io"
)

// Color represents an RGB color value (3 bytes) matching EQ2's format
type Color struct {
	R uint8
	G uint8
	B uint8
}

// NewColor creates a new Color from RGB values
func NewColor(r, g, b uint8) Color {
	return Color{R: r, G: g, B: b}
}

// NewColorFromUint32 creates a Color from a packed uint32 (ignores alpha, uses 0x00RRGGBB)
func NewColorFromUint32(packed uint32) Color {
	return Color{
		R: uint8((packed >> 16) & 0xFF),
		G: uint8((packed >> 8) & 0xFF),
		B: uint8(packed & 0xFF),
	}
}

// ToUint32 converts the color to a packed uint32 (0x00RRGGBB for compatibility)
func (c Color) ToUint32() uint32 {
	return uint32(c.R)<<16 | uint32(c.G)<<8 | uint32(c.B)
}

// Serialize writes the color as 3 bytes (RGB) to a writer
func (c Color) Serialize(w io.Writer) error {
	if err := binary.Write(w, binary.LittleEndian, c.R); err != nil {
		return err
	}
	if err := binary.Write(w, binary.LittleEndian, c.G); err != nil {
		return err
	}
	return binary.Write(w, binary.LittleEndian, c.B)
}

// SerializeToBytes writes the color as 3 bytes to a byte slice at the given offset
func (c Color) SerializeToBytes(dest []byte, offset *uint32) {
	dest[*offset] = c.R
	dest[*offset+1] = c.G
	dest[*offset+2] = c.B
	*offset += 3
}

// Size returns the serialized size of the color (always 3 bytes)
func (c Color) Size() uint32 {
	return 3
}

// Deserialize reads a color (3 bytes) from a reader
func (c *Color) Deserialize(r io.Reader) error {
	if err := binary.Read(r, binary.LittleEndian, &c.R); err != nil {
		return err
	}
	if err := binary.Read(r, binary.LittleEndian, &c.G); err != nil {
		return err
	}
	return binary.Read(r, binary.LittleEndian, &c.B)
}

// EQ2Color is an alias for Color specifically for EQ2 packets
// EQ2 sometimes uses different color formats, this allows for customization
type EQ2Color Color

// Serialize writes the EQ2 color as a uint32 to a writer
func (c EQ2Color) Serialize(w io.Writer) error {
	return Color(c).Serialize(w)
}

// SerializeToBytes writes the EQ2 color to a byte slice
func (c EQ2Color) SerializeToBytes(dest []byte, offset *uint32) {
	Color(c).SerializeToBytes(dest, offset)
}

// Size returns the serialized size (always 4 bytes)
func (c EQ2Color) Size() uint32 {
	return 4
}

// Deserialize reads an EQ2 color from a reader
func (c *EQ2Color) Deserialize(r io.Reader) error {
	color := (*Color)(c)
	return color.Deserialize(r)
}