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

package draw

import "image"

// A Color represents a color with 8-bit R, G, B, and A values,
// packed into a uint32—0xRRGGBBAA—so that comparison
// is defined on colors.
// Color implements image.Color.
// Color also implements image.Image: it is a
// 10⁹x10⁹-pixel image of uniform color.
type Color uint32

// Check that Color implements image.Color and image.Image
var _ image.Color = Black
var _ image.Image = Black

var (
	Opaque        Color = 0xFFFFFFFF
	Transparent   Color = 0x00000000
	Black         Color = 0x000000FF
	White         Color = 0xFFFFFFFF
	Red           Color = 0xFF0000FF
	Green         Color = 0x00FF00FF
	Blue          Color = 0x0000FFFF
	Cyan          Color = 0x00FFFFFF
	Magenta       Color = 0xFF00FFFF
	Yellow        Color = 0xFFFF00FF
	PaleYellow    Color = 0xFFFFAAFF
	DarkYellow    Color = 0xEEEE9EFF
	DarkGreen     Color = 0x448844FF
	PaleGreen     Color = 0xAAFFAAFF
	MedGreen      Color = 0x88CC88FF
	DarkBlue      Color = 0x000055FF
	PaleBlueGreen Color = 0xAAFFFFFF
	PaleBlue      Color = 0x0000BBFF
	BlueGreen     Color = 0x008888FF
	GreyGreen     Color = 0x55AAAAFF
	PaleGreyGreen Color = 0x9EEEEEFF
	YellowGreen   Color = 0x99994CFF
	MedBlue       Color = 0x000099FF
	GreyBlue      Color = 0x005DBBFF
	PaleGreyBlue  Color = 0x4993DDFF
	PurpleBlue    Color = 0x8888CCFF
)

func (c Color) RGBA() (r, g, b, a uint32) {
	x := uint32(c)
	r, g, b, a = x>>24, (x>>16)&0xFF, (x>>8)&0xFF, x&0xFF
	r |= r << 8
	g |= g << 8
	b |= b << 8
	a |= a << 8
	return
}

// SetAlpha returns the color obtained by changing
// c's alpha value to a and scaling r, g, and b appropriately.
func (c Color) SetAlpha(a uint8) Color {
	r, g, b, oa := c>>24, (c>>16)&0xFF, (c>>8)&0xFF, c&0xFF
	if oa == 0 {
		return 0
	}
	r = r * Color(a) / oa
	if r < 0 {
		r = 0
	}
	if r > 0xFF {
		r = 0xFF
	}
	g = g * Color(a) / oa
	if g < 0 {
		g = 0
	}
	if g > 0xFF {
		g = 0xFF
	}
	b = b * Color(a) / oa
	if b < 0 {
		b = 0
	}
	if b > 0xFF {
		b = 0xFF
	}
	return r<<24 | g<<16 | b<<8 | Color(a)
}

func (c Color) Width() int { return 1e9 }

func (c Color) Height() int { return 1e9 }

func (c Color) At(x, y int) image.Color { return c }

func toColor(color image.Color) image.Color {
	if c, ok := color.(Color); ok {
		return c
	}
	r, g, b, a := color.RGBA()
	return Color(r>>8<<24 | g>>8<<16 | b>>8<<8 | a>>8)
}

func (c Color) ColorModel() image.ColorModel { return image.ColorModelFunc(toColor) }
