/*
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
For a list of contributors, see the accompanying CONTRIBUTORS file.

This file is part of GtkRadiant.

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

GtkRadiant 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 General Public License for more details.

You should have received a copy of the GNU General Public License
along with GtkRadiant; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/


#include "qdata.h"

byte			*byteimage, *lbmpalette;
int				byteimagewidth, byteimageheight;

qboolean		TrueColorImage;
int				longimagewidth, longimageheight;

char			book_prefix[1024];
byte			buffer[640 * 480];
unsigned long	bufferl[640 * 480];

miptex_t *CreateBook8(byte *buffer, int w, int h, byte *palette, int *FinalSize)
{
	miptex_t	*mp;
	int			i, j;
	byte		*pos;
	int			size;

	size = sizeof(*mp) + (w * h);
	mp = (miptex_t *)SafeMalloc(size, "CreateBook8");
	memset(mp, 0, size);

	mp->version = MIP_VERSION;

	for(i=j=0;i<256;i++,j+=3)
	{
		mp->palette[i].r = palette[j];
		mp->palette[i].g = palette[j+1];
		mp->palette[i].b = palette[j+2];
	}
	pos = (byte *)(mp + 1);

	mp->width[0] = w;
	mp->height[0] = h;
	mp->offsets[0] = sizeof(*mp);
	memcpy(pos, buffer, w * h);

	*FinalSize = size;
	return(mp);
}

miptex32_t *CreateBook32(long *buffer, int w, int h, int *FinalSize)
{
	miptex32_t	*mp;
	byte		*pos;
	int			size;

	size = sizeof(*mp) + (w * h * 4);
	mp = (miptex32_t *)SafeMalloc(size, "CreateBook32");
	memset(mp, 0, size);

	mp->version = MIP32_VERSION;

	pos = (byte *)(mp + 1);

	mp->width[0] = w;
	mp->height[0] = h;
	mp->offsets[0] = sizeof(*mp);
	memcpy(pos, buffer, w * h * 4);

	*FinalSize = size;
	return(mp);
}


// Routines to chop a random sized image into gl texture friendly chunks

typedef struct rect_s 
{
	int		x, y;
	int		w, h;
	char	name[4];
} rect_t;

int GetCoords(int x, int store[MAX_MD2SKINS])
{
	int		index, start, delta;

	index = 0;
	start = 0;
	delta = 256;

	store[index++] = start;
	while(x)
	{
		if(x >= delta)
		{
			start += delta;
			store[index++] = start;
			x -= delta;
		}
		else
		{
			delta >>= 1;
		}
	}
	return(index);
}

int ChopImage(int w, int h, rect_t coords[MAX_MD2SKINS])
{
	int		xs[MAX_MD2SKINS], ys[MAX_MD2SKINS];
	int		xcount, ycount, x, y, index;

	index = 0;
	xcount = GetCoords(w, xs) - 1;
	ycount = GetCoords(h, ys) - 1;

	for(y = 0; y < ycount; y++)
	{
		for(x = 0; x < xcount; x++, index++)
		{
			coords[index].x = xs[x];
			coords[index].y = ys[y];
			coords[index].w = xs[x + 1] - xs[x];
			coords[index].h = ys[y + 1] - ys[y];
			coords[index].name[0] = x + '0';
			coords[index].name[1] = y + '0';
			coords[index].name[2] = 0;
		}
	}
	return(index);
}

/*
===============
Cmd_Pic
===============
*/

void Cmd_Book()
{
	int             xl,yl,xh,yh,w,h;
	byte            *dest, *source;
	int				flags, value, contents;
	char			lumpname[64];
	char			filename[1024];
	unsigned long	*destl, *sourcel;
	int             linedelta, x, y;
	int				size;
	miptex_t		*qtex;
	miptex32_t		*qtex32;
	float			scale_x, scale_y;
	int				numrects, i;
	rect_t			coords[MAX_MD2SKINS];
	bookframe_t		bframes[MAX_MD2SKINS];
	bookframe_t		*bf;
	book_t			book;

	GetScriptToken (false);
	strcpy (lumpname, token);
	
	GetScriptToken (false);
	xl = atoi (token);
	GetScriptToken (false);
	yl = atoi (token);
	GetScriptToken (false);
	w = atoi (token);
	GetScriptToken (false);
	h = atoi (token);

	total_x += w;
	total_y += h;
	total_textures++;

	if ( (w & 7) || (h & 7) )
		Error ("line %i: miptex sizes must be multiples of 8", scriptline);

	flags = 0;
	contents = 0;
	value = 0;

	scale_x = scale_y = 0.5;

	if (g_release)
		return;

	if(TrueColorImage)
	{
		xh = xl + w;
		yh = yl + h;

		if (xl >= longimagewidth || xh > longimagewidth ||
			yl >= longimageheight || yh > longimageheight)
		{
			Error ("line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,longimagewidth,longimageheight);
		}

		sourcel = (unsigned long *) longimage + (yl * longimagewidth) + xl;
		destl = (unsigned long *) longimage;
		linedelta = (longimagewidth - w);

		for(y = yl; y < yh; y++)
		{
			for(x = xl; x < xh; x++)
			{
				*destl++ = *sourcel++;	// RGBA
			}
			sourcel += linedelta;
		}

		// Get rectangles to chop into
		numrects = ChopImage(w, h, coords);

		bf = bframes;
		for(i = 0; i < numrects; i++, bf++)
		{
			// Copy section of image to buffer
			sourcel = (unsigned long *) longimage + (coords[i].y * w) + coords[i].x;
			destl = bufferl;
			linedelta = w - coords[i].w;

			for(y = 0; y < coords[i].h; y++)
			{
				for(x = 0; x < coords[i].w; x++)
				{
					*destl++ = *sourcel++;
				}
				sourcel += linedelta;
			}

			qtex32 = CreateBook32(bufferl, coords[i].w, coords[i].h, &size);

			qtex32->flags = flags;
			qtex32->contents = contents;
			qtex32->value = value;
			qtex32->scale_x = scale_x;
			qtex32->scale_y = scale_y;

			sprintf (filename, "%sbook/%s/%s_%s.m32", gamedir, book_prefix, lumpname, coords[i].name);
			sprintf (qtex32->name, "%s/%s_%s.m32", book_prefix, lumpname, coords[i].name);

			strcpy(bf->name, qtex32->name);
			bf->x = coords[i].x;
			bf->y = coords[i].y;
			bf->w = coords[i].w;
			bf->h = coords[i].h;
 		//
		// write it out
		//
			printf ("writing %s\n", filename);
			SaveFile (filename, (byte *)qtex32, size);

			free (qtex32);
		}
	}
	else
	{
		xh = xl + w;
		yh = yl + h;

		if (xl >= byteimagewidth || xh > byteimagewidth ||
			yl >= byteimageheight || yh > byteimageheight)
		{
			Error ("line %i: bad clip dimmensions (%d,%d) (%d,%d) > image (%d,%d)", scriptline, xl,yl,w,h,byteimagewidth,byteimageheight);
		}

		// Copy image to top left
		source = byteimage + yl*byteimagewidth + xl;
		dest = byteimage;
		linedelta = byteimagewidth - w;

		for(y = yl; y < yh; y++)
		{
			for(x = xl; x < xh; x++)
			{
				*dest++ = *source++;
			}
			source += linedelta;
		}

		// Get rectangles to chop into
		numrects = ChopImage(w, h, coords);

		bf = bframes;
		for(i = 0; i < numrects; i++, bf++)
		{
			// Copy section of image to buffer
			source = byteimage + (coords[i].y * w) + coords[i].x;
			dest = buffer;
			linedelta = w - coords[i].w;

			for(y = 0; y < coords[i].h; y++)
			{
				for(x = 0; x < coords[i].w; x++)
				{
					*dest++ = *source++;
				}
				source += linedelta;
			}

			qtex = CreateBook8(buffer, coords[i].w, coords[i].h, lbmpalette, &size);

			qtex->flags = flags;
			qtex->contents = contents;
			qtex->value = value;

			sprintf (filename, "%sbook/%s/%s_%s.m8", gamedir, book_prefix, lumpname, coords[i].name);
			sprintf (qtex->name, "%s/%s_%s.m8", book_prefix, lumpname, coords[i].name);

			strcpy(bf->name, qtex->name);
			bf->x = coords[i].x;
			bf->y = coords[i].y;
			bf->w = coords[i].w;
			bf->h = coords[i].h;
 		//
		// write it out
		//
			printf ("writing %s\n", filename);
			SaveFile (filename, (byte *)qtex, size);

			free (qtex);
		}
	}
	// Set up descriptor
	size = sizeof(bookframe_t) * numrects;

	book.bheader.ident = IDBOOKHEADER;
	book.bheader.version = BOOK_VERSION;
	book.bheader.num_segments = numrects;
	book.bheader.total_w = w;
	book.bheader.total_h = h;
	memcpy(book.bframes, bframes, size);

	// Save out segment descriptor
	sprintf (filename, "%sBook/%s/%s.bk", gamedir, book_prefix, lumpname);
	printf ("writing %s\n", filename);
	SaveFile (filename, (byte *)&book, size + sizeof(bookheader_t));
}

/*
===============
Cmd_picdir
===============
*/
void Cmd_Bookdir (void)
{
	char	filename[1024];

	GetScriptToken (false);
	strcpy (book_prefix, token);
	// create the directory if needed
	sprintf (filename, "%sBook", gamedir);
	Q_mkdir (filename); 
	sprintf (filename, "%sBook/%s", gamedir, book_prefix);
	Q_mkdir (filename); 
}

// end
