#include "kdtreelog.h"
#include "logentry.h"
#include <GL/gl.h>
#include "bounds3d.h"
#include <stdio.h>
#include <iostream.h>
#include "kdtreestepvis.h"

KDTreeStepVis::KDTreeStepVis (const Vis *parent, const LogEntry *someevent) : Vis (parent, someevent) {
  strcpy (_type, "KDTreeStep");

  _start = VisManager::FindVisStart (this, someevent);
}

void KDTreeStepVis::Display(const LogEntry* upto) const {
  KDTreeStep_Start_Entry *s = (KDTreeStep_Start_Entry*)_start->_data;
  // draw start node in hilited wireframe
  glColor3f(1.0,0.6,0.0);  // orange
  s->_start->_bounds.drawWireFrame();

  // draw shared point along ray
  Bounds3d ptbox;
  ptbox.IncludePoint (s->_nextpt);

  Vec4 dim = s->_start->_bounds[1] - s->_start->_bounds[0];
  float mindim = MAXFLOAT;
  if (dim[0] < mindim && dim[0] != 0.) mindim = dim[0];
  if (dim[1] < mindim && dim[1] != 0.) mindim = dim[1];
  if (dim[2] < mindim && dim[2] != 0.) mindim = dim[2];
  mindim *= .1;

  ptbox[1] += Vec4 (mindim, mindim, mindim);
  ptbox[0] -= Vec4 (mindim, mindim, mindim);
  glColor3f (0., 1., 0.);  // green
  ptbox.drawFilled ();

  // draw current node
  switch (upto->_event)
    {
    case KDTreeStep_Ascend:
      KDTreeStep_Ascend_Entry *a = (KDTreeStep_Ascend_Entry*)upto->_data;
      // draw current node filled
      glColor3f(0.0,0.0,1.0);  // blue
      a->_latest->_bounds.drawWireFrame();
      break;
    case KDTreeStep_ToSibling:
      KDTreeStep_ToSibling_Entry *t = (KDTreeStep_ToSibling_Entry*)upto->_data;
      // draw sibling node filled
      glColor3f(1.0,0.0,1.0);  // purple
      t->_sibling->_bounds.drawWireFrame();
      break;
    case KDTreeStep_End:
      KDTreeStep_End_Entry *d = (KDTreeStep_End_Entry*)upto->_data;
      glColor3f(1.0,0.0,0.0);  // red
      // draw final node if haven't left tree
      if (d->_final)
	d->_final->_bounds.drawWireFrame();
      break;
    }

}

char * KDTreeStepVis::StatusLine (const LogEntry *ours) const {
  char *scratch;
  switch (ours->_event)
    {
    case KDTreeStep_Start:
      KDTreeStep_Start_Entry *s = (KDTreeStep_Start_Entry *)(ours->_data);
      scratch = new char [100];
      sprintf (scratch, "Stepping out %c%c face along ray to next k-d cell", (s->_dir) ? '+' : '-', (char)(s->_face + 'X'));
      return scratch;
    case KDTreeStep_Ascend:
      scratch = new char [100];
      sprintf (scratch, "Ascending to node one level up");
      return scratch;
    case KDTreeStep_ToSibling:
      scratch = new char [100];
      sprintf (scratch, "Stepping across to sibling");
      return scratch;
    case KDTreeStep_End:
      KDTreeStep_End_Entry *d = (KDTreeStep_End_Entry *)(ours->_data);
      scratch = new char [100];
      if (d->_final)
	sprintf (scratch, "Descended to node of adjacent k-d cell along ray");
      else
	sprintf (scratch, "Ray has left tree upon exiting the cell");
      return scratch;
    default:
      cerr << "unknown event " << ours->_name << " for kdtreestep.statusline" << endl;
      return newStr(ours->_name);
    }
}
