/*******************************************************************************

  Copyright(c) 2003-2004 Aurelien Reynaud.

  This program 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.

  This program 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
  this program; if not, write to the Free Software Foundation, Inc., 59
  Temple Place - Suite 330, Boston, MA  02111-1307, USA.

  The full GNU General Public License is included in this distribution in the
  file called COPYING.

*******************************************************************************/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "ggiterm.h"
#include "debug.h"
#include <ggi/ggi.h>


/* External variables */
extern ggi_visual_t vis;
extern ggi_pixel color[];
extern int cell_w, cell_h;
extern ggi_visual_t backend_vis;


int native_cache_load(void *boxptr, wchar_t charcode, int fgcol, int bgcol, int underline)
{
	debug(DEBUG_FUNCTION,
	      "called with args (boxptr=[void*], charcode=0x%X, fg=%d, bg=%d, underline=%d",
	      (wint_t)charcode, fgcol, bgcol, underline);

	ggiSetGCBackground(backend_vis, color[bgcol]);
	ggiSetGCForeground(backend_vis, color[fgcol]);
	ggiPutc(backend_vis, 0, 1, (char)charcode);

	ggiSetGCForeground(backend_vis, color[bgcol]);
	ggiDrawHLine(backend_vis, 0, 0, cell_w);
	if (underline) {
		ggiSetGCForeground(backend_vis, color[fgcol]);
	}
	ggiDrawHLine(backend_vis, 0, cell_h-1, cell_w);
	
	ggiGetBox(backend_vis, 0, 0, cell_w, cell_h, boxptr);

	debug(DEBUG_FUNCTION, "Leaving");
	return 0;
}

wchar_t native_get_charmap()
{
	static wchar_t last = 0;
	
	debug(DEBUG_FUNCTION, "called with no args");
	if (last == 0) {
		last = 32;
	} else {
		last++;
		if (last == 127) {
			last = 0;
		}
	}
	debug(DEBUG_FUNCTION, "Leaving");
	return last;
}

int native_has_glyph(wchar_t glyph)
{
	return glyph < 128 ? 1 : 0;
}

int native_find_cell_size(int *width, int *height)
{
	ggi_mode current_mode;
	ggi_visual_t tmp_vis;
	int status = 0;

	debug(DEBUG_FUNCTION, "called with args (*width, *height");

	ggiGetMode(vis, &current_mode);
	debug(DEBUG_INIT, "Opening temporary memory visual");
	tmp_vis = ggiOpen("display-memory", NULL);
	if (tmp_vis == NULL) {
		error("Couldn't open memory visual!");
		status = 1;
		goto exit;
	}
	debug(DEBUG_INIT, "Setting mode for cache visual");
	status = ggiSetSimpleMode(tmp_vis, GGI_AUTO, GGI_AUTO, 1, current_mode.graphtype);
	if (status) {
		error("Cannot set mode");
		ggiClose(tmp_vis);
		goto exit;
	}
	ggiGetCharSize(tmp_vis, width, height);
	debug(DEBUG_INIT, "Native character size %d x %d", *width, *height);
	/* Add some space below for underlining */
	(*height) += 2;
	debug(DEBUG_INIT, "Using character size  %d x %d", *width, *height);
	ggiClose(tmp_vis);
exit:
	debug(DEBUG_FUNCTION, "Leaving");
	return status;
}

int native_init(int *width, int *height)
{
	int err;
	
	debug(DEBUG_FUNCTION, "called with no args");

	err = native_find_cell_size(width, height);
	if (err) {
		error("Couldn't find cell size");
		debug(DEBUG_FUNCTION, "Leaving");
		return 1;
	}

	debug(DEBUG_FUNCTION, "Leaving");
	return 0;
}

void native_exit()
{
	debug(DEBUG_FUNCTION, "called with no args");
	/* No resources to free here */
	debug(DEBUG_FUNCTION, "Leaving");
}
