#ifndef CULOOKS_H
#define CULOOKS_H

#include <pthread.h>
#include <vector>
#include <GL/glut.h>
#include <GL/glx.h>
#include <GL/gl.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <string>

using namespace std;

class culooks
{
 public:
  
  culooks (const char* name, const int& xcubes, const int& ycubes, const int& l, int *argc, char **argv);
  void setLink (const int& cubeid, const int& posdir,
		const float& red, const float& green, const float& blue, const float& alpha);
  void setPlaq (const int& cubeid, const int& posdir,
		const float& red, const float& green, const float& blue, const float& alpha);
  void swapBuffers();
  void hidePlaqs(const int& cubeid);
  void hidePlaqs();
  void hideLinks(const int& cubeid);
  void hideLinks();
  void setBgColor(const float& red, const float& green, const float& blue, const float& alpha);
  void setWireColor(const float& r, const float& g, const float& b, const float& a);
  void setFrameWidth(float width);
  void setLinkWidth(float width);

 private:

  struct comarg {
    int *argc;
    char **argv;
  };

  static comarg comArg;
  
  class cube {
  public:
    cube (int l);
    void draw();
    int id;
    float az, alt;
    float azRotSpeed;
    float zoom;
    void setLink (const int& posdir, 
		  const float& red, const float& green, const float& blue, const float& alpha);
    void setPlaq (const int& posdir, 
		  const float& red, const float& green, const float& blue, const float& alpha);
    void swapLinkBuffer();
    void swapPlaqBuffer();
    void hidePlaqs();
    void hideLinks();
    void setWireColor(const float& r, const float& g, const float& b, const float& a);
    void setFrameWidth(float width);
    void setLinkWidth(float width);
  private:
    float wireColor[4];
    void drawAll();
    void drawBox();
    static void drawFrame();
    float *plaq;
    float *link;
    float *plaqbuf[2];
    float *linkbuf[2];
    int l;
    int plaqbuf_active;
    int linkbuf_active;
    static int allid;
    bool hideplaquettes;
    bool hidelinks;
    float framewidth;
    float linkwidth;
  };
  
  struct window {
    int layout[2];
    double aspect;
    vector<cube> cubes;
    int w, h;
    int gwinid;
    bool initialized;
    string name;
    float bgcolor[4];
    bool redisplay;
  };

  class drawing 
  {
  private:
    static int rotcube[3];
    static culooks::window* getWin();
    static int getCubeFromPos(int x, int y);
    static void motionFunc(int x, int y);
    static void mouseFunc(int button, int state, int x, int y);
    static void reshapeFunc(int w, int h);
    static void displayFunc();
    static void initWindow(int winid);
    static void idleFunc();
  public:
    static void* glutThread(void *leer);
  };
  
  static vector< pair<int,window*> > Windows;
  static pthread_t glThreadId;
  static int windowid;
  int mywid;
};

#endif
