/* Copyright 2008 Jeffrey Lee
   This file is part of Pale.
   Pale 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 3 of the License, or
   (at your option) any later version.
   Pale 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 Pale.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "sprfile.h"
#include "preview.h"
#include "editor.h"

#include "/WoumInclude:lib/osspr.h"

//DEPPEND

#define ICON_HPAD 12
#define ICON_VPAD 12
#define ICON_WIDTH 192
#define ICON_HEIGHT 192

limpx_event *event_sprfile_drag_box;

void open_sprfile_menu(sprfile *s,int index,limpx_mouse_obj *m)
{
	open_menu = MENU_SPRITEFILE;
	open_menu_sprfile = s;
	LimpX_CreateMenu(menu_spritefile,m->x-64,m->y+12);
}

void sprfile_rebuildicons(sprfile *s)
{
	limpx_window_state ws;
	char name[16];
	int i;
	/* Delete all existing icons for simplicity */
	i = LimpX_GetWindow_Icons(s->mainwin); 
	while(i-- > 0)
		LimpX_DeleteIcon(LimpX_IconFromWindow(s->mainwin,i));
	/* Get current window width, so we can flow the icons properly */
	ws = LimpX_GetWindowOutline(s->mainwin);
	/* Set icon basics */
	temp_iconblock.sminx = ICON_HPAD;
	temp_iconblock.sminy = -(ICON_HEIGHT+ICON_VPAD);
	temp_iconblock.smaxx = ICON_HPAD+ICON_WIDTH;
	temp_iconblock.smaxy = -ICON_VPAD;
	temp_iconblock.flags = 0x1701880B;
	/* Create icons! */
	for(i=0;i<OSSpr_CountSprites(s->sprs);i++)
	{
		OSSpr_GetName(s->sprs,name,i+1);
		memcpy(&(temp_iconblock.data[0]),name,12);
		LimpX_NewIcon(s->mainwin,&temp_iconblock);
		/* Move to new position */
		temp_iconblock.sminx += ICON_WIDTH+ICON_HPAD;
		temp_iconblock.smaxx += ICON_WIDTH+ICON_HPAD;
		if(temp_iconblock.smaxx >= ws.vmaxx-ws.vminx)
		{ 
			temp_iconblock.sminx = ICON_HPAD;
			temp_iconblock.smaxx = ICON_HPAD+ICON_WIDTH;
			temp_iconblock.sminy -= ICON_HEIGHT+ICON_VPAD;
			temp_iconblock.smaxy -= ICON_HEIGHT+ICON_VPAD;
		}
	}
	/* Ensure window y min is correct */
	LimpX_SetExtent(s->mainwin,temp_spritefile->wminx,temp_iconblock.sminy-ICON_VPAD,temp_spritefile->wmaxx,temp_spritefile->wmaxy);
	/* Done; make sure sprite block ptr is set, then redraw window */
	LimpX_SetWindow_SpriteBlock(s->mainwin,(int) s->sprs);
	sprfile_redraw(s,0);
}

void *sprfile_getsprite(sprfile *s,int index)
{
	char name[16];
	/* Do it the ugly way */
	if((!s) || (index < 0) || (index > OSSpr_CountSprites(s->sprs)))
		return 0;
	OSSpr_GetName(s->sprs,name,index+1);
	return OSSpr_GetAddress(s->sprs,name);
}

rgb *sprfile_getpalette(void *spr)
{
	/* Is the palette valid? */
	int *s = (int *) spr;
	if(!s)
		return 0;
	if(s[8]-44 != 2048)
		return 0; /* No palette or wrong size */
	return (rgb *) (&s[11]);
}

void sprfile_redraw(sprfile *s,void *spr)
{
	/* Redraw entire window */
	limpx_window_state ws;
	ws = LimpX_GetWindowOutline(s->mainwin);
	LimpX_ForceRedraw(0,ws.vminx,ws.vminy,ws.vmaxx,ws.vmaxy);
	/* Redraw previews for spr, if provided */
	if(!spr)
		return;
	preview *p;
	p = s->previews;
	while(p)
	{
		if(p->spr == spr)
			preview_redrawall(p);
		p = p->next;
	}
}

void sprfile_updatetitle(sprfile *s)
{
	limpx_window_state o;
	char text[512];
	strcpy(text,s->name);
	if(s->modified)
		strcat(text," *");
	LimpX_SetWindow_Title(s->mainwin,text);
	o = LimpX_GetWindowOutline(s->mainwin);
	LimpX_ForceRedraw((limpx_window *) NULL,o.vminx,o.vmaxy-64,o.vmaxx,o.vmaxy);
}

static sprfile *sprfile_drag = 0;
static int sprfile_dragindex = 0;

static int func_sprfile_drag_box(int minx,int miny,int maxx,int maxy)
{
	limpx_mouse_obj m;
	/* Remove current event */
	LimpX_DeleteEvent(event_sprfile_drag_box);
	LimpX_DragASprite_Stop();
	drag_box_active = 0;
	/* Completely ignore the drag box pos and use the current mouse pos */
	LimpX_GetPointerInfo(&m);
	limpx_window *w = LimpX_WindowFromHandle(m.window);
	/* Is this one of ours? */
	if(!w)
		return 1;
	sprfile *s;
	preview *p;
	paleditor *e;
	if(!which_window(w,&s,&p,&e))
		return 1;
	if(!e)
		return 1;
	if(e->file != sprfile_drag)
		return 1;
	/* Add the sprite to the edit list */
	int i;
	void **n,*spr;
	spr = sprfile_getsprite(sprfile_drag,sprfile_dragindex);
	for(i=0;i<e->nsprites;i++)
		if(e->sprites[i] == spr)
			return 1;
	n = malloc(4*(e->nsprites+1));
	memcpy(n,e->sprites,4*e->nsprites);
	n[e->nsprites++] = spr;
	free(e->sprites);
	e->sprites = n;
	editor_rebuildsprlistwindow(e);
	return 1;
}

void sprfile_startdrag(sprfile *s,int index)
{
	int ox,oy;
	limpx_window_state p;
	int block[4];
	p = LimpX_GetWindowState(s->mainwin);
	ox = p.vminx - p.scrollx;
	oy = p.vmaxy - p.scrolly;
	LimpX_GetIconState(LimpX_IconFromWindow(s->mainwin,index),&temp_iconblock);
	LimpX_DragBox(s->mainwin,5,temp_iconblock.sminx + ox,temp_iconblock.sminy + oy,temp_iconblock.smaxx + ox,temp_iconblock.smaxy + oy,0,0,-1,-1,0,0,0,0);
	limpx_mouse_obj m;
	LimpX_GetPointerInfo(&m);
	block[0] = m.x;
	block[1] = m.y;
	block[2] = m.x;
	block[3] = m.y;
	LimpX_DragASprite_Start(0x85,1,"file_ff9",block,NULL);
	sprfile_drag = s;
	sprfile_dragindex = index;
	/* Add drag event */
	event_sprfile_drag_box = LimpX_NewEvent_Drag_Box(func_sprfile_drag_box);
	drag_box_active = 1;
}

void palette_remap(rgb *pal,char *remap)
{
	rgb newpal[512];
	int i;
	for(i=0;i<256;i++)
	{
		newpal[remap[i]*2] = pal[i*2];
		newpal[remap[i]*2+1] = pal[i*2+1];
	}
	memcpy(pal,newpal,sizeof(newpal));
}

void sprite_remap(sprfile *s,void *spr,char *remap)
{
	/* Use quick function to loop through */
	char *data = ((char *) spr)+((int *)spr)[8];
	int len = (((int *)spr)[4]+1)*(((int *)spr)[5]+1)*4;
	while(len--)
	{
		*data = remap[(int) *data];
		data++;
	}
	/* Redraw all previews, and main window */
	sprfile_redraw(s,spr);
}
