/*
File:       icontainer2icns.cpp
Copyright (C) 2005 Thomas Lübking <baghira-style@gmx.net>

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <stdio.h>

// --> find icns data[i]
// --> data[i-9] - data[i-1] = "[######]" (id)
// --> data[i-58] - data[i-58+x] = "name"

static inline unsigned short clamp(short s) {
	if (s < 0) return 118 + s;
	if (s > 117) return s - 118;
	return s;
}

static inline int isChar(char c) {
	if (c > 'z') return 0;
	if (c < 'a') return (c == '_');
	return -1;
}

int main(int argc, char **argv)
{
	printf("icontainer2icns, (C) 2005/2007 by Thomas Lübking\n\n");
	if (argc < 2) {
		printf("\nusage: icontainer2icns foo.icontainer\n\n");
		return -1;
	}
	else if (argc > 2) {
		printf("\nusage: icontainer2icns foo.icontainer\nif your icontainer file contains spaces etc.,\nuse a system valid form (i.e. use \"my foo.icontainer\" or my\\ foo.icontainer)\n\n");
		return -1;
	}
	char buffer[118];
	FILE *icontainer = NULL;
	FILE *icns = NULL;
	short i = 0;

	//int iconCounter = 0;
	int c;
	char name[256];

	if( (icontainer = fopen(argv[1], "r")) == NULL ) {
		printf("error while opening file %s\n",argv[1]);
		return -1;
	}

	rewind(icontainer);

	while ((c = getc(icontainer)) != EOF) {
		if (c != 'i') {
			buffer[i] = (char)(c & 0xff);
			i = clamp(++i);
			if (icns)
				fputc(buffer[i], icns);
		}
		else { // wow, lets test if this starts a new icns!
			if ((c = getc(icontainer)) == 'c') {
			if ((c = getc(icontainer)) == 'n') {
			if ((c = getc(icontainer)) == 's') { // yupp!
				if (icns) fclose(icns); // buffer only contains new icns info
				// generate the name
				// i - 7 .. i - 2 is the icontainer id
				// could be 56-4, so no memcpy please!
				// printf("%s\n",buffer);
				short j;
				short k = 0;
				if (buffer[clamp(i-1)] == ']') {
					j = clamp(i-7);
					for (k = 0; k < 6; j = clamp(++j)) {
						name[k++] = buffer[j];
					}
					name[k++] = '-';
				}
				// now the name
				j = clamp(i+1);
				while (!isChar(buffer[j]) && j != i) j = clamp(++j);
				while (isChar(buffer[j]) && j != i) {
					name[k++] = buffer[j]; j = clamp(++j);
				}
				name[k++] = '.'; name[k++] = 'i'; name[k++] = 'c';
				name[k++] = 'n'; name[k++] = 's'; name[k] = '\0';

				// printf("%s\n",name);

				if( (icns = fopen(name, "w")) == NULL ) {
					printf("error while opening icns file %s\n", name);
					return -1;
				}

				rewind(icns);
				// write header
				fputc('i', icns); fputc('c', icns);
				fputc('n', icns); fputc('s', icns);
				// init buffer
				for (i = 0; i < 117; ++i)
					buffer[i] = (char)(getc(icontainer) & 0xff);
			}
			else { // reset
				ungetc(c, icontainer); ungetc('n', icontainer);
				ungetc('c', icontainer);
				buffer[i] = 'i'; i = clamp(++i);
				if (icns)
					fputc(buffer[i], icns);
			}
			}
			else { // reset
				ungetc(c, icontainer); ungetc('c', icontainer);
				buffer[i] = 'i'; i = clamp(++i);
				if (icns)
					fputc(buffer[i], icns);
			}
			}
			else { // reset
				ungetc(c, icontainer);
				buffer[i] = 'i'; i = clamp(++i);
				if (icns)
					fputc(buffer[i], icns);
			}
		}
	}
	fclose(icontainer);
	return 0;
}
