using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace DOFerVolumeRenderer
{
	public class ColorPicker
	{
		private Game _game;
		private Texture2D _texture;

		Color[,] _refcolors = new Color[3,4];
	
		public ColorPicker(Game game, int texSize)
		{
			_game = game;
			_texture = new Texture2D(game.GraphicsDevice, texSize, texSize);

			_refcolors[0,0] = new Color(1, 1, 1, 1);
			_refcolors[0,1] = new Color(1, 1, 1, 1);
			_refcolors[0,2] = new Color(1, 1, 1, 1);
			_refcolors[0,3] = new Color(1, 1, 1, 1);
			_refcolors[1,0] = new Color(1, 0, 0, 1);
			_refcolors[1,1] = new Color(0, 1, 0, 1);
			_refcolors[1,2] = new Color(0, 0, 1, 1);
			_refcolors[1,3] = new Color(1, 0, 0, 1);
			_refcolors[2,0] = new Color(0, 0, 0, 1);
			_refcolors[2,1] = new Color(0, 0, 0, 1);
			_refcolors[2,2] = new Color(0, 0, 0, 1);
			_refcolors[2,3] = new Color(0, 0, 0, 1);

			// generate the color
			Color[] texData = new Color[texSize * texSize];
			for (int i = 0; i < texSize; i++)
			{
				for (int j = 0; j < texSize; j++)
				{
					texData[i * texSize + j] = GetColorAtPos((float)j / texSize, (float)i / texSize);
				}
			}
			_texture.SetData<Color>(texData);
		}

		public Color GetColorAtPos(float u, float v)
		{
			int uidx = (int)(u * 3);
			if (uidx < 0) uidx = 0;
			if (uidx >= 3) uidx = 2;

			float dx = (u - 0.333333f * uidx) / 0.33333f;
			
			Color c1 = _refcolors[1, uidx];
			c1 = new Color(c1.R * (1f - dx), c1.G * (1f - dx), c1.B * (1f - dx), 1f);
			Color c2 = _refcolors[1, uidx + 1];
			c2 = new Color(c2.R * (dx), c2.G * (dx), c2.B * (dx), 1f);

			// add interpolated colors
			Color cPure = new Color(c1.R + c2.R, c1.G + c2.G, c1.B + c2.B, 255);

			Color cLumi = cPure;
			if (v < 0.5f)
			{
				// => lighten!
				float dy = v / 0.5f;
				float idy = 1f - dy;
				cLumi = new Color(((float)cPure.R / byte.MaxValue) * dy + idy, ((float)cPure.G / byte.MaxValue) * dy + idy, ((float)cPure.B / byte.MaxValue) * dy + idy, 1f);
			}
			else
			{
				// => darken!
				float dy = 1.0f - (v - 0.5f) / 0.5f;
				cLumi = new Color(((float)cPure.R / byte.MaxValue) * dy, ((float)cPure.G / byte.MaxValue) * dy, ((float)cPure.B / byte.MaxValue) * dy, 1f);
			}
			return cLumi;
		}

		public Texture2D Texture
		{
			get { return _texture; }
		}
	}
}
