/*  spellmanage.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 <string.h>
#include "gwiz.h"
#include "text.h"
#include "playerpawn.h"
#include "spellmanage.h"
#include "uiloop.h"
#include "menus.h"

extern GwizApp gwiz;

/* Private to this file.  All spells are generated with NewSpell() */
void CreateSpell (SpellLevel level, SpellClass class, SpellOrigin origintype,
		  SpellTarget targettype, SpellElement elem, SpellNo spellno,
		  SpellEffect effect, int min, int max, GwizSpell *spell);

GwizSpell *NewSpell (SpellNo spellno)
{
    GwizSpell *spell;

    if (spellno == NO_SPELL)
	return (NULL);

    spell = Smalloc (sizeof(GwizSpell));

    switch (spellno)
	{
	case IGNIS:
	    CreateSpell (FIRST, MAGE_BATTLE, O_PAWN, T_MONSTER, E_FIRE,
			 spellno, EF_NONE, 1, 8, spell);
	    break;
	case FERRUM_CORPORI:
	    CreateSpell (FIRST, MAGE_BATTLE, O_PAWN, T_MONSTER, E_NONE,
			 spellno, EF_AC_TWO, 0, 0, spell);
	    break;
	case REQUIEM:
	    CreateSpell (FIRST, MAGE_BATTLE, O_PAWN, T_CLUSTER, E_NONE,
			 spellno, EF_SLEEP, 0, 0, spell);
	    break;
	case CLARITAS:
	    CreateSpell (FIRST, MAGE_CAMP, O_PAWN, T_NONE, E_NONE,
			 spellno, EF_NONE, 0, 0, spell);
	    break;

	case ALACRITAS:
	    CreateSpell (SECOND, MAGE_BATTLE, O_PAWN, T_PAWN, E_NONE, spellno,
			 EF_AGI, 0, 0, spell);
	    break;
	case SCINTILLATUS:
	    CreateSpell (SECOND, MAGE_BATTLE, O_PAWN, T_CLUSTER, E_FIRE,
			 spellno, EF_NONE, 1, 8, spell);
	    break;
	case RECLUDERE:
	    CreateSpell (SECOND, MAGE_OTHER, O_PAWN, T_NONE, E_NONE, spellno,
			 EF_NONE, 0, 0, spell);
	    break;
	case TERRERE:
	    CreateSpell (SECOND, MAGE_BATTLE, O_PAWN, T_MONSTER, E_NONE,
			 spellno, EF_FEAR, 0, 0, spell);
	    break;
	case CORDA_PETRI:
	    CreateSpell (SECOND, MAGE_BATTLE, O_PAWN, T_MONSTER, E_NONE,
			 spellno, EF_STONE, 0, 0, spell);
	    break;

	case APERIRE:
	    CreateSpell (THIRD, MAGE_OTHER, O_PAWN, T_HDOOR, E_NONE, spellno,
			 EF_NONE, 0, 0, spell);
	    break;
	case IGNIS_POTENTI:
	    CreateSpell (THIRD, MAGE_BATTLE, O_PAWN, T_CLUSTER, E_FIRE,
			 spellno, EF_NONE, 4, 24, spell);
	    break;
	case FILTRUM_MAGICE:
	    CreateSpell (THIRD, MAGE_BATTLE, O_PAWN, T_PARTY, E_NONE, spellno,
			 EF_MSCREEN, 0, 0, spell);
	    break;
	case DISRUPTUS:
	    CreateSpell (THIRD, MAGE_BATTLE, O_PAWN, T_CLUSTER, E_NONE,
			 spellno, EF_DISRUPT, 0, 0, spell);
	    break;

	case PUGNUS:
	    CreateSpell (FOURTH, MAGE_BATTLE, O_PAWN, T_MONSTER, E_NONE,
			 spellno, EF_NONE, 0, 0, spell);
	    break;
	case IGNIS_VEHEMENS:
	    CreateSpell (FOURTH, MAGE_BATTLE, O_PAWN, T_CLUSTER, E_FIRE,
			 spellno, EF_NONE, 6, 36, spell);
	    break;
	case VOLITARE:
	    CreateSpell (FOURTH, MAGE_CAMP, O_PAWN, T_PARTY, E_NONE, spellno,
			 EF_LEVITATE, 0, 0, spell);
	    break;
	case SENSU_PRIVARE:
	    CreateSpell (FOURTH, MAGE_BATTLE, O_PAWN, T_CLUSTER, E_NONE,
			 spellno, EF_STUN, 0, 0, spell);
	    break;

	case ACCIRE:
	    CreateSpell (FIFTH, MAGE_BATTLE, O_PAWN, T_NONE, E_NONE, spellno,
			 EF_SUMMON, 0, 0, spell);
	    break;
	case REX_GELI:
	    CreateSpell (FIFTH, MAGE_BATTLE, O_PAWN, T_CLUSTER, E_ICE,
			 spellno, EF_NONE, 8, 64, spell);
	    break;
	case ARS_MAGICA_OBSTARE:
	    CreateSpell (FIFTH, MAGE_BATTLE, O_PAWN, T_CLUSTER, E_NONE,
			 spellno, EF_FIZZLE, 0, 0, spell);
	    break;
	case PARMAE_SOLVERE:
	    CreateSpell (FIFTH, MAGE_BATTLE, O_PAWN, T_MPARTY, E_NONE,
			 spellno, EF_DEFIZZLE, 0, 0, spell);
	    break;
	case ARCUS_PLUVIUS:
	    CreateSpell (FIFTH, MAGE_BATTLE, O_PAWN, T_CLUSTER, E_NONE,
			 spellno, EF_RANDOM, 0, 0, spell);
	    break;

	case PARIAE_VIS:
	    CreateSpell (SIXTH, MAGE_BATTLE, O_PAWN, T_PAWN, E_NONE, spellno,
			 EF_AC_TEN, 0, 0, spell);
	    break;
	case EXIGERE:
	    CreateSpell (SIXTH, MAGE_BATTLE, O_PAWN, T_MONSTER, E_NONE,
			 spellno, EF_NONE, 500, 1000, spell);
	    break;
	case TERRAE_PASCET:
	    CreateSpell (SIXTH, MAGE_BATTLE, O_PAWN, T_MPARTY, E_EARTH,
			 spellno, EF_SWALLOW, 0, 0, spell);
	    break;
	case PROCELLA_GELI:
	    CreateSpell (SIXTH, MAGE_BATTLE, O_PAWN, T_MPARTY, E_ICE,
			 spellno, EF_NONE, 0, 0, spell);
	    break;

	case LOCUS_NOVUS:
	    CreateSpell (SEVENTH, MAGE_CAMP, O_PAWN, T_PARTY, E_NONE, spellno,
			 EF_TELEPORT, 0, 0, spell);
	    break;
	case OBTESTARI:
	    CreateSpell (SEVENTH, MAGE_BATTLE, O_PAWN, T_PAWN, E_NONE,
			 spellno, EF_BESEECH, 0, 0, spell);
	    break;
	case DIRUMPERE:
	    CreateSpell (SEVENTH, MAGE_BATTLE, O_PAWN, T_MPARTY, E_NONE,
			 spellno, EF_NONE, 10, 150, spell);
	    break;
	case CHAOS:
	    CreateSpell (SEVENTH, MAGE_BATTLE, O_PAWN, T_MPARTY, E_NONE,
			 spellno, EF_RANDOM, 0, 0, spell);
	    break;
	case ARS_MAGICA_DEI:
	    CreateSpell (SEVENTH, MAGE_BATTLE, O_PAWN, T_MONSTER, E_NONE,
			 spellno, EF_RANDOM, 1200, 2000, spell);
	    break;


	    /* End mage.  Begin cleric */

	case MEDERI:
	    CreateSpell (FIRST, CLERIC_BOTH, O_PAWN, T_PAWN, E_NONE, spellno,
			 EF_RECOVERY,  1, 8, spell);
	    break;
	case DAMNUM:
	    CreateSpell (FIRST, CLERIC_BATTLE, O_PAWN, O_MONSTER, E_NONE,
			 spellno, EF_NONE, 1, 8, spell);
	    break;
	case LUMEN:
	    CreateSpell (FIRST, CLERIC_CAMP, O_PAWN, T_NONE, E_NONE, spellno,
			 EF_LIGHT, 0, 0, spell);
	    break;
	case BENEDICTUS:
	    CreateSpell (FIRST, CLERIC_BATTLE, O_PAWN, T_PARTY, E_NONE,
			 spellno, EF_AC_ONE, 0, 0, spell);
	    break;
	case PARMA:
	    CreateSpell (FIRST, CLERIC_BATTLE, O_PAWN, T_PAWN, E_NONE,
			 spellno, EF_AC_ONE, 0, 0, spell);
	    break;

	case FASCINARE:
	    CreateSpell (SECOND, CLERIC_BATTLE, O_PAWN, T_MONSTER, E_NONE,
			 spellno, EF_CHARM, 0, 0, spell);
	    break;
	case VISUS_EMENDATUS:
	    CreateSpell (SECOND, CLERIC_OTHER, O_PAWN, T_MONSTER, E_NONE,
			 spellno, EF_XRAY, 0, 0, spell);
	    break;
	case PLACIDUS_AER:
	    CreateSpell (SECOND, CLERIC_BATTLE, O_PAWN, T_CLUSTER, E_NONE,
			 spellno, EF_FIZZLE, 0, 0, spell);
	    break;
	case CORPUS_REPERIRE:
	    CreateSpell (SECOND, CLERIC_CAMP, O_PAWN, T_CLUSTER, E_NONE,
			 spellno, EF_LOCATEPAWN, 0, 0, spell);
	    break;

	case AGNOSCERE:
	    CreateSpell (THIRD, CLERIC_BOTH, O_PAWN, T_CLUSTER, E_NONE,
			 spellno, EF_IDENTIFY, 0, 0, spell);
	    break;
	case EXPERGERE:
	    CreateSpell (THIRD, CLERIC_BOTH, O_PAWN, T_PAWN, E_NONE,
			 spellno, EF_AWAKEN, 0, 0, spell);
	    break;
	case PAX:
	    CreateSpell (THIRD, CLERIC_BATTLE, O_PAWN, T_PARTY, E_NONE,
			 spellno, EF_AC_THREE, 0, 0, spell);
	    break;
	case SOLIS_ORTUS:
	    CreateSpell (THIRD, CLERIC_BOTH, O_PAWN, T_PARTY, E_NONE,
			 spellno, EF_LIGHT2, 0, 0, spell);
	    break;
	case MAGICE_SICCARE:
	    CreateSpell (THIRD, CLERIC_BATTLE, O_PAWN, T_MONSTER, E_NONE,
			 spellno, EF_MAGICDRAIN, 0, 0, spell);
	    break;

	case MEDERI_POTENTI:
	    CreateSpell (FOURTH, CLERIC_BOTH, O_PAWN, T_PAWN, E_NONE,
			 spellno, EF_RECOVERY, 2, 16, spell);
	    break;
	case SAUCIARE:
	    CreateSpell (FOURTH, CLERIC_BATTLE, O_PAWN, T_MONSTER, E_NONE,
			 spellno, EF_NONE, 6, 30, spell);
	    break;
	case LAVABARE:
	    CreateSpell (FOURTH, CLERIC_BOTH, O_PAWN, T_PAWN, E_NONE, spellno,
			 EF_ANTIDOTE, 0, 0, spell);
	    break;
	case MAGNUS_PARMUM:
	    CreateSpell (FOURTH, CLERIC_BOTH, O_PAWN, T_PARTY, E_NONE,
			 spellno, EF_AC_FOUR, 0, 0, spell);
	    break;
	case VENTI_NOVACULA:
	    CreateSpell (FOURTH, CLERIC_BATTLE, O_PAWN, T_CLUSTER, E_NONE,
			 spellno, EF_NONE, 0, 0, spell);
	    break;

	case MAGNUS_MEDERUM:
	    CreateSpell (FIFTH, CLERIC_BOTH, O_PAWN, T_PAWN, E_NONE, spellno,
			 EF_RECOVERY, 3, 24, spell);
	    break;
	case RENATUS:
	    CreateSpell (FIFTH, CLERIC_CAMP, O_PAWN, T_PAWN, E_NONE, spellno,
			 EF_LIFE, 1, 4, spell);
	    break;
	case INVOCARE:
	    CreateSpell (FIFTH, CLERIC_BATTLE, O_PAWN, T_NONE, E_NONE,
			 spellno, EF_SUMMON, 0, 0, spell);
	    break;
	case ASTRI_PORTA:
	    CreateSpell (FIFTH, CLERIC_BATTLE, O_PAWN, T_MONSTER, E_NONE,
			 spellno, EF_KILL, 0, 0, spell);
	    break;
	case INTERFICERE:
	    CreateSpell (FIFTH, CLERIC_BATTLE, O_PAWN, T_MONSTER, E_NONE,
			 spellno, EF_KILL, 0, 0, spell);
	    break;

	case REVOCARE:
	    CreateSpell (SIXTH, CLERIC_BOTH, O_PAWN, T_PARTY, E_NONE,
			 spellno, EF_KILL, 0, 0, spell);
	    break;
	case SANARE:
	    CreateSpell (SIXTH, CLERIC_BOTH, O_PAWN, T_PAWN, E_NONE, spellno,
			 EF_FULLHEAL, 0, 0, spell);
	    break;
	case FUR_VITAE:
	    CreateSpell (SIXTH, CLERIC_BATTLE, O_PAWN, T_MONSTER, E_NONE,
			 spellno, EF_HPDRAIN, 0, 0, spell);
	    break;
	case VENTI_IGNIS:
	    CreateSpell (SIXTH, CLERIC_BATTLE, O_PAWN, T_CLUSTER, E_FIRE,
			 spellno, EF_NONE, 0, 0, spell);
	    break;

	case VENTI_PETRUS:
	    CreateSpell (SEVENTH, CLERIC_BATTLE, O_PAWN, T_MPARTY, E_EARTH,
			 spellno, EF_NONE, 12, 72, spell);
	    break;
	case DIVINA_GRATIA:
	    CreateSpell (SEVENTH, CLERIC_CAMP, O_PAWN, T_PAWN, E_NONE,
			 spellno, EF_FAVOR, 0, 0, spell);
	    break;
	case VENTI_MORS:
	    CreateSpell (SEVENTH, CLERIC_BATTLE, O_PAWN, T_CLUSTER, E_NONE,
			 spellno, EF_DCLUSTER, 0, 0, spell);
	    break;
	case INFERUS_EXCITARE:
	    CreateSpell (SEVENTH, CLERIC_CAMP, O_PAWN, T_PAWN, E_NONE,
			 spellno, EF_REBIRTH, 0, 0, spell);
	    break;

	default:
	    return (NULL);
	}
    spell->visual = GetSpellVisual (spell);
    return (spell);
}

inline void DestroySpell (GwizSpell **spell)
{
    SDL_FreeSurface ((*spell)->visual);
    Sfree (*spell);
    *spell = NULL;
}

void CreateSpell (SpellLevel level, SpellClass class, SpellOrigin origintype,
		  SpellTarget targettype, SpellElement elem, SpellNo spellno,
		  SpellEffect effect, int min, int max, GwizSpell *spell)
{
    spell->level = level;
    spell->class = class;
    spell->origintype = origintype;
    spell->targettype = targettype;
    spell->elem = elem;
    spell->spellno = spellno;
    spell->effect = effect;
    spell->min = min;
    spell->max = max;
}

SDL_Surface *GetSpellVisual (GwizSpell *spell)
{
    switch (spell->spellno)
	{
	case IGNIS:
	    strncpy (spell->name, "Ignis", 19);
	    break;
	case FERRUM_CORPORI:
	    strncpy (spell->name, "Ferrum Corpori", 19);
	    break;
	case REQUIEM:
	    strncpy (spell->name, "Requiem", 19);
	    break;
	case CLARITAS:
	    strncpy (spell->name, "Claritas", 19);
	    break;

	case ALACRITAS:
	    strncpy (spell->name, "Alacritas", 19);
	    break;
	case SCINTILLATUS:
	    strncpy (spell->name, "Scintillatus", 19);
	    break;
	case RECLUDERE:
	    strncpy (spell->name, "Recludere", 19);
	    break;
	case TERRERE:
	    strncpy (spell->name, "Terrere", 19);
	    break;
	case CORDA_PETRI:
	    strncpy (spell->name, "Corda Petri", 19);
	    break;

	case APERIRE:
	    strncpy (spell->name, "Aperire", 19);
	    break;
	case IGNIS_POTENTI:
	    strncpy (spell->name, "Ignis Potenti", 19);
	    break;
	case FILTRUM_MAGICE:
	    strncpy (spell->name, "Filtrum Magice", 19);
	    break;
	case DISRUPTUS:
	    strncpy (spell->name, "Disruptus", 19);
	    break;

	case PUGNUS:
	    strncpy (spell->name, "Pugnus", 19);
	    break;
	case IGNIS_VEHEMENS:
	    strncpy (spell->name, "Ignis Vehemens", 19);
	    break;
	case VOLITARE:
	    strncpy (spell->name, "Volitare", 19);
	    break;
	case SENSU_PRIVARE:
	    strncpy (spell->name, "Sensu Privare", 19);
	    break;

	case ACCIRE:
	    strncpy (spell->name, "Accire", 19);
	    break;
	case REX_GELI:
	    strncpy (spell->name, "Rex Geli", 19);
	    break;
	case ARS_MAGICA_OBSTARE:
	    strncpy (spell->name, "Ars Magica Obstare", 19);
	    break;
	case PARMAE_SOLVERE:
	    strncpy (spell->name, "Parmae Solvere", 19);
	    break;
	case ARCUS_PLUVIUS:
	    strncpy (spell->name, "Arcus Pluvius", 19);
	    break;

	case PARIAE_VIS:
	    strncpy (spell->name, "Pariae Vis", 19);
	    break;
	case EXIGERE:
	    strncpy (spell->name, "Exigere", 19);
	    break;
	case TERRAE_PASCET:
	    strncpy (spell->name, "Terrae Pascet", 19);
	    break;
	case PROCELLA_GELI:
	    strncpy (spell->name, "Procella Geli", 19);
	    break;

	case LOCUS_NOVUS:
	    strncpy (spell->name, "Locus Novus", 19);
	    break;
	case OBTESTARI:
	    strncpy (spell->name, "Obtestari", 19);
	    break;
	case DIRUMPERE:
	    strncpy (spell->name, "Dirumpere", 19);
	    break;
	case CHAOS:
	    strncpy (spell->name, "Chaos", 19);
	    break;
	case ARS_MAGICA_DEI:
	    strncpy (spell->name, "Ars Magica Dei", 19);
	    break;


	    /* End mage.  Begin cleric */

	case MEDERI:
	    strncpy (spell->name, "Mederi", 19);
	    break;
	case DAMNUM:
	    strncpy (spell->name, "Damnum", 19);
	    break;
	case LUMEN:
	    strncpy (spell->name, "Lumen", 19);
	    break;
	case BENEDICTUS:
	    strncpy (spell->name, "Benedictus", 19);
	    break;
	case PARMA:
	    strncpy (spell->name, "Parma", 19);
	    break;

	case FASCINARE:
	    strncpy (spell->name, "Fascinare", 19);
	    break;
	case VISUS_EMENDATUS:
	    strncpy (spell->name, "Visus Emendatus", 19);
	    break;
	case PLACIDUS_AER:
	    strncpy (spell->name, "Placidus Aer", 19);
	    break;
	case CORPUS_REPERIRE:
	    strncpy (spell->name, "Corpus Reperire", 19);
	    break;

	case AGNOSCERE:
	    strncpy (spell->name, "Agnoscere", 19);
	    break;
	case EXPERGERE:
	    strncpy (spell->name, "Expergere", 19);
	    break;
	case PAX:
	    strncpy (spell->name, "Pax", 19);
	    break;
	case SOLIS_ORTUS:
	    strncpy (spell->name, "Solis Ortus", 19);
	    break;
	case MAGICE_SICCARE:
	    strncpy (spell->name, "Magice Siccare", 19);
	    break;

	case MEDERI_POTENTI:
	    strncpy (spell->name, "Mederi Potenti", 19);
	    break;
	case SAUCIARE:
	    strncpy (spell->name, "Sauciare", 19);
	    break;
	case LAVABARE:
	    strncpy (spell->name, "Lavabare", 19);
	    break;
	case MAGNUS_PARMUM:
	    strncpy (spell->name, "Magnus Parmum", 19);
	    break;
	case VENTI_NOVACULA:
	    strncpy (spell->name, "Venti Novacula", 19);
	    break;

	case MAGNUS_MEDERUM:
	    strncpy (spell->name, "Magnus Mederum", 19);
	    break;
	case RENATUS:
	    strncpy (spell->name, "Renatus", 19);
	    break;
	case INVOCARE:
	    strncpy (spell->name, "Invocare", 19);
	    break;
	case ASTRI_PORTA:
	    strncpy (spell->name, "Astri Porta", 19);
	    break;
	case INTERFICERE:
	    strncpy (spell->name, "Interficere", 19);
	    break;

	case REVOCARE:
	    strncpy (spell->name, "Revocare", 19);
	    break;
	case SANARE:
	    strncpy (spell->name, "Sanare", 19);
	    break;
	case FUR_VITAE:
	    strncpy (spell->name, "Fur Vitae", 19);
	    break;
	case VENTI_IGNIS:
	    strncpy (spell->name, "Venti Ignis", 19);
	    break;

	case VENTI_PETRUS:
	    strncpy (spell->name, "Venti Petrus", 19);
	    break;
	case DIVINA_GRATIA:
	    strncpy (spell->name, "Divina Gratia", 19);
	    break;
	case VENTI_MORS:
	    strncpy (spell->name, "Venti Mors", 19);
	    break;
	case INFERUS_EXCITARE:
	    strncpy (spell->name, "Inferus Excitare", 19);
	    break;

	default:
	    spell->name[0] = '\0';
	    break;
	}
    if (spell->spellno == NO_SPELL)
	return (NULL);
    return (GwizRenderText (spell->name));
}

void ReadSpells (PlayerPawn *pawn)
{
    SDL_Surface *window = NULL;
    SDL_Surface *displace = NULL;
    SDL_Surface *magics[7];
    SDL_Rect wrect;
    char *mc[] = {
	"Mage spells",
	"Cleric spells",
	NULL
    };
    int widest = gwiz.font.width*18;
    int highest = gwiz.font.height*5;
    int i;

    for (i = 0; i < 7; i++)
	magics[i] = NewGwizSurface (widest, highest);

    switch (NewGwizMenu (gwiz.canvas, mc, -1, -1, 0))
	{
	case 0:
	    window = RenderReadSpellsWin (magics, pawn, 0);
	    break;
	case 1:
	    window = RenderReadSpellsWin (magics, pawn, 1);
	    break;
	}
    wrect.x = gwiz.canvas->w/2 - window->w/2;
    wrect.y = gwiz.canvas->h/2 - window->h/2;
    wrect.h = window->h;
    wrect.w = window->w;

    displace = NewGwizSurface (wrect.w, wrect.h);
    SDL_BlitSurface (gwiz.canvas, &wrect, displace, NULL);
    SDL_BlitSurface (window, NULL, gwiz.canvas, &wrect);
    SDL_Flip(gwiz.canvas);

    WaitForAnyKey ();

    SDL_BlitSurface (displace, NULL, gwiz.canvas, &wrect);
    SDL_Flip (gwiz.canvas);

    for (i = 0; i < 7; i++)
	SDL_FreeSurface (magics[i]);
    SDL_FreeSurface (window);
    SDL_FreeSurface (displace);
}

SDL_Surface *RenderReadSpellsWin (SDL_Surface **target, PlayerPawn *pawn,
				  int mode)
{
    SDL_Surface *area = NULL;
    SDL_Rect dest[7];
    int firstspell = (mode == 0 ? IGNIS : MEDERI);
    int lastspell = (mode == 0 ? MEDERI : NO_SPELL);
    int blockwidth = gwiz.font.width*18;
    int totalwidth = blockwidth*3 + gwiz.font.width*2;
    int blockheight = gwiz.font.height*5;
    int totalheight = blockheight*3 + gwiz.font.height*2;
    int column2 = BORDERWIDTH + gwiz.font.width*19;
    int column3 = BORDERWIDTH + gwiz.font.width*38;
    int knownspells = 0;
    int whichlevel;
    int i;

    for (i = 0; i < 7; i++)
	{
	    dest[i].x = 0;
	    dest[i].y = 0;
	    dest[i].h = gwiz.font.height;
	}

    area = NewTextBox (totalwidth, totalheight);

    for (i = firstspell; i < lastspell; i++)
	if (pawn->spellsknown[i])
	    {
		GwizSpell *spell = NewSpell (i);
		knownspells++;
		whichlevel = spell->level;
		/* FIXME: Segfault here.  why? */
		dest[whichlevel].w = spell->visual->pitch;
		SDL_BlitSurface (spell->visual, NULL, target[whichlevel],
				 &dest[whichlevel]);
		dest[whichlevel].y += gwiz.font.height;
		
		DestroySpell (&spell);
	    }

    dest[0].x = BORDERWIDTH;
    dest[0].y = BORDERHEIGHT;
    dest[1].x = column2;
    dest[1].y = BORDERHEIGHT;
    dest[2].x = column3;
    dest[2].y = BORDERHEIGHT;
    dest[3].x = BORDERWIDTH;
    dest[3].y = BORDERHEIGHT + gwiz.font.height*6; /* 5 for list, 1 blank */
    dest[4].x = column2;
    dest[4].y = dest[3].y;
    dest[5].x = column3;
    dest[5].y = dest[3].y;
    dest[6].x = BORDERWIDTH;
    dest[6].y = dest[3].y + gwiz.font.height*6;
    
    for (i = 0; i < 7; i++)
	{
	    dest[i].h = target[i]->h;
	    dest[i].w = target[i]->w;
	    SDL_BlitSurface (target[i], NULL, area, &dest[i]);
	}
	
    GwizLogEvent (__FILE__, __LINE__, "Registered %d spells for pawn: %s",
		  knownspells, pawn->name);

    return (area);
}
