/*  menus.c: (c) 2002 sibn

    This file is part of GWiz.

    GWiz 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.

    GWiz 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 GWiz; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gwiz.h"
#include "prefsdat.h"
#include "uiloop.h"
#include "text.h"
#include "menus.h"
#include "items.h"
#include "shop.h"
#include "keyconfig.h"
#include "joystick.h"
#include "color.h"
#include "spellmanage.h"
#include "multiline.h"

extern GwizApp gwiz;
extern const SDL_Color fg;
extern const SDL_Color bg;

int NewGwizMenu (SDL_Surface *target, char **labels, int x, int y, int initpos)
{
    GwizMenu menu;
    SDL_Rect dest;
    SDL_Rect trect;
    int i = 0;
    int positions = 0;
    SDL_Surface *entry[32]; /* Important: Do not exceed 32 lines. */

    dest.x = 0;
    dest.y = 0;
    dest.h = gwiz.canvas->h;
    dest.w = gwiz.canvas->w;
    trect.x = gwiz.canvas->w/2 - target->w/2;
    trect.y = gwiz.canvas->h/2 - target->h/2;
    trect.h = target->h;
    trect.w = target->w;
    /* render the text surfaces */
    while (labels[i] != NULL)
	{
	    entry[i] = GwizRenderText (labels[i]);
	    i++;
	    positions++;
	    if (positions == 32) /* Reached the end of the list */
		BailCall ("menus.c: menu requested was too large: ",
			  "33 positions");
	}
    
    menu.positions = positions;
    menu.cursorposition = initpos;
    menu.cursorinitpos = BORDERHEIGHT + (gwiz.font.height / 2) -
	gwiz.cursor->h/2 + gwiz.font.height*menu.cursorposition;
    
    /* find out which entry is the largest */
    menu.widestentry = 0;
    for (i = 0; i < positions; i++)
	if (entry[i]->w > menu.widestentry)
	    menu.widestentry = entry[i]->w;
    
    menu.area = NewTextBox(menu.widestentry + 14, 
			   (gwiz.font.height*positions));
    dest.x = 22;
    dest.y = 8;
    dest.h = gwiz.font.height;
    for (i = 0; i < positions; i++)
	{
	    dest.w = entry[i]->w;
	    SDL_BlitSurface (entry[i], NULL, menu.area, &dest);
	    dest.y += gwiz.font.height;
	}
    
    SetActualCoords (target, &x, &y, &menu);
    menu.x = x;
    menu.y = y;
    
    dest.x = menu.x;
    dest.y = menu.y;
    dest.h = menu.area->h + target->h;
    dest.w = menu.area->w + target->h;

    menu.oldcanvas = NewGwizSurface (menu.area->w, menu.area->h);
    SDL_BlitSurface (gwiz.canvas, &dest, menu.oldcanvas, NULL);

    menu.cursorposition = MenuLoop (target, &menu);

    for (i = 0; i < positions; i++)
	SDL_FreeSurface (entry[i]);
    SDL_FreeSurface (menu.area);
    SDL_BlitSurface (menu.oldcanvas, NULL, gwiz.canvas, &dest);
    SDL_FreeSurface (menu.oldcanvas);
    SDL_Flip (gwiz.canvas);
    return (menu.cursorposition);
}

void SetActualCoords (SDL_Surface *target, int *x, int *y, GwizMenu *menu)
{
    if ((*x + menu->area->w) > target->w)
	/* all the way against the right border. */
	*x = ((target->w) - (menu->area->w));
    if (*x < 0)
	/* half canvas width - half area width.  dead center. */
	*x = target->w/2 - menu->area->w/2;
    if ((*y + menu->area->h) > target->h)
	/* all the way against the bottom border. */
	*y = ((target->h) - (menu->area->h));
    if (*y < 0)
	/* half canvas height - half area height.  dead center. */
	*y = target->h/2 - menu->area->h/2;
}

int MenuLoop (SDL_Surface *target, GwizMenu *menu)
{
    SDL_Surface *tmpsurf = SDL_DisplayFormat (target);
    SDL_Event event;
    SDL_Rect crect, mrect, trect;
    int breakout = -2;
     
    menu->cursorinfo.x = 9;
    menu->cursorinfo.y = menu->cursorinitpos;
    menu->cursorinfo.h = gwiz.cursor->h;
    menu->cursorinfo.w = gwiz.cursor->w;
    crect.x = 0;
    crect.y = 0;
    crect.h = menu->oldcanvas->h;
    crect.w = menu->oldcanvas->w;
    mrect.x = menu->x;
    mrect.y = menu->y;
    mrect.h = menu->area->h;
    mrect.w = menu->area->w;
    trect.x = gwiz.canvas->w/2 - target->w/2;
    trect.y = gwiz.canvas->h/2 - target->h/2;
    trect.h = target->h;
    trect.w = target->w;
    
    SDL_BlitSurface (gwiz.cursor, NULL, menu->area, &menu->cursorinfo);
    SDL_BlitSurface (menu->area, NULL, tmpsurf, &mrect);
    SDL_BlitSurface (tmpsurf, NULL, gwiz.canvas, &trect);
    SDL_Flip (gwiz.canvas);
    
    while (SDL_WaitEvent (&event) != 0)
	{
	    SDL_Event *e = &event;
	    if (EventIsCancel (e))
		breakout = -1;
	    if (EventIsUp (e))
		MoveCursor (UP, menu);
	    if (EventIsDown (e))
		MoveCursor (DOWN, menu);
	    if (EventIsOk (e))
		breakout = menu->cursorposition;
	    if ((event.key.keysym.sym == SDLK_F12))
		KeyConfig();
	    if ((event.type==SDL_KEYDOWN)&&(event.key.keysym.sym==SDLK_F11))
		{
		    /* Disabled, used for testing new functions */

		}

	    if (breakout != -2)
		break;
	    SDL_BlitSurface (menu->area, NULL, tmpsurf, &mrect);
	    SDL_BlitSurface (tmpsurf, NULL, gwiz.canvas, &trect);
	    SDL_Flip (gwiz.canvas);
	}
    SDL_FreeSurface (tmpsurf);
    return (breakout);
}

void MoveCursor (int direction, GwizMenu *menu)
{
    switch (direction)
	{
	case UP:
	    menu->cursorposition--;
	    if (menu->cursorposition < 0)
		menu->cursorposition = menu->positions-1;
	    break;
	case DOWN:
	    menu->cursorposition++;
	    if (menu->cursorposition == menu->positions)
		menu->cursorposition = 0;
	    break;
	}
    SDL_FillRect (menu->area, &menu->cursorinfo, gwiz.bgc);
    menu->cursorinfo.y = BORDERHEIGHT + (gwiz.font.height / 2) -
	gwiz.cursor->h/2 + gwiz.font.height*menu->cursorposition;
    SDL_BlitSurface (gwiz.cursor, NULL, menu->area, &menu->cursorinfo);
}

