#include <iterator>
#include <iostream>
#include <cfloat>
#include <cstdio>
#include "Picking.h"
#include <climits>

using namespace std;

void projection();                  // projection transformation in main.cpp
void render_main_window();          // assume you are rendering multiple viewports. Otherwise, simply use display().

int Picking :: processHits (int hits)
{
  unsigned int i, j;
  GLuint names, *ptr = (GLuint *) selectBuf;
  double minz = DBL_MAX;

  cout << "hits = " << hits << endl;
    
  for (unsigned i = 0; i < hits; i++) 
  {  
    GLuint names = *ptr;                             // # of names on name stack when this hit occurs.  should be 1.
    double cur_minz = (double) *++ptr/0x7fffffff;    // minz (followed by maxz, and name stack content) 
    ptr += names + 1;                                // point to last name in cur hit record.
       
    if( cur_minz < minz) 
    {
      minz = cur_minz;
      selected_id = *ptr;
    }
    ++ptr;                                           // starting of next hit record.
  }
  return selected_id;
}

int Picking :: operator() (int x, int y, double width, double height)
{
  UnSelect();

  glSelectBuffer (hit_buff_sz, selectBuf);
  glRenderMode (GL_SELECT);

  glInitNames();   
  glPushName(UINT_MAX);
 
  glMatrixMode (GL_PROJECTION);
  glPushMatrix();
  {
    glLoadIdentity ();
    {
      GLint viewport[4];
      glGetIntegerv(GL_VIEWPORT, viewport);
      gluPickMatrix (x, y, width, height, viewport);
    }
    projection();
    
    render_main_window(); 
  }
  glMatrixMode (GL_PROJECTION);
  glPopMatrix();
    
  return processHits( glRenderMode (GL_RENDER) );
}
