#include "cs148.h"
#include "tga.h"

// Our texture id
unsigned int mytex = 0;

// Screen size
int screenWidth = 640;
int screenHeight = 480;

// Mouse viewing rotation points
const double PI = 3.1415926;
const double DEG_TO_RAD = PI / 180.0;
int last_mouse_valid = 0;
int mouse_lastx, mouse_lasty;
double mouse_theta = 90.0;

// Which button is being dragged right now?
int dragging = -1;

// Mouse rotation
const double ROTATE_RATE = 0.75;
const double ZOOM_RATE = 0.05;

// Where is our camera?
float ex=0, ey=0.0, ez=3.0;

void drawFace(void) {

  glEnable (GL_TEXTURE_2D); 
  glBindTexture (GL_TEXTURE_2D, mytex); 

  glBegin (GL_QUADS);
    glTexCoord2f (0.0f,0.0f);
    glVertex3f (-1.0f, -1.0f, 0.0f);

    glTexCoord2f (2.0f, 0.0f);
    glVertex3f (1.0f, -1.0f, 0.0f);

    glTexCoord2f (2.0f, 2.0f);
    glVertex3f (1.0f, 1.0f, 0.0f);

    glTexCoord2f (0.0f, 2.0f);
    glVertex3f (-1.0f, 1.0f, 0.0f);
  glEnd ();

  glDisable (GL_TEXTURE_2D);
}


void glutDisplay(void) {

  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity ();
  
  // Position the camera
  gluLookAt(ex, ey, ez, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);


  drawFace ();

  glutSwapBuffers();
}


void myMouse(int button, int state, int mousex, int mousey) {

  int x = mousex;
  int y = screenHeight - mousey;

  // If this is the first time myMouse was called...
  if (last_mouse_valid == 0) {
    last_mouse_valid = 1;
    mouse_lastx = x;
    mouse_lasty = y;
  }

  // Record which button was pressed
  if ((button == GLUT_LEFT_BUTTON) && (state == GLUT_DOWN)) {
    mouse_lastx = x;
    mouse_lasty = y;
    dragging = GLUT_LEFT_BUTTON;
  }

  else if ((button == GLUT_RIGHT_BUTTON) && (state == GLUT_DOWN)) {
    mouse_lastx = x;
    mouse_lasty = y;
    dragging = GLUT_RIGHT_BUTTON;
  }

  else dragging = -1;

}


void myMovedMouse(int mousex, int mousey) {
  
  int x = mousex;
  int y = screenHeight - mousey;

  if (dragging == GLUT_LEFT_BUTTON) {
  
    // Update rotation 
    mouse_theta -= (double)(x - mouse_lastx) * ROTATE_RATE;
    mouse_lastx = x;
    mouse_lasty = y;
  
    // Recompute look position (polar coords)
    double radius = sqrt(ez*ez+ex*ex);
    ex = radius * cos(DEG_TO_RAD * mouse_theta); 
    ez = radius * sin(DEG_TO_RAD * mouse_theta);   

  }

  else if (dragging == GLUT_RIGHT_BUTTON) {

    // Move in or out along our current look axis
    int dy = y - mouse_lasty;
    mouse_lastx = x;
    mouse_lasty = y;
    ex += ((float)dy) * ex / 100.0;
    ey += ((float)dy) * ey / 100.0;
    ez += ((float)dy) * ez / 100.0;
    
  }

  // Redraw
  glutPostRedisplay();

}


void glutResize(int w, int h) { 
  screenWidth = w;
  screenHeight= h;
    
  glViewport (0, 0, screenWidth, screenHeight);

  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();
  gluPerspective (45.0, screenWidth / screenHeight, 0.5, 30.0);
  glMatrixMode (GL_MODELVIEW);
  

  glutPostRedisplay ();
}



void glInit(void) {

  glEnable (GL_DEPTH_TEST);
  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);

  glGenTextures(1,&mytex);
  int retval = loadTGA("texture.tga", mytex, 1);
  printf("LoadTGA = %d\n", retval);
}


void main (void) {

  glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  glutInitWindowSize (screenWidth,screenHeight);
  glutCreateWindow ("Texture");
  glutDisplayFunc (glutDisplay);
  glutReshapeFunc (glutResize);
  glutMouseFunc(myMouse);
  glutMotionFunc(myMovedMouse);

  glInit ();

  glutMainLoop(); 
}
