/*
 * Simple X11 sprite handling
 * Header file
 *
 * $Id: xsprite.h,v 1.3 2003/02/09 03:51:05 hsteoh Exp hsteoh $
 */

#ifndef XSPRITE_H
#define XSPRITE_H

#include "xutil.h"


// Sprite engine for giving context to sprites. There should be one sprite
// engine per application window, theoretically.
// The reason we have this is so that we can minimize X server resource usage
// by putting common stuff, such as GC's, here, instead of one copy per
// sprite.
class xsprite_engine {
  xconnection *conn;			// [R]
  Drawable d;				// Drawable to render sprites on
  int closeness;			// XPM color closeness range (TEMP)

  GC copygc;
  GC maskgc;
  GC drawgc;
public:
  xsprite_engine(xconnection *conn, Drawable d, int color_closeness);
  ~xsprite_engine();

  // Convenience functions
  Display *display() { return conn->display(); }
  int screen() { return conn->screen(); }
  int scrn_depth() { return conn->scrn_depth(); }
  unsigned long black() { return conn->black(); }
  unsigned long white() { return conn->white(); }

  Drawable get_drawable() { return d; }
  int get_closeness() { return closeness; }
  GC get_copygc() { return copygc; }
  GC get_maskgc() { return maskgc; }
  GC get_drawgc() { return drawgc; }

  // Possible future extension: a file loader that can understand all kinds
  // of graphic formats. Maybe a wrapper to Imlib or similar.
  //XImage *load_imagefile(char *filename);
};

// For now, we provide a simple interface to create sprites from XPM files
class xflatsprite {
  xsprite_engine *eng;			// [R] sprite engine context
  Pixmap image;
  Pixmap mask;
  int wd, ht;				// width & height
  int ox, oy;				// image origin (==XPM hotspot)
public:
  xflatsprite(xsprite_engine *engine, char *xpmfile);
  ~xflatsprite();

  void draw(Drawable d, int x, int y);
  int width() { return wd; }
  int height() { return ht; }

  // Location of hotspot
  int org_x() { return ox; }
  int org_y() { return oy; }
};

// Buffer for saving backgrounds, for animating sprites.
class xsavebuf {
  xsprite_engine *eng;			// [R]
  int wmax, hmax;			// maximum dimensions

  Pixmap bckgnd;
  Drawable bckgnd_d;			// Drawable to restore to
  int last_x, last_y;
  int last_wd, last_ht;
  int saved;				// does bckgnd contain valid data
public:
  xsavebuf(xsprite_engine *engine, Drawable d, int max_width,
             int max_height);
  ~xsavebuf();

  void save(Drawable d, int x, int y, int wd, int ht);
  void restore();

  int max_width() { return wmax; }
  int max_height() { return hmax; }
};

// FIXME: need to generalize this
class xsprite {
public:
  xsprite(xsprite_engine *engine, xflatsprite *spr, char *xpmfile);
  ~xsprite();

  void sdraw(Drawable d, int x, int y);
  void erase();
};

#endif // XSPRITE_H
