//#include <windows.h>

#include "imvideocapture.h"
#include <GL/glut.h>
#include <stdio.h>
#include <time.h>

imVideoCapture* myVideoCap;
GLuint  gTexCapedImage;
int gHeight = 0, gWidth = 0;
unsigned char* gData = NULL;

void myIdle()
{
  if (!imVideoCaptureLive(myVideoCap, IMVC_QUERY))
    return;

  imVideoCaptureGetImageSize(myVideoCap, &gWidth, &gHeight);

  if(!gData)
    gData = new unsigned char[gHeight*gWidth*3];  // This is valid only because capture images are DWORD aligned already

  imVideoCaptureFrame(myVideoCap, gData, 1000);

  glBindTexture(GL_TEXTURE_2D, gTexCapedImage);
  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, gWidth, gHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, gData);

  glutPostRedisplay();
}

void display() 
{
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(40, 1.0, 0.1, 100.0);
  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity();
  gluLookAt(0, 0, 3,  0, 0, 0, 0, 1, 0);
  double hw=gWidth*1.0/gHeight/2;
  glRotated(clock()/100, 0, 1, 0);
  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, gTexCapedImage);
  glBegin(GL_QUADS);
  glColor3d(1.0, 1.0, 0.0);
  glTexCoord2d(0.0, 0.0); glVertex2d(-hw, -0.5);
  glTexCoord2d(0.0, gHeight/512.0); glVertex2d(-hw, 0.5);
  glTexCoord2d(gWidth/1024.0, gHeight/512.0); glVertex2d(hw, 0.5);
  glTexCoord2d(gWidth/1024.0, 0.0); glVertex2d(hw, -0.5);
  glEnd();
  glutSwapBuffers();
}

void parsekey(unsigned char key, int x, int y)
{
 switch (key) {
  case 27: 
   imVideoCaptureDisconnect(myVideoCap);
   imVideoCaptureDestroy(myVideoCap);
   delete gData;
//   CoUninitialize();
   exit(1);
  case ' ':
   if (imVideoCaptureLive(myVideoCap, IMVC_QUERY))
     imVideoCaptureLive(myVideoCap, 0);
   else
     imVideoCaptureLive(myVideoCap, 1);
   break;
  case 's':
   imVideoCaptureShowSourceDialog(myVideoCap, NULL);
   break;
  default:
   glutPostRedisplay();
   return;
 }
}

void myGlInit()
{
 glShadeModel (GL_SMOOTH);
 glFrontFace(GL_CCW);
 glEnable(GL_DEPTH_TEST);
 glGenTextures(1, &gTexCapedImage);
 glBindTexture(GL_TEXTURE_2D, gTexCapedImage);
 glTexImage2D(GL_TEXTURE_2D, 0, 3, 1024, 512, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, 0);
 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
}

int main(int argc, char* argv[])
{
//  CoInitialize(NULL);

  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE | GLUT_MULTISAMPLE | GLUT_STENCIL);
  glutInitWindowPosition(0, 0);
  glutInitWindowSize(512, 512);
  glutCreateWindow("VideoCap");
  glClearColor(0, 0.5, 0, 1.0);
  glutDisplayFunc(display);
  glutKeyboardFunc(parsekey);
  glutIdleFunc(myIdle);

  myGlInit();

  myVideoCap = imVideoCaptureCreate();
  if (!myVideoCap)
  {
    printf("No Capture Device!\n");
    return 0;
  }

  imVideoCaptureConnect(myVideoCap, 0);
  imVideoCaptureLive(myVideoCap, 1);

  imVideoCaptureShowFormatDialog(myVideoCap, NULL);

  glutMainLoop();

  return 1;
}
