
#ifndef _JL_RC_Engine_H_
#define _JL_RC_Engine_H_


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

#include "universal_threads.h"
#include "ui_thread.h"
#include "render_thread.h"
#include "reconstruct_thread.h"
#include "cyclestate.h"
#include "globalstate.h"

extern int _frame_count;

class RC_Engine {

	private:
		UI_Thread			_ui_thread;
		Render_Thread		_render_thread;
		Reconstruct_Thread	_reconstruct_thread;
		CycleState			_cycle_state[3];
		GlobalState			_global_state;
  //		int					_frame_count;

		int					_num_procs;

		UNIV_THREAD			_thread1, _thread2, _thread3;
		int					_done;

	public: 
		RC_Engine();
		RC_Engine(const JLString &filename, int xwinsize, int ywinsize);
		RC_Engine(const RC_Engine &R) { CopyFrom(R); }
		virtual ~RC_Engine();

		RC_Engine& CopyFrom(const RC_Engine&);
		RC_Engine& operator=(const RC_Engine &R) { return CopyFrom(R); }

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

		int Done() { return _done; }

		void StartThreads(int num_procs);
		void OneFrame() {
		  if (_num_procs == 3) _OneFrame_ThreeProcs();
		  else if (_num_procs == 1) _OneFrame_OneProc();
		}

		void EndThreads();

	private:
		void _InitCycleState(CycleState&);

		void _OneFrame_OneProc();
		void _OneFrame_ThreeProcs();

		void _DoThreadProc(Thread &T, int cycle);
		void _DoUIProc(Thread &T, int cycle);

		static UNIV_THREAD_RETURN_TYPE _Render_Proc(void*);
		static UNIV_THREAD_RETURN_TYPE _Reconstruct_Proc(void*);
		static UNIV_THREAD_RETURN_TYPE _UI_Proc(void*);
};

#endif
