package net.beadsproject.touch.world;

import java.awt.Color;
import java.awt.Image;
import java.util.HashMap;

import processing.core.PApplet;
import processing.core.PGraphics;
import processing.core.PImage;

/**
 * A RegionMap provides a map from pixels to regions.
 */
public class RegionMap {
	
	int width, height;	
	private Region[][] pixels;	
		
	public RegionMap(int w, int h)
	{		
		pixels = new Region[w][h];	
		width = w;
		height = h;
	}
		
	public void set(int x, int y, Region r)
	{
		pixels[x][y] = r;
	}
	
	public Region get(int x, int y)
	{
		if (x >= width || y>=width || x<0 || y<0) return null;		
		return pixels[x][y];
	}
	
	public Region getNormalised(float x, float y)
	{
		int xi = (int)(x*width), yi = (int)(y*height);
		xi = Math.max(xi, 0);
		xi = Math.min(xi, width - 1);
		yi = Math.max(yi, 0);
		yi = Math.min(yi, height - 1);
		return pixels[xi][yi];
	}
	
	public void generateFromPGraphics(PGraphics gfx, Region[] regions) 
	{
		gfx.loadPixels();
		for(int i=0;i<gfx.pixels.length;i++)
		{
			int r = i/gfx.width;
			int c = i%gfx.width;
			int pni = gfx.pixels[i];
			
			int in = RegionMap.PGetIndex(pni);
			if (in<0)
				set(c,r,null);
			else
				set(c,r,regions[in]);
		}			
		gfx.updatePixels();
	}	
	
	/**
	 * Create a basic image generated by mapping regions to colours.
	 * @param app
	 * @param colourMap
	 * @return
	 */
	public PImage generatePImage(PApplet app, HashMap<Region,Color> colourMap)
	{
		// generate the PImage
		PImage img = app.createImage(width,height,app.RGB);
		img.loadPixels();
		for(int i=0;i<img.pixels.length;i++)
		{
			int r = i/img.width;
			int c = i%img.width;
			
			if (pixels[c][r]==null) {
				img.pixels[i] = app.color(255,0,255);
			}
			else
			{			
				Color col = colourMap.get(pixels[c][r]); // new Color(Color.HSBtoRGB(pixels[c][r].uniqueValue(), .75f, .75f));
				img.pixels[i] = app.color(col.getRed(),col.getGreen(),col.getBlue());
			}
		}		
		img.updatePixels();
		return img;
	}
	
	/**
	 * Create a basic image generated by mapping regions to colours.
	 * @param app
	 * @param colourMap
	 * @return
	 */
	public PImage generatePImage(PGraphics app, HashMap<Region,Color> colourMap)
	{
		// generate the PImage
		PImage img = new PImage(width,height,app.RGB);
		img.loadPixels();
		for(int i=0;i<img.pixels.length;i++)
		{
			int r = i/img.width;
			int c = i%img.width;
			
			if (pixels[c][r]==null) {
				img.pixels[i] = app.color(255,0,255);
			}
			else
			{			
				Color col = colourMap.get(pixels[c][r]); // new Color(Color.HSBtoRGB(pixels[c][r].uniqueValue(), .75f, .75f));
				img.pixels[i] = app.color(col.getRed(),col.getGreen(),col.getBlue());
			}
		}		
		img.updatePixels();
		return img;
	}
	
	public static void PSetFill(PGraphics gfx, int id)
	{
		int colour = id + 1;
		gfx.fill((colour >> 16)&0xFF, (colour >> 8)&0xFF, colour&0xFF);
	}
	
	public static int PGetIndex(int col)
	{
		int rd = (col >> 16) & 0xFF;
		int gr = (col >> 8) & 0xFF;
		int bl = col & 0xFF;
		
		int in = (int)((rd << 16) | (gr << 8) | bl) - 1;
		return in;
	}
}
