/* toon_draw.c - draw and erase the toons 
 * -copyright-
#-# 
#-# Copyright (C) 1999-2001  Robin Hogan, 2021-2026 Willem Vermin
#-# 
#-# 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
#-# 
*/
#include <stdio.h>
#include "toon.h"
#include "debug.h"
#include "utils.h"
#include "windows.h"
/* DRAWING FUNCTIONS */

/* Draw the toons from toon[0] to toon[n-1] */
/* Currently always returns 0 */
int ToonDraw(Toon *t, int n)
{
   P("ToonDraw"); //printxwindowattrs(toon_display,toon_root1);
   if (ConditionalClear)
   {
      P("clearscreen\n");
      ClearScreen();
      ConditionalClear = 0;
   }

   int i;
   for (i = 0; i < n; i++, t++) {
      if (t->active) {
	 ToonData *data = toon_data[t->genus] + t->type;
	 int width      = data->width;
	 int height     = data->height;
	 int direction  = t->direction;
	 if (direction >= data->ndirections) {
	    direction = 0;
	 }

	 XSetClipOrigin(toon_display, toon_drawGC,
	       t->x-width*t->frame, t->y-height*direction); 
	 XSetClipMask(toon_display, toon_drawGC, data->mask);   

	 P("xcopyarea %#lx %5d %5d w: %5d h: %5d x: %f y: %f %f %f\n",toon_root,width*t->frame,height*direction,
	       width,height,t->x,t->y,t->x_map,t->y_map);

	 XCopyArea(toon_display, data->pixmap,
	       toon_root,toon_drawGC,width*t->frame,height*direction,
	       width,height,t->x,t->y);
	 P("xcopyarea end\n");
	 XSetClipMask(toon_display, toon_drawGC, None);
	 t->x_map = t->x;
	 t->y_map = t->y;
	 t->width_map = width;
	 t->height_map = height;
	 t->mapped = 1;
      }
      else {
	 t->mapped = 0;
      }
   }
   return 0;
}

/* Erase toons toon[0] to toon[n-1] */
/* Currently always returns 0 */
/* If toon_expose is set then every 100th frame an expose event will
 * be sent to redraw any desktop icons */
int ToonErase(Toon *t, int n)
{
   static int minx     = 10000;
   static int maxx     = 0;
   static int miny     = 10000;
   static int maxy     = 0;
   static double tprev = 0;
   int time_for_expose;

   int i;

   // it seems that, when the ui is showing a tooltip, the background is gone
   // for the transparent window created with create_transparent_window() ...
   // I do not understand, in xsnow there is no such thing ...
   // So, we define the background again here:
   if(toon_trans)
      XSetWindowBackground(toon_display,toon_root1,0);

   for (i = 0; i < n; i++, t++) {
      if (t->mapped) 
      {
	 float x      = t->x_map;
	 float y      = t->y_map;
	 int width    = t->width_map;
	 int height   = t->height_map;
	 P("erase    %#lx %d %d %f %f\n",toon_root,width,height,x,y);
	 XClearArea(toon_display, toon_root, x, y, width, height, False);
	 if (!toon_trans && toon_expose) {
	    if (x < minx) {
	       minx = x;
	    }
	    if (x + width > maxx) {
	       maxx = x + width;
	    }
	    if (y < miny) {
	       miny = y;
	    }
	    if (y + height > maxy) {
	       maxy = y + height;
	    }
	 }
      }
   }

   time_for_expose = (!toon_trans && toon_expose && (wallclock() - tprev > 1.0));
   if (time_for_expose && maxx > minx && maxy > miny) 
   {
      P("%d expose event\n",counter++);
      XExposeEvent event;

      event.type        = Expose;
      event.send_event  = True;
      event.display     = toon_display;
      event.window      = toon_root1; /*letop*/
      event.x           = minx;
      event.y           = miny;
      event.width       = maxx-minx + 1;
      event.height      = maxy-miny + 1;
      XSendEvent(toon_display, toon_root1, True, Expose, (XEvent *) &event); /*letop*/
      minx  = 10000;
      maxx  = 0;
      miny  = 10000;
      maxy  = 0;
      tprev = wallclock();
   }

   return 0;
}

/* Send any buffered X calls immediately */
   void
ToonFlush()
{
   XFlush(toon_display);
   return;
}
