//*****************************************************************************************
// Truevision - a 3d modeler for gnome and povray
//
// povfe.h
//
// Vincent LE PRINCE <vincentleprince@users.sourceforge.net>
// Copyright (C) 2000-2005 Vincent LE PRINCE
// This file is part of the TRUEVISION Package

//   This program is free software; you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation; either version 2 of the License, or
//   (at your option) any later version.
//
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program; if not, write to the Free Software
//   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */ 
//*******************************************************************************************
#ifndef TV_POVFE_H
#define TV_POVFE_H
using namespace std;
#include "main.h"
#include "tvwidgets.h"
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include "material.h"
#include <vector>

#define POVFE_DEF PovrayFE *povfe = (PovrayFE*)(app_ref->povfe);


//**********************************************
//  Front end Class
//
// Define pov front end for scene render
//**********************************************
class PovrayFE : public app_object {
	// Callbacks
	#define SENDER ((PovrayFE*)data)
	
	// Option box
	friend void sign_options_box( GtkWidget *wid, gpointer data ) { SENDER->raise_options_box(); }
	friend void sign_povfe_opt_click( GtkWidget *wid, gint button, gpointer data ) { SENDER->opt_box_clicked( button ); }
	friend void sign_povfe_opt_destroy( GtkWidget *wid, GdkEvent *ev, gpointer data ) { SENDER->opt_box_clicked(-1); }
	friend void sign_povfe_presets( GtkWidget *wid, gpointer data ) { SENDER->size_preset_choice(); }

	// Render box
	friend void sign_render_box( GtkWidget *wid, gpointer data ) { SENDER->raise_render_box(); }
	friend void sign_render_run( GtkWidget *wid, gpointer data ) { SENDER->render_run(); }
	friend void sign_render_stop( GtkWidget *wid, gpointer data ) { SENDER->stop_render(); }
	friend void sign_povfe_rend_destroy( GtkWidget *wid, GdkEvent *ev, gpointer data ) { SENDER->close_render_box(); }
	friend void sign_povfe_rend_close( GtkWidget *wid, gpointer data ) { SENDER->close_render_box(); }
	friend void sign_povfe_start_stop_clicked( GtkWidget *wid, gpointer data ) { SENDER->start_stop_clicked(); }
	friend void *read_console_thread( void * data ) { SENDER->read_console_pipe(); return NULL; }		
	
	// Console
	friend void sign_povfe_console( GtkWidget *wid, gpointer data ) { SENDER->raise_console_dlg(); }
	friend void sign_povfe_cons_click( GtkWidget *wid, gint button, gpointer data ) { SENDER->close_console_dlg();  }
	friend void sign_povfe_cons_destroy( GtkWidget *wid, GdkEvent *ev, gpointer data ) { SENDER->close_console_dlg(); }		
	#undef SENDER

	private:
		app_objs *app_ref;
		char *scene_file;
		void flush();
	
		// Widgets
		GtkWidget *start_button, *start_label;
		GtkWidget *progress_bar;
		GtkAction *start_render_action, *stop_render_action;
		void get_progress_bar( GtkWidget *box, bool tt );
	
		// Process control
		pid_t povray_pid;
		char *pipe_console_name;
		int pipe_console_id;
		pthread_t console_thread;
		FILE *fifo_console;
		bool render_status;
		bool render_finished;
		bool modal;
		bool get_pipe_line( int file, char *buffer, int size );

		// Options box
		GtkWidget *options_box, *options_notebk;
		int options_selected_page;
		bool opt_applied;
		void opt_box_clicked( int button );
		void flush_opt_box();
		void close_opt_box();
		void unapply_opt_box();
		void size_preset_choice();

		// Render box
		GtkWidget *render_box;
		GtkWidget *status, *cons_text, *cons_box;
		GtkWidget *time_lab;
		void close_render_box();
		void start_stop_clicked();
		void stop_rendering_scene( bool from_thread );
		void read_console_pipe();

		// Console dialog
		GtkWidget *cons_dlg;
		void raise_console_dlg();
		void close_console_dlg();

		// Rendering options	
		vector<TvWidget*> tv_widgets;	
		TvWidget_path *filename;
		TvWidget_option_combo *fimage_type, *presets;
		TvWidget_int *width, *height;
		TvWidget_int *start_col, *start_row, *end_row, *end_col;
		
		TvWidget_int *quality;
		TvWidget_bool *alpha;
		TvWidget_int *bits_per_color;
		TvWidget_bool *radiosity;
		TvWidget_bool *antialias;
		TvWidget_bool *jitter;
		TvWidget_float *jamount;
		TvWidget_option_combo *anti_met;
		TvWidget_int *anti_depth;
		TvWidget_float *threshold;
		
		TvWidget_bool *display;
		TvWidget_bool *iconified;
		TvWidget_bool *owncmap;
		TvWidget_bool *greyscale;

		TvWidget_int *bounding_thres;
		TvWidget_bool *light_buff;
		TvWidget_bool *vista;
		TvWidget_bool *draw_vista;
 		
 		// Options globales
		TvWidget_float	 *adc_bailout;
		TvWidget_color *ambient_light;
		TvWidget_bool *hf_gray_16;
		TvWidget_color *irid_wavelength;
		TvWidget_int *max_trace_level;
		TvWidget_int *max_intersections;
		TvWidget_int *number_of_waves;
		TvWidget_noise_generator *noisegen;
		
		// Option de radiosité
		TvWidget_float *brightness;
		TvWidget_int *count;
		//TvWidget_float *distance_maximum;
		TvWidget_float *error_bound;
		TvWidget_float *gray_threshold;
		TvWidget_float *low_error_factor;
		TvWidget_float *minimum_reuse;
		TvWidget_int *nearest_count;
		TvWidget_int *recursion_limit;
		TvWidget_float *rad_adc_bailout;
		TvWidget_bool *always_sample;
		TvWidget_float *max_sample;
		TvWidget_bool *rad_media;
		TvWidget_bool *rad_normal;
		TvWidget_float *pretrace_start, *pretrace_end;

		// Photons
		TvWidget_bool_activator *set_spacing, *set_count;
		TvWidget_float *spacing;
		TvWidget_int *photon_count;
		TvWidget_int *gather_min, *gather_max;
		TvWidget_bool *use_media;
		TvWidget_int *max_steps;
		TvWidget_float *media_factor;
		TvWidget_bool_activator *set_gradius, *set_gradius_med;
		TvWidget_float *gradius, *gradius_med;
		TvWidget_float *gradius_mult, *gradius_med_mult;
		TvWidget_float *photon_jitter;
		TvWidget_int *photon_max_trace;
		TvWidget_float *photon_adc;
		TvWidget_float *autostop;
		TvWidget_float *photon_thres_perc;
		TvWidget_int *photon_thres_min;

		// Scene description
		TvWidget_entry *author;
		TvWidget_text *description;

		
		
	public:
		PovrayFE( app_objs *app_ref );
		~PovrayFE();
		void pref_changed();

		// Option box
		void raise_options_box();
	
		// render box
		void raise_render_box();
		bool start_rendering_scene();
		void render_run() { raise_render_box(); start_render(); }
		void start_render();
		void stop_render();
		void set_menu_actions( GtkAction *act1, GtkAction *act2 ) { start_render_action = act1; stop_render_action = act2; }

		// Output to povray
		void output_to_povray( ofstream & file );
		void output_to_povray_ini( ofstream & file, char *fname );
		
		// Save, load, reset
		void save( ofstream & file );
		bool load( ifstream & file, char * tag );
		void reset_defaults();
};

#endif
