/*
  $Id: gtkmap.c,v 1.1 1999/10/25 14:07:07 issei Exp issei $
 */

#include <sys/types.h>
#include <signal.h>
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
#include <gdk/gdkx.h>
#include "winGTK.h"

/*
  if map_click is true, we do gtk_main_quit() when clicking map
 */
static int	 map_click;

static GtkWidget *map_scroll;
static GtkWidget *map;
static GdkPixmap *map_pixmap;
static GdkFont   *map_font;

static GdkGC	  *map_color_gc[N_NH_COLORS];

#ifdef	RADAR
static int	 radar_is_popuped;
static GtkWidget *radar;
static GtkWidget *radar_darea;
/*
  we use 2 pixmaps for radar.

  radar_pixmap keeps radar dot
  radar_pixmap2 keeps radar dot and frame rectangle
  */
static GdkPixmap *radar_pixmap;
static GdkPixmap *radar_pixmap2;

#define RADAR_MONSTER	MAP_YELLOW
#define RADAR_HUMAN	MAP_WHITE
#define RADAR_PET	MAP_GREEN
#define RADAR_OBJECT	MAP_BLUE

#define RADAR_WALL	MAP_GRAY
#define RADAR_FLOOR	MAP_DARK_GREEN
#define RADAR_DOOR	MAP_ORANGE
#define RADAR_LADDER	MAP_MAGENTA
#define RADAR_WATER	MAP_BLUE
#define RADAR_TRAP	MAP_RED
#define RADAR_SWALLOW	MAP_RED
#define RADAR_ICE	MAP_GRAY
#define RADAR_LAVA	MAP_ORANGE
#define RADAR_BRIDGE	MAP_GRAY
#define RADAR_AIR	MAP_CYAN
#define RADAR_CLOUD	MAP_GRAY
#define RADAR_BEAM	MAP_YELLOW

#endif

static GdkPixmap *tile_pixmap;
static GdkBitmap *tile_mask;

#define NH_TILE_CACHE_SIZE	256

static GdkPixmap *tile_cache_pixmap;
static GdkGC	 *clip_gc;
static GdkGC	 *map_gc;

/*
  BIT3DTILE is unser constructing. never define it
 */
#undef BIG3DTILE
#ifdef BIG3DTILE
#define NH_TILE_FILE	"floor.xpm"
#define	NH_TILE_WIDTH	48
#define	NH_TILE_HEIGHT	64
#define	NH_TILE_PER_COL	20
#define NH_TILE_3D_WIDTH	32
#define NH_TILE_3D_HEIGHT	32
#define NH_TILE_3D_OFSET	16
#define NH_TILE_CACHE_WIDTH	128
#define NH_TILE_CACHE_HEIGHT	128
#define NH_MAP_WIDTH		(NH_TILE_WIDTH * 80)
#define NH_MAP_HEIGHT		(NH_TILE_HEIGHT * 20)
#else
#ifdef BIGTILE
#define NH_TILE_FILE	"t32-1024.xpm"
#define	NH_TILE_WIDTH	32
#define	NH_TILE_HEIGHT	32
#define	NH_TILE_PER_COL	32
#define NH_TILE_3D_WIDTH	32
#define NH_TILE_3D_HEIGHT	32
#define NH_TILE_3D_OFSET	0
#define NH_TILE_CACHE_WIDTH	32
#define NH_TILE_CACHE_HEIGHT	32
#define NH_MAP_WIDTH		(NH_TILE_WIDTH * 80)
#define NH_MAP_HEIGHT		(NH_TILE_HEIGHT * 20)
#else
#define NH_TILE_FILE	"x11tiles"
#define	NH_TILE_WIDTH	16
#define	NH_TILE_HEIGHT	16
#define	NH_TILE_PER_COL	1
#define NH_TILE_3D_WIDTH	16
#define NH_TILE_3D_HEIGHT	16
#define NH_TILE_3D_OFSET	0
#define NH_TILE_CACHE_WIDTH	16
#define NH_TILE_CACHE_HEIGHT	16
#define NH_MAP_WIDTH		(NH_TILE_WIDTH * 80)
#define NH_MAP_HEIGHT		(NH_TILE_HEIGHT * 20)
#endif	/* BIGTILE */
#endif  /* 3DTILE */

#ifdef RADAR
#define NH_RADAR_UNIT	4
#define NH_RADAR_WIDTH	(80 * NH_RADAR_UNIT)
#define NH_RADAR_HEIGHT	(20 * NH_RADAR_UNIT)
#endif

static int	traditional = 0;

extern short	glyph2tile[];
extern int	root_width;
extern int	root_height;

int	cursx;
int	cursy;

static int	c_width;
static int	c_height;

static int	c_3dwidth;
static int	c_3dheight;
static int	c_3dofset;

static int	c_map_width;
static int	c_map_height;

#define	NH_FONT		"nh10"
#define	NH_DEF_FONT	"fixed"	

/*
  0: character
  1: tile
 */
void
nh_set_map_visual(int mode)
{
    int saved_t;
    int width, height;

    saved_t = traditional;

    traditional = !mode;

    if(saved_t != traditional){
	nh_map_clear();

	if(traditional){
	    c_width = gdk_string_width(map_font, "W");
	    c_height = map_font->ascent + map_font->descent;
	    c_3dwidth = c_width;
	    c_3dheight = c_height;
	    c_3dofset = 0;

	    c_map_width = 80 * c_width;
	    c_map_height = 20 * c_height;
	}
	else{
	    c_width = NH_TILE_WIDTH;
	    c_height = NH_TILE_HEIGHT;
	    c_3dwidth = NH_TILE_3D_WIDTH;
	    c_3dheight = NH_TILE_3D_HEIGHT;
	    c_3dofset = NH_TILE_3D_OFSET;

	    c_map_width = NH_MAP_WIDTH;
	    c_map_height = NH_MAP_HEIGHT;
	}

	width = c_map_width + 22;
	height = c_map_height + 22;

	if(width >= root_width)
	    width = root_width - 50;

	if(height >= root_height * .67)
	    height = root_height * .67 - 50;
	
	gtk_widget_set_usize(GTK_WIDGET(map_scroll), width, height);

	nh_map_check_visibility();
#ifdef RADAR
	nh_radar_update();
#endif
	doredraw();
    }
}

int
nh_get_map_visual(void)
{
    return !traditional;
}

/*
  fix tile number
 */
static int
fix_tile(int tile)
{
#if defined(FIGHTER) || !defined(BIGTILE)
    return tile;
#else
    int orgtile = tile;

    if(orgtile >= glyph2tile[PM_HEALER])
	++tile;
    if(orgtile >= glyph2tile[PM_HIPPOCRATES])
	++tile;
    if(orgtile >= glyph2tile[PM_CYCLOPS])
	++tile;
    if(orgtile >= glyph2tile[PM_ATTENDANT])
	++tile;
    if(orgtile >= glyph2tile[GLYPH_OBJ_OFF + HAWAIIAN_SHIRT])
	++tile;
    return tile;
#endif    
}

#ifdef RADAR
static gint
radar_expose_event(GtkWidget *widget, GdkEventExpose *event)
{
    gdk_draw_pixmap(
	widget->window,
	widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
	radar_pixmap2,
	event->area.x, event->area.y,
	event->area.x, event->area.y,
	event->area.width, event->area.height);

    return FALSE;
}
#endif

static gint
map_button_event(GtkWidget *widget, GdkEventButton *event)
{
    GTK_curs(NHW_MAP, event->x / 32, event->y / 32);

    if(map_click)
	gtk_main_quit();
    return FALSE;
}

static gint
map_expose_event(GtkWidget *widget, GdkEventExpose *event)
{
    gdk_draw_pixmap(
	widget->window,
	widget->style->fg_gc[GTK_WIDGET_STATE(widget)],
	map_pixmap,
	event->area.x, event->area.y,
	event->area.x, event->area.y,
	event->area.width, event->area.height);
    return FALSE;
}

void
nh_map_check_visibility()
{
    GtkAdjustment *adj;
    int width, height;
    int x, y;
    int adjx, adjy;

    x = cursx;
    y = cursy;

    if(map_scroll){
	width = map_scroll->allocation.width;
	height = map_scroll->allocation.height;

	adj = gtk_scrolled_window_get_vadjustment(
	    GTK_SCROLLED_WINDOW(map_scroll)
	    );
	if(traditional)
	    adjy = (y - 10) * c_3dheight;
	else
	    adjy = y * c_3dheight - height/2;

	if(adjy > c_map_height - height)
	    adjy = c_map_height - height;

	gtk_adjustment_set_value(adj, adjy);
	 
	adj = gtk_scrolled_window_get_hadjustment(
	    GTK_SCROLLED_WINDOW(map_scroll)
	    );
	if(traditional)
	    adjx = (x - 40) * c_3dwidth;
	else
	    adjx = x * c_3dwidth - width/2 + (20 - y) * c_3dofset;

	if(adjx > c_map_width - width)
	    adjx = c_map_width - width;

	gtk_adjustment_set_value(adj, adjx);
    }
}

void
nh_map_clear()
{
#ifdef RADAR
    GdkRectangle update_rect;
#endif

    if(traditional){
	gdk_draw_rectangle(
	    map_pixmap, map->style->black_gc,
	    TRUE, 0, 0, c_map_width, c_map_height);
	 
	gdk_draw_pixmap(
	    map->window,
	    map->style->fg_gc[GTK_WIDGET_STATE(map)],
	    map_pixmap,
	    0, 0,
	    0, 0,
	    c_map_width, c_map_height);
    }
    else{
	gdk_draw_rectangle(
	    map_pixmap, map->style->black_gc,
	    TRUE, 0, 0, c_map_width, c_map_height);
	
	gdk_draw_pixmap(
	    map->window,
	    map->style->fg_gc[GTK_WIDGET_STATE(map)],
	    map_pixmap,
	    0, 0,
	    0, 0,
	    c_map_width, c_map_height);
    }
#ifdef RADAR
    gdk_draw_rectangle(
	radar_pixmap, map->style->black_gc,
	TRUE, 0, 0, NH_RADAR_WIDTH, NH_RADAR_HEIGHT);

    update_rect.x = 0;
    update_rect.y = 0;
    update_rect.width = NH_RADAR_WIDTH;
    update_rect.height = NH_RADAR_HEIGHT;

    gtk_widget_draw(radar, &update_rect);
    if(radar_is_popuped)
	gdk_window_raise(radar->window);
#endif
}

void
nh_map_destroy()
{
    map_scroll = NULL;
}

GtkWidget *
nh_map_new(GtkWidget *w)
{
    int i;
    int width, height;

    map_scroll = gtk_scrolled_window_new(
	NULL, NULL);

    gtk_scrolled_window_set_policy(
	GTK_SCROLLED_WINDOW(map_scroll),
	GTK_POLICY_AUTOMATIC,
	GTK_POLICY_AUTOMATIC);

    map = gtk_drawing_area_new();
    gtk_signal_connect(GTK_OBJECT(map), "expose_event",
		       GTK_SIGNAL_FUNC(map_expose_event), NULL);

    gtk_signal_connect(GTK_OBJECT(map), "button_press_event",
		       GTK_SIGNAL_FUNC(map_button_event), NULL);

    gtk_widget_set_events(map, GDK_EXPOSURE_MASK
			  | GDK_BUTTON_PRESS_MASK);

/*
  load font

  GTK nethack automaticaly
 */

    {
	int i, n;
	char **path;
	char **new_path;

	path = XGetFontPath(GDK_DISPLAY(), &n);
	for(i=0 ; i<n ; ++i)
	    if(!strncmp(path[i], HACKDIR, strlen(HACKDIR)))
		goto NextStep;

	new_path = (char **)malloc(sizeof(char *) * (n + 1));
	for(i=0 ; i<n ; ++i)
	    new_path[i] = path[i];

	new_path[n] = HACKDIR;

	XSetFontPath(GDK_DISPLAY(), new_path, n+1);
    NextStep:
    }

    map_font = gdk_font_load(NH_FONT);
    if(!map_font)
	map_font = gdk_font_load(NH_DEF_FONT);

    if(!map_font)
	panic("Cannot open fixed font!");

/*
  load tile
 */
    tile_pixmap = gdk_pixmap_create_from_xpm(
	w->window,
	&tile_mask,
	&w->style->black,
	NH_TILE_FILE
	);

    tile_cache_pixmap = gdk_pixmap_new(
	w->window,
	NH_TILE_CACHE_WIDTH * NH_TILE_CACHE_SIZE,
	NH_TILE_CACHE_HEIGHT, -1);

    map_gc = gdk_gc_new(w->window);
    clip_gc = gdk_gc_new(w->window);

    if(tile_mask)
	gdk_gc_set_clip_mask(clip_gc, tile_mask);

    if(traditional){
 	c_height = map_font->ascent + map_font->descent;
	c_width = gdk_string_width(map_font, "W");
    }
    else{
	c_width = NH_TILE_WIDTH;
 	c_height = NH_TILE_HEIGHT;
	c_3dwidth = NH_TILE_3D_WIDTH;
	c_3dheight = NH_TILE_3D_HEIGHT;
	c_3dofset = NH_TILE_3D_OFSET;

    }
    c_map_width = NH_MAP_WIDTH;
    c_map_height = NH_MAP_HEIGHT;

    gtk_drawing_area_size(
	GTK_DRAWING_AREA(map),
	NH_MAP_WIDTH, NH_MAP_HEIGHT);


    map_pixmap = gdk_pixmap_new(
	w->window,
	NH_MAP_WIDTH, NH_MAP_HEIGHT, -1);

    gtk_scrolled_window_add_with_viewport(
	GTK_SCROLLED_WINDOW(map_scroll),
	map);
/*
  set map area size
  */
    width = NH_MAP_WIDTH + 22;
    height = NH_MAP_HEIGHT + 22;

    if(width >= root_width)
	width = root_width - 50;

    if(height >= root_height * .67)
	height = root_height * .67 - 50;
    
    gtk_widget_set_usize(GTK_WIDGET(map_scroll), width, height);
/*
  set gc 
 */
    for(i=0 ; i < N_NH_COLORS ; ++i){
	map_color_gc[i] = gdk_gc_new(w->window);
	gdk_gc_set_foreground(map_color_gc[i], &nh_color[i]);
	gdk_gc_set_background(map_color_gc[i], &nh_color[MAP_BACKGROUND]);
    }

    return map_scroll;
}

/*
  create radar
 */

#ifdef RADAR
GtkWidget *
nh_radar_new(GtkWidget *w)
{
    radar = gtk_window_new(GTK_WINDOW_TOPLEVEL);

#ifdef JNETHACK
    gtk_window_set_title(GTK_WINDOW(radar), "JNetHack Radar");
#else
    gtk_window_set_title(GTK_WINDOW(radar), "NetHack Radar");
#endif

    radar_darea = nh_gtk_new_and_add(gtk_drawing_area_new(), radar, "");
    gtk_drawing_area_size(
	GTK_DRAWING_AREA(radar_darea),
	NH_RADAR_WIDTH, NH_RADAR_HEIGHT);

    gtk_signal_connect(
	GTK_OBJECT(radar_darea), "expose_event",
	GTK_SIGNAL_FUNC(radar_expose_event), NULL);
  
    radar_pixmap = gdk_pixmap_new(
	w->window,
	NH_RADAR_WIDTH, NH_RADAR_HEIGHT, -1);
  
    radar_pixmap2 = gdk_pixmap_new(
	w->window,
	NH_RADAR_WIDTH, NH_RADAR_HEIGHT, -1);
  
    return radar;
}
#endif

/*
  clip mask drawing is very slow, so we cache picture data
  by [bg + object]
 */
static int
nh_tile_cache(int bgtile, int objtile)
{
    static struct {
	int bgtile;
	int objtile;
    }tile_cache[NH_TILE_CACHE_SIZE], *c;

    int	simple_hash;
    int bg_x, bg_y;
    int obj_x, obj_y;
    int dst_x, dst_y;

    bgtile = bgtile;
    objtile = objtile;
    
    simple_hash = (bgtile + objtile) % NH_TILE_CACHE_SIZE;
    c = &tile_cache[simple_hash];

    dst_x = simple_hash * c_width;
    dst_y = 0;

    if(c->bgtile == bgtile && c->objtile == objtile)
	;
    else{
	bg_x = (bgtile % NH_TILE_PER_COL) * c_width;
	bg_y = (bgtile / NH_TILE_PER_COL) * c_height;
	obj_x = (objtile % NH_TILE_PER_COL) * c_width;
	obj_y = (objtile / NH_TILE_PER_COL) * c_height;

	gdk_gc_set_clip_origin(
	    clip_gc,
	    dst_x - bg_x, dst_y - bg_y
	    );
/*
  Anyone know the function which copy from pixmap to pixmap in GDK?
  */
	gdk_window_copy_area(
	    tile_cache_pixmap,
	    clip_gc,
	    dst_x, dst_y,
	    tile_pixmap,
	    bg_x, bg_y,
	    c_width, c_height);

	if(objtile != bgtile){
	    gdk_gc_set_clip_origin(
		clip_gc,
		dst_x - obj_x , dst_y - obj_y
		);
	    
/*
  Anyone know the function which copy from pixmap to pixmap in GDK?
  */
	    gdk_window_copy_area(
		tile_cache_pixmap,
		clip_gc,
		dst_x, dst_y,
		tile_pixmap,
		obj_x, obj_y,
		c_width, c_height);
	}

	c->bgtile = bgtile;
	c->objtile = objtile;
    }

    return dst_x;
}

#ifdef RADAR
void
nh_print_radar(int x, int y, int glyph)
{
    int c;
    /*
      int tile = glyph2tile[glyph];
      */
    c = MAP_BLACK;

    if(glyph < PM_ARCHEOLOGIST)
	c = RADAR_MONSTER;
    else if(glyph_is_monster(glyph))
	c = RADAR_HUMAN;
    else if(glyph_is_pet(glyph))
	c = RADAR_PET;
    else if(glyph_is_object(glyph))
	c = RADAR_OBJECT;
    else if(glyph_is_trap(glyph))
	c = RADAR_TRAP;
    else if(glyph_is_swallow(glyph))
	c = RADAR_SWALLOW;
    else if(glyph_is_cmap(glyph)){
	if(glyph == GLYPH_CMAP_OFF)
	    ;
	else if(glyph <= GLYPH_CMAP_OFF + S_trwall)
	    c = RADAR_WALL;
	else if(glyph <= GLYPH_CMAP_OFF + S_hcdoor)
	    c = RADAR_DOOR;
	else if(glyph <= GLYPH_CMAP_OFF + S_litcorr)
	    c = RADAR_FLOOR;
	else if(glyph <= GLYPH_CMAP_OFF + S_dnladder)
	    c = RADAR_LADDER;
	else if(glyph <= GLYPH_CMAP_OFF + S_pool)
	    c = RADAR_WATER;
	else if(glyph <= GLYPH_CMAP_OFF + S_ice)
	    c = RADAR_ICE;	/* fountain sink ice */
	else if(glyph <= GLYPH_CMAP_OFF + S_lava)
	    c = RADAR_LAVA;	/* lava */
	else if(glyph <= GLYPH_CMAP_OFF + S_hcdbridge)
	    c = RADAR_BRIDGE;	/* bridge */
	else if(glyph <= GLYPH_CMAP_OFF + S_air)
	    c = RADAR_AIR;	/* air */
	else if(glyph <= GLYPH_CMAP_OFF + S_cloud)
	    c = RADAR_CLOUD;	/* cloud */
	else if(glyph <= GLYPH_CMAP_OFF + S_water)
	    c = RADAR_WATER;	/* water */
	else if(glyph < GLYPH_CMAP_OFF + S_explode9)
	    c = RADAR_BEAM;	/* beam */
    }
    else
	c = RADAR_WALL;

    gdk_draw_rectangle(
	radar_pixmap, map_color_gc[c],
	TRUE, 
	x * NH_RADAR_UNIT, y * NH_RADAR_UNIT,
	NH_RADAR_UNIT, NH_RADAR_UNIT);
}
#endif

#ifdef TEXTCOLOR
#define zap_color(n)	(zapcolors[n])
#define cmap_color(n)	(defsyms[n].color)
#define obj_color(n)	(objects[n].oc_color)
#define mon_color(n)	(mons[n].mcolor)
#define pet_color(n)	(mons[n].mcolor)
#else
#define zap_color(n)	(n)
#define cmap_color(n)	(n)
#define obj_color(n)	(n)
#define mon_color(n)	(n)
#define pet_color(n)	(n)
#endif

void
GTK_print_glyph(winid id, XCHAR_P x, XCHAR_P y, int glyph)
{
    char ch;
    register int offset;
    GdkRectangle update_rect;
    int color;
#ifdef RADAR
    nh_print_radar(x, y, glyph);
#endif
    
    color = 0;
    if(traditional){
	if ((offset = (glyph - GLYPH_SWALLOW_OFF)) >= 0) {	/* swallow */
	    ch = (uchar) showsyms[S_sw_tl + (offset & 0x7)];
	    color = mon_color(offset>>3);
	}
	else if ((offset = (glyph - GLYPH_ZAP_OFF)) >= 0) {	/* zap beam */
	    ch = showsyms[S_vbeam + (offset & 0x3)];
	    color = zap_color(offset>>2);
	}
	else if ((offset = (glyph - GLYPH_CMAP_OFF)) >= 0) {	/* cmap */
	    ch = showsyms[offset];
	    color = cmap_color(offset);
	}
	else if ((offset = (glyph - GLYPH_OBJ_OFF)) >= 0) {	/* object */
	    ch = oc_syms[(int)objects[offset].oc_class];
	    color = obj_color(offset);
	}
	else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) {	/* a corpse */
	    ch = oc_syms[(int)objects[CORPSE].oc_class];
	    color = mon_color(offset);
	}
	else if ((offset = (glyph - GLYPH_PET_OFF)) >= 0) {	/* a pet */
	    ch = monsyms[(int)mons[offset].mlet];
	    color = pet_color(offset);
	}
	else{							/* a monster */
	    ch = monsyms[(int)mons[glyph].mlet];
	    color = mon_color(glyph);
	}

	update_rect.x = x * c_width;
	update_rect.y = y * c_height - (traditional ? map_font->ascent : 0);
	update_rect.width = c_width;
	update_rect.height = c_height;

#ifdef TEXTCOLOR	
	gdk_draw_rectangle(
	    map_pixmap, map_color_gc[MAP_BACKGROUND],
	    TRUE, x * c_width, y * c_height - (traditional ? map_font->ascent : 0), c_width, c_height);

	gdk_draw_text(
	    map_pixmap, map_font,
	    map_color_gc[color],
	    x * c_width, y * c_height, &ch, 1);

	if(glyph_is_pet(glyph) && iflags.hilite_pet){
	    gdk_draw_rectangle(
		map_pixmap,
		map_color_gc[MAP_RED],
		FALSE,
		x * c_width, y * c_height - (traditional ? map_font->ascent : 0),
		c_width - 1, c_height - 1
		);
	}
#else
	gdk_draw_rectangle(
	    map_pixmap, map->style->bg_gc,
	    TRUE, x * c_width, y * c_height - (traditional ? map_font->ascent : 0), c_width, c_height);

	gdk_draw_text(
	    map_pixmap, map_font,
	    map->style->black_gc,
	    x*c_width, y*c_height, &ch, 1);
#endif
	gtk_widget_draw(map, &update_rect);
    }
    else{
	struct rm *lev = &levl[x][y];
	int tile;
	int bgtile;
	int src_x, src_y;
	int dst_x, dst_y;

	tile = fix_tile(glyph2tile[glyph]);
	if(Blind || (viz_array && !cansee(x, y)))
	    bgtile = fix_tile(glyph2tile[lev->glyph]);
	else
	    bgtile = fix_tile(glyph2tile[back_to_glyph(x, y)]);

#ifdef	BIG3DTILE
	src_x = (tile % NH_TILE_PER_COL) * c_width;
	src_y = (tile / NH_TILE_PER_COL) * c_height;
	dst_x = x * c_3dwidth + (20 - y) * c_3dofset;
	dst_y = y * c_3dheight;

	update_rect.x = dst_x;
	update_rect.y = dst_y;
	update_rect.width = c_width;
	update_rect.height = c_height;

	gdk_gc_set_clip_origin(
	    clip_gc,
	    dst_x - src_x , dst_y - src_y
	    );

	gdk_window_copy_area(
	    map_pixmap,
	    clip_gc,
	    dst_x, dst_y,
	    tile_pixmap,
	    src_x, src_y,
	    c_width, c_height);
#else
	src_x = nh_tile_cache(bgtile, tile);
	src_y = 0;
	dst_x = x * c_3dwidth + (20 - y) * c_3dofset;
	dst_y = y * c_3dheight;

	update_rect.x = dst_x;
	update_rect.y = dst_y;
	update_rect.width = c_width;
	update_rect.height = c_height;

/*
  Anyone know the function which copy from pixmap to pixmap in GDK?
  */
	gdk_window_copy_area(
	    map_pixmap,
	    map_gc,
	    dst_x, dst_y,
	    tile_cache_pixmap,
	    src_x, src_y,
	    c_width, c_height);
#endif

	if(glyph_is_pet(glyph) && iflags.hilite_pet){
	    gdk_draw_rectangle(
		map_pixmap,
		map_color_gc[MAP_RED],
		FALSE,
		dst_x, dst_y,
		c_width - 1, c_height - 1
		);
	}
	gtk_widget_draw(map, &update_rect);
    }
}

void
GTK_curs(winid id, int x, int y)
{
    GdkRectangle update_rect;

    if(id != NHW_MAP)
	return;

    update_rect.x = cursx * c_3dwidth + (20 - y) * c_3dofset;
    update_rect.y = cursy * c_3dheight - (traditional ? map_font->ascent : 0);
    update_rect.width = c_width;
    update_rect.height = c_height;

    gtk_widget_draw(map, &update_rect);

    cursx = x;
    cursy = y;

    update_rect.x = x * c_3dwidth + (20 - y) * c_3dofset;
    update_rect.y = y * c_3dheight - (traditional ? map_font->ascent : 0);
    update_rect.width = c_width;
    update_rect.height = c_height;

    gdk_draw_rectangle(
	map->window, map->style->white_gc, FALSE,
	update_rect.x, update_rect.y,
	c_width - 1, c_height - 1);
}

#ifdef RADAR
void
nh_radar_update()
{
    GdkRectangle update_rect;
    GtkAdjustment *hadj, *vadj;

    if(flags.radar && !radar_is_popuped){
	gtk_widget_show_all(radar);
	radar_is_popuped= 1;
    }
    if(!flags.radar && radar_is_popuped){
	gtk_widget_hide_all(radar);
	radar_is_popuped= 0;
    }
    
    if(map_scroll){
	hadj = gtk_scrolled_window_get_hadjustment(
	    GTK_SCROLLED_WINDOW(map_scroll)
	    );
	    
	vadj = gtk_scrolled_window_get_vadjustment(
	    GTK_SCROLLED_WINDOW(map_scroll)
	    );
/*
  Anyone know the function which copy from pixmap to pixmap in GDK?
  */
	gdk_window_copy_area(
	    radar_pixmap2, map->style->white_gc,
	    0, 0,
	    radar_pixmap,
	    0, 0, 
	    NH_RADAR_WIDTH, NH_RADAR_HEIGHT);
	
	gdk_draw_rectangle(
	    radar_pixmap2, map->style->white_gc,
	    FALSE,
	    hadj->value / c_width * NH_RADAR_UNIT,
	    vadj->value / c_height * NH_RADAR_UNIT,
	    hadj->page_size / c_width * NH_RADAR_UNIT,
	    vadj->page_size / c_height * NH_RADAR_UNIT);
	
	update_rect.x = 0;
	update_rect.y = 0;
	update_rect.width = NH_RADAR_WIDTH;
	update_rect.height = NH_RADAR_HEIGHT;

	gtk_widget_draw(radar, &update_rect);
	if(radar_is_popuped)
	    gdk_window_raise(radar->window);
    }
    ;
}
#endif

void
GTK_cliparound(int x, int y)
{
    ;
}

void
nh_map_click(int f)
{
    map_click = f;
}

void
nh_map_pos(int *x, int *y)
{
    *x = cursx;
    *y = cursy;
}
