#ifndef _RTVIS_H
#define _RTVIS_H

#include "visman.h"
#include "rtlog.h"
#include "cyclestate.h"

//DrawFrustumPlanes is in debugwin.C.
void DrawFrustumPlanes (WorkRec *wr, CycleState &CS, float planesize, const Vec4 &basecolor, int back);

class RTNewRootFrustumVis : public Vis {
    const LogEntry *_start;
public:
  RTNewRootFrustumVis (const Vis *parent, const LogEntry *someevent) : Vis (parent, someevent) {strcpy (_type, "RTNewRootFrustumVis"); _start = VisManager::FindVisStart (this, someevent);}

  void Display (const LogEntry *current) const {
    extern CycleState *UI_CS;
    RT_NewRootFrustum_Start_Entry *e = (RT_NewRootFrustum_Start_Entry *)_start->_data;
    DrawFrustumPlanes (e->_root, *UI_CS, 5, Vec4 (.4, .2, .0),0);
  }
  
  char *StatusLine (const LogEntry *ours) const  {
    if (IsStartEvent (ours))
      {
	return newStr ("creating root frustum");
      }
    else if (IsEndEvent (ours))
      {
	return newStr ("finished creating root frustum");
      }
    else
      return NULL;
  }
  
  const LogEntry *GetStartEntry (void) const {return _start;}

  int IsOurs (const LogEntry *en) const {return (IsStartEvent (en) || IsEndEvent (en));}
  int IsStartEvent (const LogEntry *en) const {return (en->_event == RT_NewRootFrustum_Start);}
  int IsEndEvent (const LogEntry *en) const {return (en->_event == RT_NewRootFrustum_End);}

};

class RTSampleFourCornersVis : public Vis {
    const LogEntry *_start;
public:
  RTSampleFourCornersVis (const Vis *parent, const LogEntry *someevent) : Vis (parent, someevent) {strcpy (_type, "RTSampleFourCornersVis"); _start = VisManager::FindVisStart (this, someevent);}
  
  void Display (const LogEntry *current) const {
    extern CycleState *UI_CS;
    glDisable (GL_DEPTH_TEST);
    RT_SampleFourCorners_Start_Entry *e = (RT_SampleFourCorners_Start_Entry *)_start->_data;
    DrawFrustumPlanes (e->_root, *UI_CS, 5, Vec4 (.4, .2, .0),0);
  }
  
  char *StatusLine (const LogEntry *ours) const  {
    if (IsStartEvent (ours))
      {
	return newStr ("sampling the four corners");
      }
    else if (IsEndEvent (ours))
      {
	return newStr ("finished sampling the four corners");
      }
    else
      return NULL;
  }
  
  const LogEntry *GetStartEntry (void) const {return _start;}

  int IsOurs (const LogEntry *en) const {return (IsStartEvent (en) || IsEndEvent (en));}
  int IsStartEvent (const LogEntry *en) const {return (en->_event == RT_SampleFourCorners_Start);}
  int IsEndEvent (const LogEntry *en) const {return (en->_event == RT_SampleFourCorners_End);}

};

class RTRenderingVis : public Vis {
  const LogEntry *_start;
public:
  RTRenderingVis (const Vis *parent, const LogEntry *someevent) : Vis (parent, someevent) {strcpy (_type, "RTRenderingVis"); _start = VisManager::FindVisStart (this, someevent);}
  
  void Display (const LogEntry *current) const {}
  
  char *StatusLine (const LogEntry *ours) const  {
    if (IsStartEvent (ours))
      {
	RT_Rendering_Start_Entry *e = (RT_Rendering_Start_Entry *)ours->_data;
	char *scratch = new char [200];
	sprintf (scratch, "Starting rendering of frame %d, subframe %d  (age %d)", e->_frame_id, e->_sub_frame_id, e->_age);
	return scratch;
      }
    else if (IsEndEvent (ours))
      {
	RT_Rendering_End_Entry *end = (RT_Rendering_End_Entry *)ours->_data;
	char *scratch = new char [200];
	sprintf (scratch, "Finished rendering of frame %d, subframe %d  (age %d)", end->_frame_id, end->_sub_frame_id, end->_age);
	return scratch;
      }
    else
      return NULL;
  }


  const LogEntry *GetStartEntry (void) const {return _start;}
  
  int IsOurs (const LogEntry *en) const {return (IsStartEvent (en) || IsEndEvent (en));}
  int IsStartEvent (const LogEntry *en) const {return (en->_event == RT_Rendering_Start);}
  int IsEndEvent (const LogEntry *en) const {return (en->_event == RT_Rendering_End);}
  
};


class RTNewFrameVis : public Vis {
  const LogEntry *_start;
public:
  RTNewFrameVis (const Vis *parent, const LogEntry *someevent) : Vis (parent, someevent) {strcpy (_type, "RTNewFrameVis"); _start = VisManager::FindVisStart (this, someevent);}

  void Display (const LogEntry *current) const {}
  
  char *StatusLine (const LogEntry *ours) const  {
    if (IsStartEvent (ours))
      {
	RT_NewFrame_Entry *e = (RT_NewFrame_Entry *)ours->_data;
	char *scratch = new char [200];
	sprintf (scratch, "not continuing from previous frame; starting #%d", e->_frame_num);
	return scratch;
      }
    else
      {
	cerr << "newframevis got unknown event to display" << endl;
	return NULL;
      }
  }
  
  const LogEntry *GetStartEntry (void) const {return _start;}

  int IsOurs (const LogEntry *en) const {return (IsStartEvent (en) || IsEndEvent (en));}
  int IsStartEvent (const LogEntry *en) const {return (en->_event == RT_NewFrame);}
  int IsEndEvent (const LogEntry *en) const {return (en->_event == RT_NewFrame);}

};


class RTStatsVis : public Vis {
    const LogEntry *_start;
public:
  RTStatsVis (const Vis *parent, const LogEntry *someevent) : Vis (parent, someevent) {strcpy (_type, "RTStatsVis"); _start = VisManager::FindVisStart (this, someevent);}

  void Display (const LogEntry *current) const {}
  
  char *StatusLine (const LogEntry *ours) const  {
    if (IsOurs (ours))
      {
	return newStr ("storing away stats for this frame");
      }
    else
      {
	cerr << "unknown entry given to rtstatsvis" << endl;
	return NULL;
      }
  }
  
  const LogEntry *GetStartEntry (void) const {return _start;}

  int IsOurs (const LogEntry *en) const {return (en->_event == RT_Stats);}
  int IsStartEvent (const LogEntry *en) const {return (IsOurs (en));}
  int IsEndEvent (const LogEntry *en) const {return (IsOurs (en));}

};

#endif



