#define COLOR_STEP_SIZE 4
#define MAX_COLOR_RANGE 256/COLOR_STEP_SIZE

#include <stdio.h>
#include <ctype.h>
#include <math.h>

#include <stdlib.h>


#include <fstream> 
#include <iostream>


class ArrayColorDef // constructs the intial array and initializes all values to 0
{ public:
	bool colors[MAX_COLOR_RANGE][MAX_COLOR_RANGE][MAX_COLOR_RANGE];
	bool truthValue;
	int red, green, blue;
	
	ArrayColorDef()
	{reset();}
	
	
	void reset()
	{
	for ( red = 0; red < MAX_COLOR_RANGE; red++)
	{
		for ( green = 0; green < MAX_COLOR_RANGE; green++)
		{
			for ( blue = 0; blue < MAX_COLOR_RANGE; blue++)
			{
				colors[red][green][blue] = 0;
			}
		}
		
	}
	}

	

	void loadFromFile( char* filename)
	{
	printf("begin loading color definitions from file %s.\n", filename);
	FILE* fp = fopen(filename, "r");
	red = 0;
	while (!(red == green && green == blue && blue == red && red == MAX_COLOR_RANGE - 1))
	// I haven't found a useful for loop to use here. It seems to depend somehow on step size, color range, and 256,
	// but I haven't gotten it to make a nice relationship yet. This at least gets it to stop when I want it to.
	{
		
		fscanf(fp, "%d %d %d %d \n", &red, &green, &blue, &truthValue);
		//printf("%d %d %d %d \n", red, green, blue, truthValue);
		colors[red][green][blue] = truthValue;
				
	}
	printf("%s is loaded. \n", filename);
	fclose(fp);
	}

	/**void loadFromFile( char* filename, char* color )
	{
		int rmin, rmax, gmin, gmax, bmin, bmax;
		FILE* fp = fopen(filename, "r");
		fscanf(fp, "r: %d %d\n", &rmin, &rmax);
		fscanf(fp, "g: %d %d\n", &gmin, &gmax);
		fscanf(fp, "b: %d %d\n", &bmin, &bmax);

		for ( red = 0; red < MAX_COLOR_RANGE; red++)
		{
			for ( green = 0; green < MAX_COLOR_RANGE; green++)
			{
				for ( blue = 0; blue < MAX_COLOR_RANGE; blue++)
				{
					if (red*COLOR_STEP_SIZE > rmin && red*COLOR_STEP_SIZE < rmax && green*COLOR_STEP_SIZE > gmin && green*COLOR_STEP_SIZE < gmax && blue*COLOR_STEP_SIZE > bmin && blue*COLOR_STEP_SIZE < bmax)
						colors[red][green][blue] = 1;
				}
			}
		}
		//printf(" %s definition loaded \n", color);
	}
	**/
	
	void saveToFile(char* filename)
	{
		FILE* fp = fopen(filename, "w");
		for ( red = 0; red < MAX_COLOR_RANGE; red++)
		{
			for ( green = 0; green < MAX_COLOR_RANGE; green++)
			{
				for ( blue = 0; blue < MAX_COLOR_RANGE; blue++)
				{
					fprintf( fp, "%d %d %d %d \n", red, green, blue, colors[red][green][blue] );
					//if (colors[red][green][blue] == true)
						//printf("%d %d %d %d \n", red, green, blue, colors[red][green][blue] );
				}
			}
		
		}
		printf( "%s saved. \n", filename );
		fclose(fp);
	}
	
	bool pixelMatch( int r, int g, int b)
	{
		return colors[r/COLOR_STEP_SIZE][g/COLOR_STEP_SIZE][b/COLOR_STEP_SIZE];
	}

	void expandToFit( int r, int g, int b, int N )
	{
		if(!(r == g && g == b && b == r && r == 255))
		{
		//printf("r =%d; g = %d; b = %d", r, g, b);
		for ( red = MAX(r-N, 0)/COLOR_STEP_SIZE ; red < MIN(r+N, 255)/COLOR_STEP_SIZE + 1; red++)
			{
				//printf("looping red\n");
			for ( green = MAX(g-N, 0)/COLOR_STEP_SIZE ; green < MIN(g+N, 255)/COLOR_STEP_SIZE + 1; green++)	
				{
					//printf("looping green \n");
				for ( blue = MAX(b-N, 0)/COLOR_STEP_SIZE ; blue < MIN(b+N, 255)/COLOR_STEP_SIZE + 1; blue++)
					{
						//printf("looping blue\n");
						//printf("red = %d; green = %d; blue = %d\n", red, green, blue);
					
							colors[red][green][blue] = 1;
						//else printf( "Error: Values out of bounds. red = %d, green = %d, blue = %d", red, green, blue);
					 }
					
				 }
			}
		}
	}
	
	void subtractRange( int r, int g, int b, int N )
	{
		if(!(r == g && g == b && b == r && r == 255))
		{
		//printf("r =%d; g = %d; b = %d", r, g, b);
		for ( red = MAX(r-N, 0)/COLOR_STEP_SIZE ; red < MIN(r+N, 255)/COLOR_STEP_SIZE + 1; red++)
			{
				//printf("looping red\n");
			for ( green = MAX(g-N, 0)/COLOR_STEP_SIZE ; green < MIN(g+N, 255)/COLOR_STEP_SIZE + 1; green++)	
				{
					//printf("looping green \n");
				for ( blue = MAX(b-N, 0)/COLOR_STEP_SIZE ; blue < MIN(b+N, 255)/COLOR_STEP_SIZE + 1; blue++)
					{
						//printf("looping blue\n");
						//printf("red = %d; green = %d; blue = %d\n", red, green, blue);
					
							colors[red][green][blue] = 0;
						//else printf( "Error: Values out of bounds. red = %d, green = %d, blue = %d", red, green, blue);
					 }
					
				 }
			}
		}
	}
	

	void print()
	{ bool onesDetected = 0;
		for ( red = 0; red < MAX_COLOR_RANGE; red++)
		{
			for ( green = 0; green < MAX_COLOR_RANGE; green++)
			{
				for ( blue = 0; blue < MAX_COLOR_RANGE; blue++)
				{
					if (colors[red][green][blue] == true)
						{printf( "%d %d %d  %d\n", red, green, blue, colors[red][green][blue] );
						onesDetected = true;}
				}
			}
		
		}
		printf("onesDetected is %d\n", onesDetected);
		}

	void setAs(ArrayColorDef newArray)
	{
		for ( red = 0; red < MAX_COLOR_RANGE; red++)
		{
			for ( green = 0; green < MAX_COLOR_RANGE; green++)
			{
				for ( blue = 0; blue < MAX_COLOR_RANGE; blue++)
				{
					colors[red][green][blue] = newArray.colors[red][green][blue];
				}
			}
		
		}
	}

		
		
		
						
};