// looks over an image (in imagedata format, so we can get at individual pixels)
// makes a table of all unique colors in the image
function extractPalette(imageData) {
	var data = imageData.data;
	
	var palette = [];
	var sourceColor, index, r, g, b;
	for (var y = 0; y < imageData.height; y ++) {
		for (var x = 0; x < imageData.width; x ++) {
			index = (y * imageData.width + x) * 4;
			r = data[index];
			g = data[index + 1];
			b = data[index + 2];
			sourceColor = r << 16 | g << 8 | b; // rgb
			// this combines all the colors into one number, 8 bits per channel

			var found = false;
			if (palette.length > 0) {
				for (var i = 0; i < palette.length; i ++) {
					if (palette[i] == sourceColor) {
						found = true;
					}
				}
			}
			if (!found) { // add new color to palette
				palette.push(sourceColor);
			}
		}
	}

	// force alpha- slot 0 is always transparent

	return palette;
}


function convertToIndexed(imageData, palette) {
	var indexedImage = new Array(imageData.width);
	for (var x = 0; x < imageData.width; x ++) {
		indexedImage[x] = new Array(imageData.height);
	}
	indexedImage.width = imageData.width;
	indexedImage.height = imageData.height;

	var sourceColor, index, r, g, b, found, colorIndex;
	var data = imageData.data;
	for (var y = 0; y < imageData.height; y ++) {
		for (var x = 0; x < imageData.width; x ++) {
			index = (y * imageData.width + x) * 4;
			r = data[index];
			g = data[index + 1];
			b = data[index + 2];
			sourceColor = r << 16 | g << 8 | b; // rgb
			
			// see if this color is in our palette
			found = false;
			colorIndex = -1;
			for (var i = 0; i < palette.length; i ++) {
				if (palette[i] == sourceColor) {
					found = true;
					colorIndex = i;
				}
			}
			if (colorIndex != -1) { // add new color to palette
				indexedImage[x][y] = colorIndex;
			}
		}
	}
		

	return indexedImage;
}


/*
notes:
there are multiple ways this could work:
draw indexed to indexed, palettize once at the end
draw indexed to rgb, palettizing as we draw
this does the latter, but for a fully indexed context it would likely be the former
*/
function drawIndexedToRGB(indexedSource, palette, imageDataTarget, targetX, targetY) {
	var colorIndex, sourceColor;
	var r, g, b;
	var a = 255;
	var data = imageDataTarget.data;
	var index;
	var width = indexedSource.width;
	var height = indexedSource.height;
	for (var y = 0; y < height; y ++) {
		for (var x = 0; x < width; x ++) {
			colorIndex = indexedSource[x][y]; // get color index from indexed image
			
			if (colorIndex != 0) { // 0 is forced alpha
				sourceColor = palette[colorIndex]; // look up the color to use

				// extract colors
				r = (sourceColor >> 16) & 0xff;
				g = (sourceColor >> 8) & 0xff;
				b = (sourceColor) & 0xff;

				// index to draw to
				index = ((targetY + y) * imageDataTarget.width + (targetX + x)) * 4;
				// set the pixel
				data[index] = r;
				data[index + 1] = g;
				data[index + 2] = b;
				data[index + 3] = a;
			}
		}
	}
}


// similar to the above-
// this draws one tile from within a larger image
// the index passed in is the index of the sprite to draw
var spriteSize = 8;
function drawIndexedSpriteToRGB(indexedSource, index, palette, imageDataTarget, targetX, targetY) {
	var colorIndex, sourceColor;
	var r, g, b;
	var a = 255;
	var data = imageDataTarget.data;
	var index;
	var width = indexedSource.width;
	var height = indexedSource.height;
	var sourceXOffset = spriteSize * (index % 8);
	var sourceYOffset = Math.floor(index / 8) * spriteSize;
	for (var y = 0; y < spriteSize; y ++) {
		for (var x = 0; x < spriteSize; x ++) {
			colorIndex = indexedSource[x + sourceXOffset][y + sourceYOffset]; // get color index from indexed image
			
			if (colorIndex != 0) { // 0 is forced alpha
				sourceColor = palette[colorIndex]; // look up the color to use

				// extract colors
				r = (sourceColor >> 16) & 0xff;
				g = (sourceColor >> 8) & 0xff;
				b = (sourceColor) & 0xff;

				// index to draw to
				index = ((targetY + y) * imageDataTarget.width + (targetX + x)) * 4;
				// set the pixel
				data[index] = r;
				data[index + 1] = g;
				data[index + 2] = b;
				data[index + 3] = a;
			}
		}
	}
}


function drawIndexedSpriteToRGBClipped(indexedSource, index, palette, imageDataTarget, targetX, targetY) {
	var colorIndex, sourceColor;
	var r, g, b;
	var a = 255;
	var data = imageDataTarget.data;
	var index;
	var width = indexedSource.width;
	var height = indexedSource.height;
	var sourceXOffset = spriteSize * (index % 8);
	var sourceYOffset = Math.floor(index / 8) * spriteSize;
	for (var y = 0; y < spriteSize; y ++) {
		for (var x = 0; x < spriteSize; x ++) {
			colorIndex = indexedSource[x + sourceXOffset][y + sourceYOffset]; // get color index from indexed image
			
			if (colorIndex != 0) { // 0 is forced alpha
				sourceColor = palette[colorIndex]; // look up the color to use

				// extract colors
				r = (sourceColor >> 16) & 0xff;
				g = (sourceColor >> 8) & 0xff;
				b = (sourceColor) & 0xff;

				// index to draw to
				index = ((targetY + y) * imageDataTarget.width + (targetX + x)) * 4;
				// set the pixel
				if ((targetX + x >= 0) && (targetX + x < imageDataTarget.width)) {
					data[index] = r;
					data[index + 1] = g;
					data[index + 2] = b;
					data[index + 3] = a;
				}
			}
		}
	}
}