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

  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 "lowlevel.h"
#include "terminal.h"


#define GGI_EVMASK	(emKeyPress|emKeyRepeat|emExpose)

/* External variables */
extern ggi_visual_t vis;
extern int cell_w, cell_h;
extern int visible_w, visible_h;
extern int current_origin;

void convert_area (unsigned int *x, unsigned int *y,
                   unsigned int *w, unsigned int *h)
{
	unsigned int tmpx, tmpy;
	
	debug (DEBUG_FUNCTION,
	       "called with args (*x=%d, *y=%d, *w=%d, *h=%d)", *x, *y, *w, *h);
	debug (DEBUG_INPUT, "Values on entry: %dx%d at (%d,%d)", *w, *h, *x, *y);
	debug (DEBUG_INPUT, "current_origin=%d", current_origin);
	tmpx = (*x+*w-1)/cell_w;
	tmpy = ((*y)-current_origin+(*h)-1)/cell_h;
	*x = *x/cell_w;
	*y = ((*y) - current_origin)/cell_h;
	*w = tmpx - *x + 1;
	*h = tmpy - *y + 1;
	debug (DEBUG_INPUT, "Values on exit %dx%d at (%d,%d)", *w, *h, *x, *y);
	debug (DEBUG_FUNCTION, "Leaving");
}

void redraw_area (unsigned int x, unsigned int y,
                  unsigned int w, unsigned int h)
{	
	debug (DEBUG_FUNCTION,
	       "called with args (x=%d, y=%d, w=%d, h=%d)", x, y, w, h);
	debug (DEBUG_INPUT, "Request to draw area %dx%d at (%d,%d)", w, h, x, y);
	
	/* Clip to the visible area */
	if (y < current_origin) {
		y = current_origin;
		h -= (current_origin - y);
	}
	if (y+h > current_origin+visible_h) {
		h = current_origin + visible_h - y;
	}
	/* Blank the area with background color */
	/*ggiSetGCForeground (vis, color[default_bgcolor]);
	ggiDrawBox (vis, x, y, w, h);*/
	
	/* Convert pixels to cells */
	convert_area (&x, &y, &w, &h);
	
	text_write_area (x, y, w, h);
	render_flush_area (x, y, w, h);
	
	debug (DEBUG_FUNCTION, "Leaving");
}

#ifndef DISABLE_RESIZE
int window_was_resized (int *w, int *h)
{
	int x, y, status=0;
	
	debug (DEBUG_FUNCTION, "Entering");
	
	ggiWmhGetSize (vis, &x, &y);
	/* This shouldn't be necessary, but as of 0.1.0, libggiwmh doesn't
	   return error codes, so it's a hint that something has failed... */
	if (x == 0 || y == 0) {
		error ("libggiwmh returned strange values (ignored)");
		return 0;
	} 
	if (x != visible_w || y != visible_h) {
		debug (DEBUG_INPUT, "WMH: window was resized to %dx%d", x, y);
		*w = x;
		*h = y;
		status = 1;
	}
	debug (DEBUG_FUNCTION, "Leaving");
	return status;
}
#endif /* DISABLE_RESIZE */

void expose_handle_events ()
{
	struct timeval tv;
	ggi_event event;
	int i;

	debug (DEBUG_FUNCTION, "Entering");
	tv.tv_sec = 0;
	tv.tv_usec = 0;
	
	if (ggiEventPoll (vis, emExpose, &tv)) {
		i = ggiEventsQueued (vis, emExpose);
		debug (DEBUG_INPUT, "Number of expose events queued: %d", i);
		while (i--) {
			ggiEventRead (vis, &event, emExpose);
			debug (DEBUG_INPUT,
			       "Expose event received for area %dx%d at (%d, %d)",
			       event.expose.w, event.expose.h,
			       event.expose.x, event.expose.y);
			redraw_area (event.expose.x, event.expose.y,
			             event.expose.w, event.expose.h);
		}
	}
	debug (DEBUG_FUNCTION, "Leaving");
}
