#include <GL/gl.h>
#include <GL/glut.h>
#include <sys/timeb.h>
#include <stdio.h>
#include "twist.h"
#include "cube.h"

float refresh = 1000.0 / 60;
float mtor = 90.0 / 500; // 90 degrees in half second

int num_twists = 0;
int squeue = 0; // start queue
const int max_twists = 20;
int twisting = 0;

char twist_queue[max_twists];

void twist_anim(int);

void queue_twist(int face, int ccw) {
  char facec;

  if (num_twists - squeue >= max_twists) return;

  facec = (char)face;
  if (ccw) facec += 6;

  twist_queue[num_twists++ % max_twists] = facec;
  if (!twisting) twist_anim(0);
}

int dequeue_twist(int *face, int *ccw) {
  char facec;

  if (squeue == num_twists) return 0;

  facec = twist_queue[squeue];
  *face = facec % 6;
  *ccw = facec > 5;

  squeue++;
  if (squeue >= max_twists) {
    squeue -= max_twists;
    num_twists -= max_twists;
  }

  return 1; // success
}

void twist_anim(int) {
  static timeb starttime;
  static int face, ccw;

  timeb t;
  ftime(&t);

  if (!twisting && dequeue_twist(&face, &ccw)) {
    twisting = 1;
    starttime = t;
    cube.twistface = face;
  }

  if (!twisting) return;

  int diff = (t.time - starttime.time) * 1000;
  diff += t.millitm - starttime.millitm;

  float r = mtor * diff;

  if (r >= 90) {
    cube.twist(ccw, face);
    cube.twist_deg = 0;
    twisting = 0;
  } else {
    cube.twist_deg = r * (ccw * 2 - 1);
  }
  glutTimerFunc(refresh, &twist_anim, 0);
  glutPostRedisplay();
}
