//*****************************************************************************************
// Truevision - a 3d modeler for gnome and povray
//
// povfe.h
//
// Vincent LE PRINCE <vincentleprince@users.sourceforge.net>
// Copyright (C) 2000-2001 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);


//**********************************************
// Classe Front end
//**********************************************
class PovrayFE : public app_object {
	// Callbacks
	#define SENDER ((PovrayFE*)data)
	friend void *reading_image_thread( void * data ) { SENDER->read_output(); return NULL; }
	friend void *reading_console_thread( void * data ) { SENDER->read_console(); return NULL; }
	
	friend void sign_start_clicked( GtkWidget *wid, gpointer data ) { SENDER->start_clicked(); }

	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_render_box( GtkWidget *wid, gpointer data ) { SENDER->raise_render_box(); }
	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 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(); }		
	
	friend void *reading_console_thread2( void * data ) { SENDER->read_console2(); return NULL; }
		
	friend void sign_povfe_presets( GtkWidget *wid, gpointer data ) { SENDER->size_preset_choice(); }
	#undef SENDER

	private:
		app_objs *app_ref;
		GtkWidget *widget, *preview_widget;
		GtkWidget *start_button, *start_label;
		GtkWidget *progress_bar;
		GtkWidget *statusbar;
		pid_t povray_pid;
		char *pipe_console_name, *pipe_output_name;
		int pipe_console_id, pipe_output_id;

		Material *current_material;
		pthread_t output_thread;
		pthread_t console_thread;
		bool render_status;
		bool render_finished;
		bool modal;

		// image
		char *scene_file;
		int image_size;
		char *image;

		// 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;
		FILE *fifo_console;
		void close_render_box();
		void start_stop_clicked();
		void close_render2( bool from_thread );
		void read_console2();

		// 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_bool *mosaic;

		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;
		
		// Option d 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;

		// Predefined scenes
		TvWidget_option_combo *predef_scene;
		TvWidget_bool *render_wall;
		TvWidget_bool *render_floor;
		TvWidget_option_combo *predef_sizes;
		TvWidget_bool *render_sky;
		
		// Scene description
		TvWidget_entry *author;
		TvWidget_text *description;

		char *get_predef_scene_file( Material *mat );
		bool launch_povray_for_preview( char *source_file );
		void delete_povray_cmd();
		
		bool get_pipe_line( int file, char *buffer, int size );
		void read_output();
		void read_console();
		void close_render( bool close_console );
		void start_clicked();
		void flush();
		
	public:
		PovrayFE( app_objs *app_ref );
		~PovrayFE();
		void pref_changed();

		// Options
		void set_size( int w, int h ) { width->set(w); height->set(h); }

		void show_image_as_widget( GtkWidget *box, bool tt );
		void get_predef_scene_widget( GtkWidget *box, bool tt );
		void get_antialias_widget( GtkWidget *box, bool tt ) { antialias->get_widget( box, tt ); }
		void get_start_button( GtkWidget *box, bool tt );
		void get_progress_bar( GtkWidget *box, bool tt );
		void get_predef_sizes( GtkWidget *box, bool tt );
		void cancel_preview() ;

		void set_current_material( Material *mat ) { current_material = mat; }

		bool start_rendering_predef( Material *mat , bool save, bool modal );
		bool start_rendering_predef_current( bool save, bool modal ) { return start_rendering_predef( current_material, save, modal ); }
		bool start_rendering_scene();
		void save_as_preview( ofstream & file );
		void save_preview_settings();


		void raise_options_box();
		void raise_render_box();
		
		void save( ofstream & file );
		void output_to_povray( ofstream & file );
		bool load( ifstream & file, char * tag );
		
		void reset_defaults();
};

#endif

