package screen

import (
	"fmt"
	"image"
	"image/color"
)

/*
See:

	https://mrob.com/pub/xapple2/colors.html
	https://archive.org/details/IIgs_2523063_Master_Color_Values
*/
var ntscColorMap = [16]color.Color{
	color.RGBA{0, 0, 0, 255},       // Black
	color.RGBA{227, 30, 96, 255},   // Magenta
	color.RGBA{96, 78, 189, 255},   // Dark Blue
	color.RGBA{255, 68, 253, 255},  // Purple
	color.RGBA{0, 163, 96, 255},    // Dark Green
	color.RGBA{156, 156, 156, 255}, // Grey 1
	color.RGBA{20, 207, 253, 255},  // Medium Blue
	color.RGBA{208, 195, 255, 255}, // Light Blue
	color.RGBA{96, 114, 3, 255},    // Brown
	color.RGBA{255, 106, 60, 255},  // Orange
	color.RGBA{156, 156, 156, 255}, // Grey 2
	color.RGBA{255, 160, 208, 255}, // Pink
	color.RGBA{20, 245, 60, 255},   // Green
	color.RGBA{208, 221, 141, 255}, // Yellow
	color.RGBA{114, 255, 208, 255}, // Aquamarine
	color.RGBA{255, 255, 255, 255}, // White
}

var attenuatedColorMap = buildAttenuatedColorMap(ntscColorMap)

func buildAttenuatedColorMap(colorMap [16]color.Color) [16]color.Color {
	colors := [16]color.Color{}
	for i := 0; i < len(colorMap); i++ {
		r, g, b, _ := colorMap[i].RGBA()
		colors[i] = color.RGBA64{
			uint16(4 * r / 5), uint16(4 * g / 5), uint16(4 * b / 5),
			65535,
		}
	}
	return colors
}

/*
var rgbColorMap = [16]color.Color{
	color.RGBA{0, 0, 0, 255},       // Black
	color.RGBA{221, 0, 51, 255},    // Magenta
	color.RGBA{0, 0, 153, 255},     // Dark Blue
	color.RGBA{221, 34, 221, 255},  // Purple
	color.RGBA{0, 119, 34, 255},    // Dark Green
	color.RGBA{85, 85, 85, 255},    // Grey 1
	color.RGBA{34, 34, 255, 255},   // Medium Blue
	color.RGBA{102, 170, 255, 255}, // Light Blue
	color.RGBA{136, 85, 0, 255},    // Brown
	color.RGBA{255, 102, 0, 255},   // Orange
	color.RGBA{170, 170, 170, 255}, // Grey 2
	color.RGBA{255, 153, 136, 255}, // Pink
	color.RGBA{17, 221, 0, 255},    // Green
	color.RGBA{255, 255, 0, 255},   // Yellow
	color.RGBA{68, 255, 153, 255},  // Aquamarine
	color.RGBA{255, 255, 255, 255}, // White
}
*/

func filterNTSCColor(in *image.RGBA, mask *image.Alpha, screenMode int) *image.RGBA {
	colorMap := ntscColorMap // or rgbColorMap
	colorMapLow := ntscColorMap
	if screenMode == ScreenModeNTSC {
		colorMapLow = attenuatedColorMap
	}

	b := in.Bounds()
	width := b.Dx()
	height := b.Dy()
	size := image.Rect(0, 0, width+4, height)
	out := image.NewRGBA(size)

	if width < 2*hiResWidth {
		panic(fmt.Sprintf("The image has width %v. We can't apply the NTSC filter.", width))
	}

	for y := 0; y < height; y++ {
		// We store the last four bits. We start with 0000
		v := 0
		for x := 0; x < width; x++ {
			cIn := in.At(x, y)
			r, _, _, _ := cIn.RGBA()

			pos := 1 << uint(x%4)
			if r != 0 {
				v |= pos
			} else {
				v &^= pos
			}

			var cOut color.Color
			if r != 0 {
				cOut = colorMap[v]
			} else {
				cOut = colorMapLow[v]
			}
			if mask != nil {
				// RGB mode7
				_, _, _, a := mask.At(x, y).RGBA()
				if a > 0 {
					cOut = cIn
				}
			}

			out.Set(x, y, cOut)
		}

		// We fade for the last three positions
		for x := width; x < width+4; x++ {
			v >>= 1
			cOut := colorMap[v]
			out.Set(x, y, cOut)
		}
	}
	return out
}
