//*****************************************************************************************
// Truevision - a 3d modeler for gnome and povray
//
// matlist.h
//
// Header for matlist.cc & mateditor.cc
// interface for material selection, edition, load and  save
//
// 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_MATLIST_H
#define TV_MATLIST_H
using namespace std;
#include <vector>
#include <iostream>
#include "main.h"
#include "matpov.h"
#include "objparam.h"
#include "povpreview.h"

// Macro for other app_objs outside calls
#define MATLIST_DEF MatList *matlist = (MatList*)(app_ref->matlist);

// Buttons numbering
#define MAX_TEX_BUTTONS 6
#define MAX_EDIT_BUTTONS 6



//**************************************
// Classe MatList
//
// Material List, selection widget and material editor
//**************************************
class MatList : app_object {
	
	// Callbacks definitions
	#define SENDER ((MatList*)data)
		// Selection widget
		friend void sign_matlist_row_select( GtkTreeSelection *select, gpointer data ) { SENDER->row_selected(select); }
		friend void sign_matlist_row_activated( GtkTreeView *View, GtkTreePath *path, GtkTreeViewColumn *col, gpointer data ) { SENDER->button_clicked( SENDER->select_buttons[2] ); }
		friend void sign_matlist_button_clicked( GtkWidget *wid, gpointer data ) { SENDER->button_clicked( wid ); }

		// Material editor
		friend void sign_ed_dlg_click( GtkDialog *wid, gint button, gpointer data ) { SENDER->clicked_ed_dlg(button); }
		friend void sign_ed_dlg_destroy( GtkWidget *wid, GdkEvent *ev, gpointer data ) { SENDER->clicked_ed_dlg(-1); }		
		friend void sign_matlist_editor_tree_select( GtkTreeSelection *selection, gpointer data ) { SENDER->editor_tree_select( selection ); }		
		friend void sign_ed_dlg_select( GtkWidget *wid, gpointer data ) { SENDER->ed_dlg_select(); }
		friend void sign_edit_button_clicked( GtkWidget *wid, gpointer data ) { SENDER->edit_button_clicked( wid ); }
		friend void sign_mat_open_editor( GtkWidget *wid, gpointer data ) { SENDER->raise_texeditor(); }	

		// Material save dialog
		friend void sign_mat_save( GtkWidget *wid, gpointer data ) { SENDER->mat_save(); }	
		friend void sign_save_dlg_click( GtkWidget *wid, gint button, gpointer data ) { SENDER->clicked_save_dlg(button); }
		friend void sign_save_dlg_destroy( GtkWidget *wid, GdkEvent *ev, gpointer data ) { SENDER->clicked_save_dlg(-1); }	
	#undef SENDER

	private:
		app_objs *app_ref;
		
		// Materials object list
		vector<Material*> mat_liste;
		gint current;

		// Selection Widget
			// Variables
			GtkWidget *select_widget;
			GtkWidget *select_list;
			GtkListStore *select_list_store;
			GtkTreeSelection *select_list_selection;
			GtkWidget *select_buttons[MAX_TEX_BUTTONS];
			GtkTooltips *select_tooltips[MAX_TEX_BUTTONS];
		
			// Actions
			bool test_name_exist( char *name );
			void button_clicked( GtkWidget *wid );
			void row_selected( GtkTreeSelection *sel );
			void update_mat_name_list();
			void select_row( int row );
			void edit_button_clicked( GtkWidget *src );
	
		// Materials reference list ( for object selectors )
		char **mat_name_list;
		int mat_name_list_size;

		//  Active material selectors list
		vector<ObjParam_texref> ref_liste;
		ObjParam_texref *current_ref;

		// Material editor
			// Variables
			GtkWidget *ed_dialog, *edit_box;
			GtkWidget *edit_butt_wid[MAX_EDIT_BUTTONS];
			GtkTooltips *edit_butt_tt_wid[MAX_EDIT_BUTTONS];
			GtkWidget *editor_tree;
			GtkTreeStore *editor_tree_store;
			GtkTreeSelection *editor_tree_selection;
			MaterialPreview *preview;
			bool ed_applied;
			int edited;
			bool in_change;
			TvWidget_option_combo *texed_select;
			MaterialItem *copied_item;
		
			// Actions
			void clicked_ed_dlg( gint button );
			void close_ed_dlg();
			void update_texeditor();
			void editor_tree_select( GtkTreeSelection *selection ) { if ( edited != -1 ) mat_liste[edited]->mat_tree_select( selection ); }
			void ed_dlg_select();

		// Material save dialog
			// Variables
			GtkWidget *save_dialog;
			MaterialPreview *save_preview;
			TvWidget_path_alt *file;
			TvWidget_entry *author;
			TvWidget_text *comment;
			TvWidget_bool_activator *use_preview;
			
			// Actions
			void mat_save();
			void mat_save_dlgbox();
			void close_save_dialog();
			void clicked_save_dlg( gint button );
		
		// Material load		
		GtkWidget *filebox;
		void mat_load();
		vector<Material*> * load_list;

		// Default material load / save path
		char *default_path;		
		void store_default_path( char *path );
		
	public:
		MatList( app_objs *appref );
		~MatList();

		// App objs 	calls
		void pref_changed();
		void output_to_povray( ofstream & file );

		// Interface for material selectors ( eg ObjParam_texref )
		char **get_mat_name_list() { return mat_name_list; }
		int get_mat_name_list_size() { return mat_name_list_size; }
		void set_current_ref( ObjParam_texref *ref ) { current_ref = ref; }
		
		// Material list query and manipulation
			// Query
			int get_size() { return mat_liste.size(); }
			int get_index_by_pointer( Material *tex );
			Material *get_pointer_by_index( int index ) { return mat_liste[index]; }
			Material *get_pointer_by_name( char *str );
			
			// Manipulation
			char *create_name( char *name );
			void remove_material( Material *mat );
			void insert_material( Material *mat, int position );
			void clear();

		// Selection widget	
		void set_select_widget( GtkWidget *wid );
		void rename_list_row( Material *tex, char *name );
		Material *get_selected_material() { return (Material*)gtk_clist_get_row_data( GTK_CLIST(select_list), current ); }
			
		// Material editor
		Material *get_edited_material() { return mat_liste[edited]; }
		void raise_texeditor( int material = -1 );
		void raise_texeditor( Material *mat ) { raise_texeditor( get_index_by_pointer( mat ) ); }
		
		// Material Load & save
		void mat_load_from_file( char *path );
		void save( ofstream & file );
		bool load( ifstream & file, char * tag );
		void set_load_list( vector<Material*> * mlist ) { load_list = mlist; }
        void flush_load_list();

};

#endif
