/* redit.m,
 *
 * The Official (ie. dodgy) Raid'em map editor.  For historical
 * reasons, this one is also called REdit.
 */

#include <allegro.h>
#include <assert.h>
#include <objc/Object.h>
#include "adime/include/adime.h"
#include "common.h"
#include "group.h"
#include "gui/gui-dirty.h"
#include "gui/gui-keyboard.h"
#include "gui/gui-mouse.h"
#include "gui/gui-raid.h"
#include "gui/gui-widgets.h"
#include "gui/gui.h"
#include "init.h"
#include "map-editor/help.h"
#include "map-editor/map-proc.h"
#include "map-editor/mouse-label-proc.h"
#include "map-editor/palette-proc.h"
#include "map-editor/quit.h"
#include "music.h"
#include "projectiles/all-projs.h"
#include "seborrhea/seborrhea-font.h"
#include "sound.h"
#include "unit.h"
#include "units/all-units.h"


#define EDITOR_NAME			"REdit"
#define EDITOR_VERSION			"0.2"
#define EDITOR_NAME_AND_VERSION		EDITOR_NAME " " EDITOR_VERSION

int editing_mode;


static Frame *root_frame;
static BITMAP *dbuf;

MapPalette *map_palette;
static MapProc *map_editing_area;
static Label *the_label;

/*--------------------------------------------------------------*/
/* Editing mode button callbacks.				*/
/*--------------------------------------------------------------*/

static int set_editing_mode_parallax(Widget *_w, int _m, int _d)
{
    (void)_w, (void)_m, (void)_d;

    editing_mode = PARALLAX_MODE;
    if (map_palette)
	[map_palette receiveMessage:MSG_CHANGED_EDITING_MODE];
    return 0;
}

static int set_editing_mode_tiles(Widget *_w, int _m, int _d)
{
    (void)_w, (void)_m, (void)_d;

    editing_mode = TILE_MODE;
    if (map_palette)
	[map_palette receiveMessage:MSG_CHANGED_EDITING_MODE];
    return 0;
}

static int set_editing_mode_ground(Widget *_w, int _m, int _d)
{
    (void)_w, (void)_m, (void)_d;

    editing_mode = GROUND_MODE;
    if (map_palette)
	[map_palette receiveMessage:MSG_CHANGED_EDITING_MODE];
    return 0;
}

static int set_editing_mode_air(Widget *_w, int _m, int _d)
{
    (void)_w, (void)_m, (void)_d;

    editing_mode = AIR_MODE;
    if (map_palette)
	[map_palette receiveMessage:MSG_CHANGED_EDITING_MODE];
    return 0;
}

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

static void pick_music(void)
{
    char filename[PATH_MAX] = "music/";

    start_autopoll_music();
    if (adime_file_select("Play which song?", filename, "mp3", sizeof filename, 600, 400)) {
	stop_autopoll_music();
	play_mp3(filename);
    }
    else
	stop_autopoll_music();
}

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

static BOOL quit;
static void close_window_hook(void) { quit = YES; }

static void switch_into_redit(void) { [root_frame receiveMessage:MSG_REDRAW :0]; }

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

void redit_loop(const char *fn)
{
    quit = NO;

    if (fn)
	[map_editing_area loadMap:fn];

    while (!quit) {
	[root_frame update];
	clear_to_color(dbuf, makecol(0xd0, 0xd0, 0xc0));
	[root_frame draw:dbuf];

	poll_music();

	if (key[KEY_Q]) {
	    quit = do_quit_dialog();
	    [root_frame receiveMessage:MSG_REDRAW :0];
	}

	if (key[KEY_F1]) {
	    do_help_dialog();
	    [root_frame receiveMessage:MSG_REDRAW :0];
	}

	if (key[KEY_F2]) {
	    pick_music();
	    [root_frame receiveMessage:MSG_REDRAW :0];
	}
    }
}

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

static void make_gui(void);

int redit_init(void)
{
    if (adime_init() < 0)
	return -1;

    dbuf = create_bitmap(SCREEN_W, SCREEN_H);
    assert(dbuf);

    unit_init();
    unit_group_init();

    gui_init();
    make_gui();

    {					/* Load data. */
	unsigned int i;
	for (i = 0; i < total_air_classes; i++)
	    load_unit_data_for(air_units_table[i], YES);
	for (i = 0; i < total_ground_classes; i++)
	    load_unit_data_for(ground_units_table[i], NO);
    }

    set_window_title(EDITOR_NAME_AND_VERSION);
    set_window_close_hook(&close_window_hook);
    set_display_switch_callback(SWITCH_IN, switch_into_redit);

    return 0;
}

void redit_shutdown(void)
{
    root_frame = [root_frame free];

    adime_exit();
    gui_shutdown();

    if (dbuf) {
        destroy_bitmap(dbuf);
        dbuf = NULL;
    }

    mark_all_projectile_data_unnecessary();
    unit_group_shutdown();
    unit_shutdown();
}










/*------------------------------------------------------------*/
/* Yucky.  Stay away.                                         */
/*------------------------------------------------------------*/










static void make_gui(void)
{
    Pane *root;

    gui_raid_init();
    default_raid_font = (SebFont *)[base_sebum getSebumByName:"fonts/sui-generis-bold"];

    root_frame = [Frame new];
    root = [Pane new];
    assert(default_raid_font && root && root_frame);

    {					/* Map area. */
	VPackingBox *vbox = [VPackingBox newWithName:"Map VBox"];

	/* The mouse position label. */
	[vbox insertWidget:[[MousePositionLabel newWithName:"Mouse Position"]
			       setMaxHeight:15]];

	/* The map. */
	map_editing_area = [[MapProc newWithName:"The Map"]
			       setMinWidth:320];
	[vbox insertWidget:map_editing_area];

	[root insertWidget:vbox];
    }

    {					/* Palette. */
	VPackingBox *vbox = [[VPackingBox newWithName:"Palette VBox"]
				setMaxWidth:(64+4)*4+30];

	{				/* Editing mode buttons. */
	    HPackingBox *hbox = [[HPackingBox newWithName:"Editing Mode Buttons"]
				    setMaxHeight:25];

	    [hbox insertWidget:[[[Button newWithName:"Parallax Button"]
				    setText:"Parallax"]
				   setPushedProc:set_editing_mode_parallax]];

	    [hbox insertWidget:[[[Button newWithName:"Tiles Button"]
				    setText:"Tiles"]
				   setPushedProc:set_editing_mode_tiles]];
	    
	    [hbox insertWidget:[[[Button newWithName:"Ground Button"]
				    setText:"Ground"]
				   setPushedProc:set_editing_mode_ground]];
	    
	    [hbox insertWidget:[[[Button newWithName:"Air Button"]
				    setText:"Air"]
				   setPushedProc:set_editing_mode_air]];

	    [vbox insertWidget:hbox];
	}

	/* The palette. */
	map_palette = [[MapPalette newWithName:"Palette"]
			  setMapProcWidget:map_editing_area];
	[vbox insertWidget:map_palette];

	/* The unit selected (in the palette). */
	the_label = [[Label newWithName:"Palette Label"]
			setMaxHeight:15];
	[map_palette setLabelWidget:the_label];
	[vbox insertWidget:the_label];

	[root insertWidget:vbox];
    }

    [[root_frame setChild:root] setX:0 Y:0 W:dbuf->w H:dbuf->h];

    /* Startup begins in tile editing mode. */
    set_editing_mode_tiles(NULL, 0, 0);
}
