/* newmenu-credits.m,
 */

#include <allegro.h>
#include "common.h"
#include "input.h"
#include "newmenu-credits.h"
#include "newmenu-dirty.h"
#include "newmenu.h"
#include "seborrhea/seborrhea-allegro.h"
#include "seborrhea/seborrhea-font.h"


#define DECORATION_UNDERLINE		0x01
#define DECORATION_DOUBLE_UNDERLINE	0x02
#define DECORATION_POST_BLANK_LINE	0x04


typedef struct {
    const char *text;
    const char *font_name;
    int colour;
    int decoration;
} credits_item_t;


static credits_item_t credits_text[] = {
    { GAME_NAME,			"fonts/elle40", 0, 0 },
    { "Version " GAME_VERSION,		"fonts/elle16", 0, DECORATION_UNDERLINE|DECORATION_DOUBLE_UNDERLINE|DECORATION_POST_BLANK_LINE },

    { "PROGRAMMING",			"fonts/elle30", 0, DECORATION_UNDERLINE },
    { "David Wang",			"fonts/elle24", 1, DECORATION_POST_BLANK_LINE },

    { "GRAPHICS",			"fonts/elle30", 0, DECORATION_UNDERLINE },
    { "David Wang",			"fonts/elle24", 1, DECORATION_POST_BLANK_LINE },

    { "ADDITIONAL CODE",		"fonts/elle30", 0, DECORATION_UNDERLINE },
    { "Peter Wang",			"fonts/elle24", 1, DECORATION_POST_BLANK_LINE },

    { "ADDITIONAL UNIT DESIGN",		"fonts/elle30", 0, DECORATION_UNDERLINE },
    { "Peter Wang (3)",			"fonts/elle24", 1, DECORATION_POST_BLANK_LINE },

    { "SPECIAL THANKS",			"fonts/elle30", 0, DECORATION_UNDERLINE },
    { "Allegro",			"fonts/elle24", 1, 0 },
    { " by Shawn & co.",		"fonts/elle24", 2, DECORATION_POST_BLANK_LINE },
    { "AllegroMP3",			"fonts/elle24", 1, 0 },
    { " by Javier Gonzalez",		"fonts/elle24", 2, DECORATION_POST_BLANK_LINE },
    { "FBlend",				"fonts/elle24", 1, 0 },
    { " by Robert Ohannessian",		"fonts/elle24", 2, DECORATION_POST_BLANK_LINE },
    { "Glyph Keeper",			"fonts/elle24", 1, 0 },
    { " by Kirill Kryukov",		"fonts/elle24", 2, DECORATION_POST_BLANK_LINE },
    { "loadpng",			"fonts/elle24", 1, 0 },
    { " by Peter Wang",			"fonts/elle24", 2, DECORATION_POST_BLANK_LINE },
    { "Adime",				"fonts/elle24", 1, 0 },
    { " by Sven Sandberg",		"fonts/elle24", 2, DECORATION_POST_BLANK_LINE },
    { "Force Feedback Code",		"fonts/elle24", 1, 0 },
    { " by Marcello Bastea-Forte",	"fonts/elle24", 2, DECORATION_POST_BLANK_LINE },

    { "FONTS",				"fonts/elle30", 0, DECORATION_UNDERLINE },
    { "Ben Nathan",			"fonts/elle24", 1, 0 },
    { "Brian Kent",			"fonts/elle24", 1, 0 },
    { "Ray Larabie",			"fonts/elle24", 1, DECORATION_POST_BLANK_LINE },

    { NULL, NULL, 0, 0 }
};

/*--------------------------------------------------------------*/

/* Returns YES if finished drawing. */
static BOOL draw_credits(BITMAP *dest, int y)
{
    BOOL exit = YES;
    int ln, r, g, b, h;
    int x1=dest->w, y1=y, x2=0, y2=0;	/* Dirty rect. */

    for (ln = 0; credits_text[ln].text; ln++) {
	credits_item_t *line = &credits_text[ln];
	SebFont *font = [base_sebum getSebumByName:line->font_name];
	if (not font)
	    continue;

	h = [font textHeight];

	if (y > dest->h)
	    break;
	elif (y < -h-3)			/* -3 for underline */
	    goto next;

	{				/* Colours. */
	    int delta = ABS((y + h/2) - SCREEN_H/2);

	    if (line->colour == 0)   { r = 0xa0; g = 0x20; b = 0x20; }
	    elif (line->colour == 1) { r = 0x80; g = 0x80; b = 0xff; }
	    elif (line->colour == 2) { r = 0x60; g = 0x60; b = 0xc0; }
	    else r = g = b = 0;

	    r *= MAX((1.0 - 0.75*delta/(SCREEN_H/2)), 0.25);
	    g *= MAX((1.0 - 0.75*delta/(SCREEN_H/2)), 0.25);
	    b *= MAX((1.0 - 0.75*delta/(SCREEN_H/2)), 0.25);
	}

	if (line->text[0] == ' ') {	/* Right aligned text. */
	    int l = [font textLength:line->text];
	    [font putString:line->text+1 To:dest X:dest->w*8/10 Y:y Colour:r:g:b Alignment:ALIGN_RIGHT Decoration:DECORATION_OUTLINE];
	    x1 = MIN(x1, dest->w*8/10-l);
	    x2 = MAX(x2, dest->w*8/10);
	}
	else {				/* Centre text. */
	    int l = [font textLength:line->text];
	    [font putString:line->text To:dest X:dest->w/2 Y:y Colour:r:g:b Alignment:ALIGN_CENTRE Decoration:DECORATION_OUTLINE];
	    x1 = MIN(x1, (dest->w-l)/2);
	    x2 = MAX(x2, (dest->w+l)/2);
	}
	y1 = MIN(y1, y);
	y2 = MAX(y2, y+h);

	/* (Double-)Underline.  (Triple exclamation mark!!!) */
	if (line->decoration & DECORATION_UNDERLINE) {
	    int c = makecol(r, g, b);

	    hline(dest, dest->w*25/100, y+h-3, dest->w*75/100, c);
	    x1 = MIN(x1, dest->w*25/100);
	    x2 = MAX(x2, dest->w*75/100);

	    if (line->decoration & DECORATION_DOUBLE_UNDERLINE)
		hline(dest, dest->w*25/100, y+h-1, dest->w*75/100, c);
	}

	/* Text still on screen -> don't exit. */
	exit = NO;

    next:
	y += h;
	if (credits_text[ln].decoration & DECORATION_POST_BLANK_LINE)
	    y += 20;
    }

    {					/* Dirty. */
	/* Plus-minus 1 in case of round off errors. */
	x1 = MAX(0, x1-1);
	y1 = MAX(0, y1-1);
	x2 = MIN(dest->w, x2+1);
	y2 = MIN(dest->h, y2+1);

	mark_dirty_rectangle(x1, y1, x2-x1+1, y2-y1+1);
    }

    blit_dirty_rectangles(dest, screen);
    return exit;
}

void roll_credits(BITMAP *dbuf)
{
    BOOL exit = NO, redraw = YES;
    BITMAP *bg = [(SebImageAllegro *)[menu_sebum getSebumByName:"credits"] bitmap];
    int y = SCREEN_H;

    mark_entire_screen_dirty();

    while (not (exit || emergency_exit)) {
	while (counter) {
	    counter--;
	    y--;
	    redraw = YES;

	    menu_common_update();

	    if (okay_released() || menu_released())
		exit = YES;

	    rest(0);
	}

	if (redraw && not exit) {
	    redraw = NO;
	    blit(bg, dbuf, 0, 0, 0, 0, dbuf->w, dbuf->h);
	    exit = draw_credits(dbuf, y);
	}
    }
}
