#include "culooks.h"

#include <vector>

#include <iostream>
#include <math.h>

vector< pair<int,culooks::window*> > culooks::Windows;
pthread_t culooks::glThreadId;
culooks::comarg culooks::comArg;

int culooks::windowid = 0;

using namespace std;

culooks::culooks (const char* name, const int& xcubes, const int& ycubes, const int& l, int *argc, char **argv)
{
  window *Win = new window;
  int winsize[2];

  XInitThreads();

  Win->layout[0] = xcubes;
  Win->layout[1] = ycubes;
  Win->aspect = (double)xcubes/ycubes;
  for (int icube=0; icube<xcubes*ycubes; icube++) {
    cube newCube(l);
    Win->cubes.push_back(newCube);
  }

  if( Win->layout[0] >= Win->layout[1] ) {
    winsize[0] = 640;
    winsize[1] = (640.0/Win->layout[0])*Win->layout[1];
  }
  else {
    winsize[1] = 640;
    winsize[0] = (640.0/Win->layout[1])*Win->layout[0];
  }

  Win->w = winsize[0];
  Win->h = winsize[1];

  Win->name = name;

  Win->initialized = false;

  //Win->linewidth = 1;

  Windows.push_back( pair<int,culooks::window*>(0, Win) );

  if (windowid == 0) {
    comArg.argc = argc;
    comArg.argv = argv;
    pthread_create(&glThreadId, 0, &drawing::glutThread, &comArg);
  }
  mywid = windowid;
  windowid++;
}

void culooks::setLink (const int& cubeid, const int& posdir,
		       const float& red, const float& green, const float& blue, const float& alpha)
{
  Windows[mywid].second->cubes[cubeid].setLink(posdir, red, green, blue, alpha);
}

void culooks::setPlaq (const int& cubeid, const int& posdir,
		       const float& red, const float& green, const float& blue, const float& alpha)
{
  Windows[mywid].second->cubes[cubeid].setPlaq(posdir, red, green, blue, alpha);
}

void culooks::swapBuffers () {
  for (int icube=0; icube<Windows[mywid].second->cubes.size(); icube++) {
    Windows[mywid].second->cubes[icube].swapLinkBuffer();
    Windows[mywid].second->cubes[icube].swapPlaqBuffer();
  }
  Windows[mywid].second->redisplay = true;
}

void culooks::hidePlaqs (const int& cubeid) {
  Windows[mywid].second->cubes[cubeid].hidePlaqs();
}

void culooks::hidePlaqs () {
  for (int icube=0; icube<Windows[mywid].second->cubes.size(); icube++)
    Windows[mywid].second->cubes[icube].hidePlaqs();
}

void culooks::hideLinks (const int& cubeid) {
  Windows[mywid].second->cubes[cubeid].hideLinks();
}

void culooks::hideLinks () {
  for (int icube=0; icube<Windows[mywid].second->cubes.size(); icube++)
    Windows[mywid].second->cubes[icube].hideLinks();
}

void culooks::setBgColor(const float& red, const float& green, const float& blue, const float& alpha)
{
  Windows[mywid].second->bgcolor[0] = red;
  Windows[mywid].second->bgcolor[1] = green;
  Windows[mywid].second->bgcolor[2] = blue;
  Windows[mywid].second->bgcolor[3] = alpha;
}

void culooks::setWireColor(const float& r, const float& g, const float& b, const float& a)
{
  for (int icube=0; icube<Windows[mywid].second->cubes.size(); icube++)
    Windows[mywid].second->cubes[icube].setWireColor(r, g, b, a);
}

void culooks::setFrameWidth(float width)
{
  for (int icube=0; icube<Windows[mywid].second->cubes.size(); icube++)
    Windows[mywid].second->cubes[icube].setFrameWidth(width);
}

void culooks::setLinkWidth(float width)
{
  for (int icube=0; icube<Windows[mywid].second->cubes.size(); icube++)
    Windows[mywid].second->cubes[icube].setLinkWidth(width);
}
