#ifndef n_glWindow_GLX_H
#define n_glWindow_GLX_H

/*
 *
 * nucleo/gl/window/glWindow_GLX.H --
 *
 * Copyright (C) Nicolas Roussel
 *
 * See the file LICENSE for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 */

#include <nucleo/utils/FileUtils.H>
#include <nucleo/gl/window/glWindow.H>
#include <nucleo/core/FileKeeper.H>

#include <X11/Xlib.h>
#include <X11/keysym.h>
#include <X11/Xutil.h>
#include <GL/glx.h>

namespace nucleo {

  // ------------------------------------------------------------------

  class glWindow_GLX : public glWindow {

  private:
    void *_getAtom(Window id, Atom to_get, Atom type, unsigned int *size);
    bool _checkNetSupported(Atom toBeSupported);
    bool _ewmhFullScreenMode(bool activate);

  protected:

    Display *_xDisplay ;
    FileKeeper *_fk ;
    Window _xParent, _xWindow ;
    GLXContext _glContext ;
    bool _mapped ; // whether the window is currently mapped on-screen

    void setup(long options, long eventmask) ;
    
    void react(Observable *) ;
    //void prepare(MultiplexRoot *mux) ;

  public:

    unsigned int getScreenWidth(void) ;
    unsigned int getScreenHeight(void) ;

    glWindow_GLX(Display *_xDisplay, Window _xParent, long options, long eventmask) ;
    glWindow_GLX(long options, long eventmask) ;
    ~glWindow_GLX(void) ;

    void map(void) ;
    void unmap(void) ;

    void setTitle(const char *title) ;
    void getGeometry(unsigned int *width, unsigned int *height,
				 int *x, int *y) ;
    void setGeometry(unsigned int width, unsigned int height,
				 int x, int y) ;
    void setGeometry(char *geom) { glWindow::setGeometry(geom) ; }
    void setAspectRatio(int width, int height) ;
    void setMinMaxSize(int minwidth, int minheight, int maxwidth, int maxheight) ;
    void fullScreenMode(bool activate) ;
    void showCursor(bool activate) ;
    void warpCursor(int x, int y) ;
    void keyboardAutoRepeat(bool activate) ;
    void raise(void) ;
    void lower(void) ;

    void makeCurrent(void) ;
    void swapBuffers(void) ;

    bool getNextEvent(event *e) ;

    // -------------------------------------------

    Display *getDisplay(void) {
	 return _xDisplay ;
    }

    Window getWindowID(void) {
	 return _xWindow ;
    }

  } ;

  // ------------------------------------------------------------------

}

#endif
