#include "orb.h"

int et,w,h,numc;
char *buf;
char pal[258][3];
char pal2[258][3];
int map[256];
int map2[256];

int intens(int i)
{
	return pal[i][0]*30+pal[i][1]*56+pal[i][2]*14;
}

int main(int argc, char *argv[])
{
	int c1,c2,c3,n,f;
	if (argc<3)
	{
		printf("sorts cols of raw file... \nusage: infile outfile [width=320] [expandto=0]\n");
		exit(1);
	}
	FILE *fi=fopen(argv[1],"rb");if (!fi) return 1;

	fread(pal,1,768,fi);
	w=atoi(argv[3]);if (w==0) w=320;
	et=atoi(argv[4]);if (et==0) et=0;
	buf=new char[w*1024];
	h=0;
	while (!feof(fi))
	{
		if (fread(buf+w*h,1,w,fi)!=w) break;
		h++;
	}
	fclose(fi);
	printf("%d x %d\n",w,h);
	n=w*h;

	// remap out unused colours into newpal
	memset(map,-1,4*256);
	numc=0;
	for (c1=0;c1<n;c1++)
	{
		c2=buf[c1];
		if (map[c2]>=0) {buf[c1]=map[c2];} else {buf[c1]=map[c2]=numc++;}
	}

	// reorder palette
	for (c1=0;c1<numc;c1++)
	{
		for (c2=0;c2<256;c2++) if (map[c2]==c1) break;
		pal2[c1][0]=pal[c2][0];
		pal2[c1][1]=pal[c2][1];
		pal2[c1][2]=pal[c2][2];
	}
	for(c1=numc;c1<256;c1++) {pal2[c1][0]=pal2[c1][1]=pal2[c1][2]=0;}
	memcpy(pal,pal2,sizeof(pal));
	printf("%d used cols\n",numc);

	// sort palette by luminance

	for (c1=0;c1<numc;c1++) map[c1]=c1;
	do
	{
		f=0;
		for (c2=0;c2<numc-1;c2++)
		{
			if (intens(c2)>intens(c2+1))
			{
				f=1;
				c3=pal[c2][0];pal[c2][0]=pal[c2+1][0];pal[c2+1][0]=c3;
				c3=pal[c2][1];pal[c2][1]=pal[c2+1][1];pal[c2+1][1]=c3;
				c3=pal[c2][2];pal[c2][2]=pal[c2+1][2];pal[c2+1][2]=c3;
				c3=map[c2];map[c2]=map[c2+1];map[c2+1]=c3;
			}
		}
	} while (f);

	// remap picture
	for (c1=0;c1<numc;c1++) map2[map[c1]]=c1;
	for (c1=0;c1<n;c1++)
	{
		buf[c1]=map2[buf[c1]];
	}

	if (et)
	{
		int m,mi;
		printf("padding to %d cols\n",et);
		while (numc<et)
		{
			// find the biggest gap of colours
			m=0;mi=0;
			for (c1=0;c1<numc-1;c1++)
			{
				if (intens(c1+1)-intens(c1)>mi) {mi=intens(c1+1)-intens(c1);m=c1;}
			}
			// insert a colour there
			memmove(pal[m+1],pal[m],(numc-m)*3);
			pal[m+1][0]=(pal[m][0]+pal[m+2][0])/2;
			pal[m+1][1]=(pal[m][1]+pal[m+2][1])/2;
			pal[m+1][2]=(pal[m][2]+pal[m+2][2])/2;
			for (c2=0;c2<n;c2++) if (buf[c2]>m) buf[c2]++;
			numc++;
		}
	}

	FILE *fo=fopen(argv[2],"wb");if (!fo) return 1;

	// write it out
	fwrite(pal,1,768,fo);
	fwrite(buf,w,h,fo);


	fclose(fo);

	return(0);
}