/*
 * Benchmark of Allegro built-in text output
 *
 * Copyright (c) 2003-2007 Kirill Kryukov
 *
 * This file is part of Glyph Keeper library, and may only be used,
 * modified, and distributed under the terms of the Glyph Keeper
 * license, located in the file 'license.txt' within this package.
 */


/*
 * This program benchmarks Allegro built-in text output speed.
 * It serves as a reference to compare the speed between different
 * libraries. It also can be used by itself to compare speed in
 * different graphics modes, screen/memory output etc.
 *
 * Running:
 *     bench_bare_alleg [<config_file>]
 *
 * If you specify the <config_file>, program reads all settings from it and
 * uses those settings it can use. (It can't use angle, italics, etc..).
 *
 * If you run it without arguments, default config file "bench.cfg" is used.
 *
 * Note about the font size. If you set the font size to 18 or more, external
 * bitmap font will be taken from "demofont.pcx". If you set the font size to
 * 17 or less, it will use Allegro's built-in tiny bitmap font.
 *
 * Use Vera.ttf font of sizes 25 and 12 with Glyph Keeper to compare with this
 * program.
 */

/* Standard includes. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <limits.h>
#include <ctype.h>

/* Target library. */
#include <allegro.h>

/* Code shared by several benchmark programs. */
#include "bench_utils.c"



time_t start_time, now, now1;
int char_count = 0;

int info_color;

BITMAP* bmp = 0;


void screen_message(int x,int y,char* text)
{
    textprintf_ex(screen,font,x,y,info_color,-1,text);
}


void screen_rect(int x1,int y1,int x2,int y2)
{
    rectfill(screen,x1,y1,x2,y2,info_color);
}


void update()
{
    int seconds = now1-start_time;
    int minutes = seconds/60;
    int hours;
    seconds -= minutes*60;
    hours = minutes/60;
    minutes -= hours*60;

    if (clip_on) set_clip_rect(bmp,0,0,screen_width-1,screen_height-1);
    rectfill(bmp,0,0,screen_width-1,area_top-1,0);
    textprintf_ex(bmp,font,15,11,info_color,0,"%02d:%02d:%02d  %ld chars/sec",hours,minutes,seconds,char_count/(now1-start_time));
    if (clip_on) set_clip_rect(bmp,SCREEN_W/4,SCREEN_H/4,SCREEN_W*3/4,SCREEN_H*3/4);
    blit(bmp,screen,0,0,0,0,screen_width,screen_height);
}


int main(int argc,char *argv[])
{
    FONT* font1 = 0;

    init_benchmark("bench_bare_alleg",argv[0],(argc>1)?argv[1]:0);

    if (allegro_init()) return 0;
    if (install_keyboard()) return 0;
    set_color_depth(color_depth);
    if (set_gfx_mode(GFX_AUTODETECT_WINDOWED,screen_width,screen_height,0,0)) return 0;
    info_color = makecol(128,192,128);

    if (text_size >= 18)
    {
        font1 = load_bitmap_font("demofont.pcx",0,0);
        if (!font1) font1 = load_bitmap_font("../fonts/demofont.pcx",0,0);
    }
    if (!font1) font1 = font;

    if (draw_to_screen) bmp = screen;
    else bmp = create_bitmap(screen_width,screen_height);
    if (clip_on) set_clip_rect(bmp,SCREEN_W/4,SCREEN_H/4,SCREEN_W*3/4,SCREEN_H*3/4);


    if (test_dataset_num_elements > 0)
    {
        int xmin = 220, xmax = xmin+78, xl = xmin, xr = xl;
        int i;

        fprintf(logfile,"Filling the test dataset of %d elements\n",test_dataset_num_elements);
        screen_message(text_x,text_y,"Filling the test dataset [          ]");

        for (i=0; i<test_dataset_num_elements; i++)
        {
            int w,h,c,n=0;

            do
            {
                test_dataset[i].length = min_string_length + rand_4() % string_length_variety;
                for (c=0; c<test_dataset[i].length; c++)
                {
                    ((char*)test_dataset[i].text)[c] = range_8_start + (rand_4() % range_8_length);
                }
                ((char*)test_dataset[i].text)[c] = 0;

                h = text_height(font1);
                w = text_length(font1,(char*)test_dataset[i].text);

                n++;
            }
            while ( (w >= area_width || h >= area_height) && n<100 );

            if (n >= 100)
            {
                fprintf(logfile,"Error: Font size is too large! One line of text does not even fit the screen!\n");
                exit(1);
            }

            test_dataset[i].x = area_left + rand_4()%(area_width-w);
            test_dataset[i].y = area_top + rand_4()%(area_height-h);

            test_dataset[i].text_color = rand_4() & 0xFFFFFF;
            if (background_on) test_dataset[i].back_color = rand_4() & 0xFFFFFF;
            else test_dataset[i].back_color = -1;

            xr = xmin+(i*(xmax-xmin)/test_dataset_num_elements);
            if (xr > xl) { screen_rect(xl,text_y,xr,text_y+6); xl = xr; }
        }
        fprintf(logfile,"Test dataset filled!\n");
        screen_message(text_x,text_y,"Filling the test dataset [          ] OK");
        text_y += text_line_height;
    }




    /* Waiting for the start of new second. */
    { int zero = time(0); do time(&start_time); while (start_time==zero); }
    now = start_time;


    /* Running the benchmark until the ESC or SPACE is hit. */
    if (test_dataset_num_elements > 0)
    {
        int di = 0, go_on = 1, i;

        while (go_on)
        {
            for (i=0; i<100; i++)
            {
                textout_ex ( bmp, font1, (char*)test_dataset[di].text,
                             test_dataset[di].x, test_dataset[di].y,
                             test_dataset[di].text_color, test_dataset[di].back_color );

                char_count += test_dataset[di].length;

                di++;
                if (di == test_dataset_num_elements) { di = 0; }
            }
            now1 = time(0);
            if (now1!=now) { update(); now = now1; }

            while (keypressed())
            {
                int k = readkey() >> 8;
                if (k == KEY_ESC || k == KEY_SPACE) go_on = 0;
                if (k == KEY_C) clear(bmp);
            }
        }
    }
    else
    {
        int go_on = 1, i;

        while (go_on)
        {
            for (i=0; i<100; i++)
            {
                int x,y,w,h,length,text_color,back_color;

                reset_str8();

                h = text_height(font1);
                w = text_length(font1,str8);
                x = area_left + rand_4()%(area_width-w);
                y = area_top + rand_4()%(area_height-h);

                text_color = rand_4() & 0xFFFFFF;
                if (background_on) back_color = rand_4() & 0xFFFFFF;
                else back_color = -1;

                textout_ex(bmp,font1,str8,x,y,text_color,back_color);
                char_count += length;
            }
            now1 = time(0);
            if (now1!=now) { update(); now = now1; }

            while (keypressed())
            {
                int k = readkey() >> 8;
                if (k == KEY_ESC || k == KEY_SPACE) go_on = 0;
                if (k == KEY_C) clear(bmp);
            }
        }
    }

    while (key[KEY_SPACE] || key[KEY_ESC]) { rest(1); }
    while (!key[KEY_SPACE] && !key[KEY_ESC]) { rest(1); }
    return 0;
}
END_OF_MAIN()
