
#ifndef _JL_GlobalState_H_
#define _JL_GlobalState_H_

#include <stdlib.h>
#include <iostream.h>

#include "protectedobject.h"
#include "scene.h"
#include "user.h"
#include "planecache.h"
#include "glwin.h"


class ofstream;
class ifstream;

class GlobalState : public ProtectedObject {

	friend class RC_Engine;

	public:
		Scene		_scene;
		int		_done;
		int		_x_winsize, _y_winsize;
		User		_user;

		int             _interp_usec; //how long it takes to interpolate, worst case
	        int             _draw_usec; //how long it takes to do the drawpixels

		Vec4            _initR, _initD, _initU; //initial camera pos, so we can reset to it at will

		int		_max_subd_level;
		float		_foveal_sampling;
		int		_num_render_workers;
                int             _visibility_cull;
                int             _frustum_cull;
                GLWin		*_glwin;

		int _ss_level; //supersampling level

		int _shadow_depth;
		int _refraction_depth;
		int _reflection_depth;

		real _frame_rate; //the latest

	        int _cf_cache_area_cutoff; //when to not cache a cell
                int _min_frusta_size; //how small to subdivide 'em.

		real _rotational_velocity;
		real _translational_velocity;

		int  _peg_frame_rate; //if 0, we peg the # pixels/frame
		real _desired_frame_rate;
		int _desired_num_pixels_per_frame;

		int _do_ambient, _do_diffuse, _do_specular;
		int _texturing;

#define DISABLE_INTERPOLATE 1
#define DISABLE_DRAW  (1 << 1)
#define DISABLE_FRAME_CONTINUE  (1 << 2)
#define DISABLE_LOAD_BALANCING  (1 << 3)
#define DISABLE_FRAME_BLEND (1 << 4)
#define FORCE_NEW_FRAME (1 << 5)
#define DISABLE_FRAME_ADD_FEATURE (1 << 6)
#define DISABLE_ANIMATION (1 << 7)
#define DISABLE_FC (1 << 8)
#define DISABLE_STRADDLERS (1 << 9)
#define DISABLE_FLOOD_YES (1 << 10)
#define DISABLE_VIEWVEC_T (1 << 11)
#define DISABLE_LP (1 << 12)
#define DISABLE_HYBRID_FC (1 << 13)
#define DISABLE_LP_SUBDIV (1 << 14)
#define DISABLE_CONTINUOUS_SHADE (1 << 15)
#define ENABLE_PLANE_CACHE_IN (1 << 16)
#define ENABLE_PLANE_CACHE_OUT (1 << 17)
#define DISABLE_PLANE_CACHE (1 << 18)
#define DISABLE_KDTREE (1 << 19)
#define DISABLE_CLIP_BBOX (1 << 20)
#define DISABLE_DOUBLE_CHECK (1 << 21)
#define DISABLE_KDTRAVERSAL_CACHE (1 << 22)
#define DISABLE_CELL_FRUSTUM_CACHE (1 << 23)
#define DISABLE_UNCACHED_BBOX_TESTS (1 << 24)
#define DISABLE_RAY_CF_CACHE (1 << 25)
#define ENABLE_FCULLED_RAY_BBOX_TESTS (1 << 26)
#define ENABLE_LOCK (1 << 27)
#define DISABLE_SMALL_CELL_WORK (1 << 28)
#define ENABLE_LP_ROOT_FRUSTUM (1 << 29)
#define ENABLE_BETTER_RAY_LISTS (1 << 30)
#define ENABLE_OBJ_SCRN_SPACE_BBOX_CALC (1 << 31)
  int _disabled_flags;
  
#define ENABLE_1_AXIS_CHECK 1
#define ENABLE_THROW_BAD_AREA_RATIO_TO_GL (1 << 1)
#define ENABLE_THROW_BAD_HIT_RATIO_TO_GL (1 << 2)
#define ENABLE_3_AXIS_CHECK (1 << 3)
#define ENABLE_COLLECT_INTERSECT (1 << 4)
  int _disabled_flags2;
  
  int res0, res1, res2, res3; //reserved!

                int _split_screen;

#define STYLE_THREAD_OWNED 1
#define STYLE_THREAD_DID (1 << 1)
#define STYLE_CELLS_WALKED (1 << 2)
#define STYLE_DEPTH_COMPLEXITY (1 << 3)
#define STYLE_PIXELS_DONE (1 << 4)
#define STYLE_KDTREE_USED (1 << 5)
#define STYLE_DEPTH_COMPLEXITY_W_BBOX (1 << 6)
#define STYLE_NO_KDTREE (1 << 7)
#define STYLE_CELL_HIT (1 << 8)
#define STYLE_SMALL_CELL_HIT (1 << 9)
#define STYLE_NOT_SMALL_CELL_HIT (1 << 10)
#define STYLE_BBOXES_MISSED (1 << 11)
#define STYLE_OBJS_MISSED (1 << 12)
#define STYLE_OBJS_HIT (1 << 13)
#define STYLE_OBJCELL (1 << 14)
  
		int _style_flags;
		int _draw_depth_complexity;
		int _draw_rays_shot;

//when # rays cast * _hw_interp_cutoff_ratio > # pixels in scene,
//we switch to software interpolation
		int _hw_interp_cutoff_ratio;

//debugging window stuff
#define DRAW_ALL 1 //vs just draw what we traverse
#define DRAW_RAY_OF_CURRENT_PIXEL (1 << 1)
#define DRAW_CELLS (1 << 2)
#define DRAW_OBJECTS (1 << 3)
#define DRAW_QUICK_REJECT_OBJECTS (1 << 4)
#define DRAW_LIGHTS (1 << 5)
#define DRAW_SHADOW (1 << 6)
#define DRAW_CELL_CONTENTS (1 << 7)
#define DRAW_CELL_BBOX (1 << 8)
#define DRAW_ALL_RAYS (1 << 9)
#define DRAW_BBOXES_MISSED (1 << 10)
#define DRAW_FRUSTA_GRID (1 << 11)
#define DRAW_FILM_PLANE (1 << 12)
#define DRAW_IMAGE_IN_FILM_PLANE (1 << 13)
#define DRAW_CELL_SHADED (1 << 14)
#define DRAW_USE_MOUSE_POS (1 << 15)
#define DRAW_FRUSTA_FROM_CURRENT_PIXEL (1 << 16)
#define DRAW_OBJ_OVER_CURSOR (1 << 17)
#define DRAW_ONLY_LARGE_CELLS (1 << 18)
#define DRAW_OBJS_TOUCHED (1 << 19)
#define DRAW_OBJS_MISSED (1 << 20)
#define DRAW_CELLS_ENTERED (1 << 21)
#define DRAW_CUR_PIXEL (1 << 22)
#define DRAW_WIREFRAME_OBJS (1 << 23)
#define DRAW_PARENT_STOPS (1 << 24)
#define DRAW_KID_CELLS (1 << 25)
#define DRAW_CELL_SCREEN_SPACE (1 << 26)
#define DRAW_RAYS_W_FRUSTUM_COLOR (1 << 27)
#define DRAW_RAYS_FROM_EYE_PT (1 << 28)
#define DRAW_NEXT_CELLS (1 << 29)
#define DRAW_TIGHTEST_CELL_BBOX (1 << 30)
#define DRAW_CLOSEST_CELL_BBOX (1 << 31)

                int _kddraw_flags;

#define DRAW_FRUSTA_CELLS (1)    
#define DRAW_FRUSTA_UP_TO (1 << 1)
#define DRAW_FRUSTUM_EXIT_PTS (1 << 2)
#define DRAW_FRUSTA_PLANES (1 << 3)
#define DRAW_FRUSTA_BACK_PLANES (1 << 4)
#define DRAW_FRUSTUM_ANIMATE (1 << 5)
#define DRAW_FRUSTUM_CELL (1 << 6)
#define DRAW_FRUSTA_OBJECTS (1 << 7)
#define DRAW_FRUSTA_SCRN_SPACE (1 << 8)
#define DRAW_FRUSTA_INFO (1 << 9)
#define DRAW_CELL_FRUSTA_CACHE (1 << 10)
#define DRAW_CF_CACHE_OBJS (1 << 11)
#define DRAW_CF_CACHE_HITS (1 << 12)
#define DRAW_CACHE_HIT_PERC (1 << 13)
#define DRAW_SCREEN_SPACE_FRUSTA_LEAVES (1 << 14)
#define DRAW_CACHE_NOT_TOTAL_USE (1 << 15)
#define DRAW_CELL_OVER_CURSOR (1 << 16)
#define DRAW_CACHE_EFFICIENCY_PERC (1 << 17)
#define DRAW_FIVE_FRUSTUM_RAYS (1 << 18)
#define DRAW_KID_RAYS (1 << 19)
#define DRAW_FRUSTA_OBJS_MISSED (1 << 20)
#define DRAW_FRUSTA_BBOXES_MISSED (1 << 21)
#define DRAW_OBJS_VIS (1 << 22)
#define DRAW_OBJS_NOT_VIS (1 << 23)
#define DRAW_INTERSECTED_OBJ_SS_BBOX (1 << 24)
#define DRAW_VIS_INTERSECTED_OBJ (1 << 25)  
#define DRAW_NOT_VIS_INTERSECTED_OBJ (1 << 26)  
#define DRAW_LOG_QUERY (1 << 27)
  int _frusta_flags;

		int _just_one_ray;
		int _show_middle_ray_info;

		int _job_chunk_size;
		real _max_thread_ratio;

		int _next_frame_hit;

		ofstream *outlogfile;
		ifstream *inlogfile;
	public: 
		GlobalState();
		GlobalState(const GlobalState &G) { CopyFrom(G); }
		virtual ~GlobalState();

		GlobalState& CopyFrom(const GlobalState&);
		GlobalState& operator=(const GlobalState &G) { return CopyFrom(G); }

//		friend ostream& operator<<(ostream&, const GlobalState&);
//		friend istream& operator>>(istream&, GlobalState&);
};

#endif
