#include "examine_nav.h"
#include "jlmouse.h"
#include "globalstate.h"
#include "render_worker.h"
#include "prim.h"
#include "bounds3d.h"
#include "globals.h"
#include "ui_thread.h"

Examine_Nav::Examine_Nav(JLTrackball::TrackballType type) : _tb (type), _firstclick (1) {
  _tb.Reset();
}

Examine_Nav::~Examine_Nav() {
}

Examine_Nav& Examine_Nav::CopyFrom(const Examine_Nav &) {

	cerr << "Error: Examine_Nav::CopyFrom() called" << endl;
	exit(-1);

	return *this;
}

/*
ostream& operator<<(ostream &co, const Examine_Nav &E) {

	return co;
}

istream& operator>>(istream &ci, Examine_Nav &E) {

	return ci;
}
*/

void Examine_Nav::Navigate(CycleState&CS, JLMouse&M) {

  float x, y;

  M.GetFloatXYGivenViewport(x, y, truly_GS->_x_winsize, truly_GS->_y_winsize);
        
  if (_firstclick)
    {
      _tb.Click (x, y);
      _firstclick = 0;
      cerr << "click " << x << "," << y << endl;
    }
  else
    {
      _tb.Drag (x, y);
      cerr << "drag " << x << "," << y << endl;

    }

  Vec4 D = truly_GS->_user.GetCamera().D(); //camera location
  Vec4 R = truly_GS->_user.GetCamera().R(); //view vector
  Vec4 U = truly_GS->_user.GetCamera().U(); //up vector

  RayCache *rayinfo = GET_RAY_INFO_PTR ((truly_GS->_x_winsize/2),(truly_GS->_y_winsize/2));

  float t = 1.0;
#if 0
  Vec4 NewFocus = R + (D * t); //XXX stupid!
  if (rayinfo->hitsomething == YES)
    {
      //center around what we were looking at
#if 0
      Bounds3d bbox = rayinfo->objhit.obj->bbox();
      NewFocus = (bbox[0] + bbox[1]) * .5;
#else
      NewFocus = R + (D * rayinfo->objhit.t);
#endif
    }
  else
    return;
#else
  Vec4 NewFocus = UI_Thread::_CB_Object->_center_of_interest;
#endif

  cerr << "R:" << R << ", D:" << D << endl;
  cerr << "t was " << t << ", new focus is " << NewFocus << endl;
  JLmatrix invMat;
  _tb.BuildIncrMatrix (invMat); //get the latest transformation

  JLmatrix Mat;
  invMat.Inverse (Mat); //justin says I need the inverse?
    
  R -= NewFocus;
  float rlen = R.Length();
  R.FastMakeUnit3();
  R *= Mat; //transform the eye point
  R *= rlen;
  R += NewFocus;

  D = NewFocus - R; //new viewvec!
  if (D.Length() == 0.) 
    {
      cerr << "newfocus == R. great!" << endl;
      return;
    }

  D.MakeUnit();

  U.MakeUnit();
  truly_GS->_user.GetCamera().Set(R, D);
}

void Examine_Nav::Stop (void)
{
  _firstclick = 1;
  _tb.Reset();
}
