// Copyright (c) 1999 Philip A. Hardin (pahardin@cs.utexas.edu)
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License v2 or later.


#ifndef _GFXTARGET_H
#define _GFXTARGET_H
#include <stdlib.h>
#include <string.h>
#include <iostream.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>

#ifndef NO_OPENGL
#include <GL/gl.h>
#include <GL/glx.h>
#endif

#include "general.h"
#include "pt2d.h"


struct gfxTarget {
  Display       *disp;   // X Display
  Drawable      win;       // window on the display
  Window        rootWin;        // root window of the display
  int           screenNo;       // default screen of the display
  GC            gc;         // graphics context for window 'win'
  Pixmap        pm;         // Pixmap for double-buffering window 'win'
  GC            pmgc;     // graphics context for the pixmap
  
  protected:
  bool   useGL;
  Drawable      savedWin;       // X window; used for double-buffering
  GC       savedGc;        // X GC;     used for double-buffering
  
  public:
  gfxTarget(bool ugl=0) : useGL(ugl) {}
  
  // In:  dispName = name of X display to open
  // Out: disp, screenNo, & rootWin member fields set if display was opened
  //      successfully
  // Returns true if display was opened successfully, false otherwise
  bool OpenDisplay(char *dispName);
  
  void ConnectToWM(char *argv[], int argc, char *progName,
                  short x, short y, short width, short height);
  
  ulong Black() const {return BlackPixel(disp,screenNo);}
  ulong White() const {return WhitePixel(disp,screenNo);}
  bool  UseGL() const {return useGL;}
  
  void  SetForeground(ulong color) const {
    XSetForeground(disp,gc,color);
  #ifndef NO_OPENGL
    if (useGL) glIndexi(color);
  #endif
  }
  void  SetBackground(ulong color) const {
    XSetBackground(disp,gc,color);
  }
  void  DrawLine(const pt2d& p1,const pt2d& p2) const {
    XDrawLine(disp,win,gc,(int)p1.x,(int)p1.y,(int)p2.x,(int)p2.y);
  }
  void  DrawString(const pt2d& p,const char* s) const {
    XDrawImageString(disp,win,gc,(int)p.x,(int)p.y,s,strlen(s));
  }
  void  DrawRectangle(const pt2d& p,const pt2d& sz) const {
    XDrawRectangle(disp,win,gc,(int)p.x,(int)p.y,(int)sz.x,(int)sz.y);
  }
  void  FillRectangle(const pt2d& p,const pt2d& sz) const {
    XFillRectangle(disp,win,gc,(int)p.x,(int)p.y,(int)sz.x,(int)sz.y);
  }
  void  ResizeWindow(const pt2d& sz) {
    XResizeWindow(disp,win,(int)sz.x,(int)sz.y);
    HandleResize();
  }
    
  // Handle the effects of the window being resized
  void HandleResize();
  
  void DoubleBufferBegin();
  
  void DoubleBufferEnd();
};
#endif

