//*****************************************************************************************
// Truevision - a 3d modeler for gnome and povray
//
// matlist.cc
//
// Material list management
// Class definition in matlist.h
// The material editor is now in mateditor.cc
//
// 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.  */ 
//*******************************************************************************************
#include "include/matlist.h"
#include "include/preferences.h"
#include "include/interface.h"
#include "config.h"
#include "include/tvio.h"
#include "include/viewmanager.h"
#include "include/matlib.h"
#include "include/scene.h"
#include "include/undo.h"



//**************************************
// Definitions
//**************************************
const char *select_tex_buttons_icons[MAX_TEX_BUTTONS] =
	{ GNOME_STOCK_PIXMAP_NEW, GNOME_STOCK_PIXMAP_CLOSE, GNOME_STOCK_PIXMAP_PROPERTIES, GNOME_STOCK_PIXMAP_SAVE, GNOME_STOCK_PIXMAP_REVERT, GNOME_STOCK_PIXMAP_BOOK_BLUE };
const char *select_tex_buttons_tooltips[MAX_TEX_BUTTONS] =
	{ N_("New"), N_("Delete"), N_("Edit"), N_("Save"), N_("Load"), N_("Library") };

const char *ref_list_def[] = { N_("None") };



//**************************************
// Constructor
//**************************************
MatList::MatList( app_objs *appref )
{
	app_ref = appref;
	app_ref->matlist = this;
	
	// Initialisations
	current = -1;
	
		// Selection widget
		select_widget = NULL;
	
		// References
		mat_name_list = NULL;
		mat_name_list_size = 0;
		current_ref = NULL;
	

		// Material editor
		ed_dialog = NULL;
		edited = -1;
		in_change = false;
		copied_item = NULL;
		ed_applied = false;
		
		// Material save dialog
		save_dialog = NULL;
		
		// Material Load
		filebox = NULL;
		load_list = NULL;

		// Materail save / load default path
		default_path = NULL;

	// Material editor selection combo init 
	texed_select = new TvWidget_option_combo( N_("Name"), NULL, NULL, app_ref );
	
	// Reference list init
	update_mat_name_list();
}


//**************************************
// Destructor
//**************************************
MatList::~MatList()
{
for ( unsigned int i = 0 ; i < mat_liste.size() ; i++ )
	delete mat_liste[i];
}


//**************************************
// Output to povray
//
// declare materials with povray scene description language
//**************************************
void MatList::output_to_povray( ofstream & file )
{
	if ( edited != -1 ) 
		mat_liste[edited]->flush_material();

	file << "\n//---------------------------------------------";
	file << "\n//   Materials";
	file << "\n//---------------------------------------------";
	for ( unsigned int i = 0 ; i < mat_liste.size() ; i++ ) 
		mat_liste[i]->output_to_povray(file);
}




//****************************************************
// Pref changed
//
// Preferences changed
// ***************************************************
void  MatList::pref_changed()
{
	PREF_DEF
	bool tt = pref->tooltips->value();
	
	for ( int i = 0 ; i < MAX_TEX_BUTTONS ; i ++ )
		if ( tt ) 
			gtk_tooltips_enable( select_tooltips[i] );
		else 
			gtk_tooltips_disable( select_tooltips[i] );

	if ( ed_dialog != NULL ) {
		for ( int i = 0 ; i < MAX_EDIT_BUTTONS ; i ++ )
			if ( tt ) 
				gtk_tooltips_enable( edit_butt_tt_wid[i] );
			else 
				gtk_tooltips_disable( edit_butt_tt_wid[i] );
	}
}



//**************************************
// Set select_widget
//
// Add the material selection widget to property panel
//**************************************
void MatList::set_select_widget( GtkWidget *wid )
{
	PREF_DEF
	select_widget = wid;

	// Material selection tree header
	GtkWidget *frame = gtk_frame_new(NULL);
	gtk_box_pack_start( GTK_BOX(wid), frame, FALSE, TRUE, 0 );
	GtkWidget *label = gtk_label_new( N_("Materials") );
	gtk_container_add( GTK_CONTAINER(frame), label );

	// The viewport
	GtkWidget *scrolled = gtk_scrolled_window_new( NULL, NULL );
	gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
	gtk_box_pack_start( GTK_BOX(wid), scrolled, TRUE, TRUE, 4 );

	// The selection tree
	select_list_store = gtk_list_store_new( 1, G_TYPE_STRING );
	for ( unsigned int i = 0 ; i < mat_liste.size() ; i++ )
		mat_liste[i]->add_to_list( select_list_store );
	select_list = gtk_tree_view_new_with_model( GTK_TREE_MODEL(select_list_store) );
	gtk_container_add( GTK_CONTAINER(scrolled), select_list );

	GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
	GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes ( N_("Name"), renderer, "text", 0, NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW (select_list), column);

	select_list_selection = gtk_tree_view_get_selection( GTK_TREE_VIEW (select_list) );
	gtk_tree_selection_set_mode ( select_list_selection, GTK_SELECTION_SINGLE );
	g_signal_connect( G_OBJECT(select_list_selection), "changed", G_CALLBACK(sign_matlist_row_select), this );
	gtk_signal_connect( GTK_OBJECT(select_list), "row-activated", GTK_SIGNAL_FUNC(sign_matlist_row_activated), this );

	// Material manipulation buttons
	GtkWidget *hbox = gtk_hbox_new( TRUE, 0 );
	gtk_box_pack_start( GTK_BOX(wid), hbox, FALSE, TRUE, 2 );
	GtkWidget *pix = NULL;
	for ( int i = 0 ; i < MAX_TEX_BUTTONS ; i ++ ) {
		select_buttons[i] = gtk_button_new();
		gtk_button_set_relief( GTK_BUTTON(select_buttons[i]), GTK_RELIEF_NONE );
		gtk_box_pack_start( GTK_BOX(hbox), select_buttons[i], TRUE, FALSE, 0 );
		gtk_signal_connect( GTK_OBJECT(select_buttons[i]), "clicked", GTK_SIGNAL_FUNC(sign_matlist_button_clicked), this );	
		pix = gtk_image_new_from_stock( select_tex_buttons_icons[i], GTK_ICON_SIZE_BUTTON );
		gtk_container_add( GTK_CONTAINER(select_buttons[i]), pix );
		select_tooltips[i] = gtk_tooltips_new();
		gtk_tooltips_set_tip( select_tooltips[i], select_buttons[i], _(select_tex_buttons_tooltips[i]), NULL );
		if ( !pref->tooltips->value() ) 
			gtk_tooltips_disable( select_tooltips[i] );
	}
	gtk_widget_show_all( wid );
}


//*******************************************
// Rename list row
//
// Change a material name in the selection tree
//*****************************************
void MatList::rename_list_row( Material* tex, char *name )
{
	int index = get_index_by_pointer( tex );
	GtkTreeIter iter;
	gtk_tree_model_get_iter_first( GTK_TREE_MODEL(select_list_store), &iter );
	for ( int i = 0 ; i < index ; i++ ) 
		gtk_tree_model_iter_next( GTK_TREE_MODEL(select_list_store), &iter );
	gtk_list_store_set( select_list_store, &iter, 0,  name, -1  );
	update_mat_name_list();
}


//*******************************************
// Row selected
//
// Material selection tree row selection callback
//*****************************************
void MatList::row_selected( GtkTreeSelection *selection )
{
	GtkTreeIter iter;
	GtkTreeModel *model;
	gchar *name;
	if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
    	gtk_tree_model_get (model, &iter, 0, &name, -1);
		unsigned int i;
		for ( i = 0 ; i < mat_liste.size() ; i++ ) 
			if ( !strcmp( mat_liste[i]->get_name(), name ) ) break;;
		current = i;
		g_free (name);
    }
}

//*******************************************
// Select Row
//
// Material selection tree row selection ( force )
//*****************************************
void MatList::select_row( int row )
{
	GtkTreeIter iter;
	gtk_tree_model_get_iter_first( GTK_TREE_MODEL(select_list_store), &iter );
	for ( int i = 0 ; i < row ; i++ ) 
		gtk_tree_model_iter_next( GTK_TREE_MODEL(select_list_store), &iter );
	gtk_tree_selection_select_iter( select_list_selection, &iter );
}


//**************************************
// Button clicked
//
// Material tree selection widget buttons callbacks
//**************************************
void MatList::button_clicked( GtkWidget *wid )
{
	// Get the button bumber
	int button = -1;
	for ( int i = 0 ; i < MAX_TEX_BUTTONS ; i ++ )
		if ( wid == select_buttons[i] ) { button = i; break; }

	// Actions
	SCENE_DEF
	UNDO_DEF
	if ( button == -1 ) return;
	switch( button ) {
		default:
			break;
	
		// Add new material
		case 0: {
			scene->set_modified();
			Material *tex = (Material*)(new PovMaterial( app_ref, "MATERIAL" ));
			mat_liste.push_back( tex );
			tex->add_to_list( select_list_store );
			update_mat_name_list();
			select_row( mat_liste.size() -1 );
			PREF_DEF
			if ( pref->matedit->value() ) 
				raise_texeditor();
			undoman->push( TV_UNDO_MAT_CREATE, tex, -1 );
		}
		break;

		// Delete the current material
 		case 1: {
			scene->set_modified();
			remove_material( mat_liste[current] );
		}
		break;

		// Open the material editor
		case 2: {
			raise_texeditor();
		}
		break;

		// Save material
		case 3: {
			if ( current == -1 ) return;
			mat_save_dlgbox();
		}
		break;

		// Load material
		case 4: {
			mat_load();
		}
		break;

		// Open the material library		
		case 5: {
			MATLIB_DEF
			matlib->raise_dlg_box();
		}
		break;
	}
}



//**************************************
// test name exists
//
// Material name management
// check if a requested name is available
//**************************************
bool MatList::test_name_exist( char *name )
{
	bool exist = false;
	char *res;
	if ( ! strcmp( name, "NONE" ) ) 
		return true;
	for ( unsigned int i = 0 ; i < mat_liste.size() ; i++ ) {
		res = mat_liste[i]->get_name();
		if ( res == NULL ) 
			continue;
		if ( strcmp( res, name ) == 0 ) { 
			exist = true; 
			break; 
		}
	}
return exist;
}


//**************************************
// create name
//
// Material name management
// Create a material name from a request
//**************************************
char *MatList::create_name( char *name )
{
	if ( !test_name_exist( name ) ) 
		return NULL;
	int num = 1;
	int len = strlen(name);
	if ( ( name[len-1] >= 0x30 ) && ( name[len-1] <= 0x39 ) )	{
		int i;
		for ( i = len ; i > 0 ; i-- )
			if ( name[i] == '#' ) 
				break;
		if ( i > 0 ) { 
			sscanf( name+i-1, "#%u", &num ); 
			num++; 
			len -= len - i; 
		}
	}

	char buffer[ len + 30 ];
	char num_buffer[30];
	strcpy( buffer, name );
	do 	{
		sprintf( num_buffer, "#%u", num++ );
		memcpy( buffer+len, num_buffer, strlen(num_buffer)+1 );
		} while 
		( test_name_exist(buffer) );

	char *res = new char[ strlen(buffer) + 1 ];
	strcpy( res, buffer );
	return res;
}


//**************************************
// remove material
//
// delete a material from the list
//**************************************
void MatList::remove_material( Material *mat )
{
	vector<Material*>::iterator node;
	GtkTreeIter iter;
	gtk_tree_model_get_iter_first( GTK_TREE_MODEL(select_list_store), &iter );
	unsigned int i = 0;
	for ( node = mat_liste.begin() ; node != mat_liste.end() ; node++ ) {
		if ( i++ > 0 ) 
			gtk_tree_model_iter_next( GTK_TREE_MODEL(select_list_store), &iter );
		if ( *node != mat ) 
			continue;
		mat_liste.erase(node);
		gtk_list_store_remove( select_list_store, &iter );
		break;
	}
	current = -1;
	i--;
	if ( i > mat_liste.size() - 1) 
		i = mat_liste.size() - 1;
	if ( mat_liste.size() != 0 ) 
		select_row( i );

	update_mat_name_list();
	if ( mat_liste[edited] == mat ) {
		texed_select->set( i );
		texed_select->update_widget();
	}
}


//**************************************
// insert material
//
// delete a material from the list
//**************************************
void MatList::insert_material( Material *material, int position )
{
	vector<Material*>::iterator node;
	int i = 0;
	GtkTreeIter iter;
	gtk_tree_model_get_iter_first( GTK_TREE_MODEL(select_list_store), &iter );
	for ( node = mat_liste.begin(); i < position ; node++ ) { 
		i++;
		gtk_tree_model_iter_next( GTK_TREE_MODEL(select_list_store), &iter );
	}	
	
	mat_liste.insert( node, material );
	material->add_to_list( select_list_store, position );

	update_mat_name_list();
	gtk_tree_model_iter_next( GTK_TREE_MODEL(select_list_store), &iter );
	gtk_tree_selection_select_iter( select_list_selection, &iter );
}



//**************************************
// clear
//
// delete al materials from the list
//**************************************
void MatList::clear()
{
	for ( unsigned int i = 0 ; i < mat_liste.size() ; i++ )
		delete mat_liste[i];
	mat_liste.clear();
	gtk_list_store_clear( select_list_store );
	current = -1;
	edited = -1;
	current_ref = NULL;
	update_mat_name_list();
}


//**************************************
// rmat load
//
// Load a material
// Ask user which file with a file chooser
//**************************************
void MatList::mat_load()
{
	// Define filters for file chooser
	GtkFileFilter *filter1 = gtk_file_filter_new();
		gtk_file_filter_add_pattern( filter1, "*.tvm" );	
		gtk_file_filter_set_name( filter1, "Truevision material file" );	
	GtkFileFilter *filter2 = gtk_file_filter_new();
		gtk_file_filter_add_pattern( filter2, "*.*" );	
		gtk_file_filter_set_name( filter2, "All files" );	

	INTERF_DEF
	filebox = gtk_file_chooser_dialog_new( _("Load material..."), (GtkWindow*)interf->get_gtkwin(), 
	GTK_FILE_CHOOSER_ACTION_OPEN,  GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
	GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,  NULL);
	if ( default_path != NULL ) 
		gtk_file_chooser_set_current_folder( GTK_FILE_CHOOSER(filebox), default_path );
	gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(filebox), filter1 );
	gtk_file_chooser_add_filter( GTK_FILE_CHOOSER(filebox), filter2 );

	if (gtk_dialog_run (GTK_DIALOG (filebox)) == GTK_RESPONSE_ACCEPT) {
  		char *fname;
  		fname = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (filebox));
		if ( fname == NULL ) { 
			g_free( fname ); 
			return; 
		}
		store_default_path( fname );
		mat_load_from_file( fname );
  		g_free (fname);
  	}
	gtk_widget_destroy( filebox );	
}


//**************************************
// rmat load from file
//
// Load a material from a truevision material file
//**************************************
 void MatList::mat_load_from_file( char *fname )
{
	ifstream file( fname, ios::binary );
	if ( file == NULL ) {
		app_warning( _("Cannot open : "), fname );
		return;
	}
	if ( ! tvio_check_file_sig( file, "TRUEVISION MATERIAL" ) ) {
		app_warning( _("File type unknown : "), fname );
		return;
	}
	tvio_get_soft_version( file );
	
	Material *tex = (Material*)(new PovMaterial( app_ref, "MATERIAL" ));
	tex->load( file );

	mat_liste.push_back( tex );
	tex->add_to_list( select_list_store );
	update_mat_name_list();	
	file.close();
	SCENE_DEF
	scene->set_modified();
	select_row( mat_liste.size()-1 );
}


//**************************************
// Update material name list
//
// Create a list of names from the material vector
//**************************************
void MatList::update_mat_name_list()
{
	if ( mat_name_list != NULL ) {
		for ( int i = 0 ; i < mat_name_list_size ; i++ )
			delete mat_name_list[i];
		delete mat_name_list;
	}

	mat_name_list = new char*[ mat_liste.size() + 1 ];
	mat_name_list[0] = new char[ strlen( ref_list_def[0] ) + 1 ];
	strcpy( mat_name_list[0], (char*)ref_list_def[0] );
	for ( unsigned int i = 0 ; i < mat_liste.size() ; i ++ ) {
		mat_name_list[i+1] = new char[ strlen( mat_liste[i]->get_name() ) + 1 ];
		strcpy( mat_name_list[i+1], mat_liste[i]->get_name() );
	}
	mat_name_list_size = mat_liste.size() + 1;
	if ( current_ref !=NULL ) 
		current_ref->update_ref_list();

	update_texeditor();
}


//**************************************
// Get index by pointer
//
// get material position in list from a pointer
//**************************************
int MatList::get_index_by_pointer( Material *tex )
{
	int res = -1;
	for ( unsigned int i = 0 ; i < mat_liste.size() ; i ++ )
		if ( mat_liste[i] == tex ) { 
			res = i; 
			break; 
		}
	return res;
}


//**************************************
// Get pointer by name
//
// get pointer to material from its name
//**************************************
Material *MatList::get_pointer_by_name( char *str )
{
	if ( load_list == NULL ) {
		for ( unsigned int i = 0 ; i < mat_liste.size() ; i ++ )
			if ( !strcmp( str, mat_liste[i]->get_name() ) ) 
				return mat_liste[i];
		return NULL;
	} else 	{
		for ( unsigned int i = 0 ; i < load_list->size() ; i ++ ) {
			char *mat_name =  (*load_list)[i]->get_previous_name();
			if ( mat_name == NULL )
				mat_name =  (*load_list)[i]->get_name();
			if ( !strcmp( str, mat_name ) ) return (*load_list)[i];
		}
		return NULL;	
	}
	return NULL;
}




//***************************************************
// Mat save dlgbox
//
// Single material Save  dialog & process
//***************************************************
void MatList::mat_save_dlgbox()
{
	if ( mat_liste.size() < 1 ) 
		return;
	PREF_DEF
	bool tt = pref->tooltips->value();
	Material *sel = mat_liste[current];

	save_dialog =  gtk_dialog_new_with_buttons( _("Save material"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL );
	gtk_window_set_wmclass( GTK_WINDOW(save_dialog), PACKAGE, "Save material" );
	g_signal_connect( G_OBJECT(save_dialog), "response", G_CALLBACK(sign_save_dlg_click), this );
	g_signal_connect( G_OBJECT(save_dialog), "close", G_CALLBACK(sign_save_dlg_destroy), this );

	GtkWidget *hbox = gtk_hbox_new( TRUE, 2 );
	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(save_dialog)->vbox), hbox, TRUE, TRUE, 2 );

	// The left box
	GtkWidget *vbox1 = gtk_vbox_new( FALSE, 2 );
	gtk_box_pack_start( GTK_BOX(hbox), vbox1, FALSE, TRUE, 2 );

	file = new TvWidget_path_alt( N_("File"), NULL, NULL, app_ref );
	file->get_widget( vbox1, tt );
	if ( default_path != NULL )	
		file->set_default_path( default_path );

	sel->author->get_widget( vbox1, tt );
	sel->comment->get_widget( vbox1, tt );
	

	// The right box
	GtkWidget *vbox2 = gtk_vbox_new( FALSE, 2 );
	gtk_box_pack_start( GTK_BOX(hbox), vbox2, TRUE, TRUE, 2 );

	use_preview = new TvWidget_bool_activator( N_("Include preview"), NULL, NULL, app_ref, true );
	use_preview->get_widget_no_toggle( vbox2, tt );
	GtkWidget *vbox3 = gtk_vbox_new( FALSE, 2 );
	gtk_box_pack_start( GTK_BOX(vbox2), vbox3, TRUE, TRUE, 2 );
	use_preview->set_target( vbox3 );
	use_preview->update_widget();

	save_preview = new MaterialPreview( app_ref );
	save_preview->set_size( 80, 80 );
	save_preview->get_widget( vbox3, tt, true );

	gtk_widget_show_all( save_dialog );
}


//***************************************************
// Clicked save dlg
//
// Material save dialog callbacks
//***************************************************
void MatList::clicked_save_dlg( gint button )
{
	if ( button == GTK_RESPONSE_CANCEL ) { 
		close_save_dialog(); 	
		return; 
	}
	Material *sel = mat_liste[current];

	file->flush();
	sel->author->flush();
	sel->comment->flush();
	store_default_path( file->value() );

	// Check for file name existence
	if ( file->value() == NULL ) {
		GtkWidget *dialog =  gtk_message_dialog_new ( NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK, _("No file name specified"));	
		gtk_dialog_run( GTK_DIALOG(dialog));
		gtk_widget_destroy( dialog );
		return;
	}

	// Filename check and creation
	char *filename;
	bool added_ext = false;
	gchar *fname = file->value();
	int offset = strlen( fname ) - 4;
	if ( offset < 1 || ( strcmp( fname + offset, ".tvm" ) && strcmp( fname + offset, ".TVM" ) ) ) {
		filename = new char[ offset + 9 ];
		strcpy( filename, fname );
		strcat( filename, ".tvm" );
		added_ext = true;
	} else 
		filename = fname;

	// Open file
	ifstream ifile( filename, ios::binary );
	if ( ifile != NULL ) {
		GtkWidget *dialog =  gtk_message_dialog_new ( NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO, _("File already exists, overwrite ?"));	
		gint button = gtk_dialog_run( GTK_DIALOG(dialog));
		gtk_widget_destroy( dialog );
		if ( button == GTK_RESPONSE_NO ) 
			return;
	}
	ifile.close();

	ofstream ofile( filename, ios::out );
	ofile.setf( ios::fixed, ios::floatfield );
	if ( ofile == NULL ) { 
		app_warning( _("Cannot create : "), filename ); 
		close_save_dialog(); 
		return; 
	}

	// Set pointer to hourglass
	GdkCursor *pointer = gdk_cursor_new( GDK_WATCH );
	gdk_window_set_cursor( save_dialog->window,  pointer );

	// Preview
	if ( use_preview->value() ) {
		if ( save_preview->start_preview( sel, true, true ) == false ) {
			app_warning( _("Can't create preview : povray error.") );
			if ( added_ext ) 
				delete filename;
			gdk_cursor_destroy( pointer );
			close_save_dialog();
			return;
		}
	}
	
	// Write file
	ofile << "TRUEVISION MATERIAL";
	ofile << "\nVERSION " << VERSION << '\n';
	sel->author->save( ofile );
	ofile << '\n';
	sel->comment->save( ofile );
	save_preview->save_as_preview( ofile );
	sel->save( ofile );
	ofile.close();

	if ( added_ext ) 
		delete filename;
	gdk_cursor_destroy( pointer );
	close_save_dialog();
}





//***************************************************
// Close sace dialog
//
// Material save dialog close
//***************************************************
void MatList::close_save_dialog()
{
	gtk_widget_destroy( save_dialog );
	delete file;
	delete author;
	delete comment;
	delete save_preview;
	delete use_preview;
}

//************************************************************
// Store default path
//
// Manage default path for material load & save
//************************************************************
void MatList::store_default_path( char *path )
{
	if ( path == NULL ) 
		return;
	if ( default_path != NULL ) 
		delete default_path;
	int len = strlen( path );
	while ( len > 0 && path[len] != '/' ) 
		len--;
	if ( len == 0 ) 
		return;
	default_path = new char[ len + 2 ];
	strncpy( default_path, path, len+1 );
	default_path[len+1] = '\0';
}


//************************************************************
// Save
//
// Mat List save in a scene file 
//************************************************************
void MatList::save( ofstream & file )
{
	SCENE_DEF
	file << "\nMATERIALS{";
	for ( unsigned int i = 0 ; i < mat_liste.size() ; i++ ) {
		mat_liste[i]->save( file );
		scene->set_save_progress();
	}
	file << "\n}\n";
}


//************************************************************
// Load
//
// Mat List load from a scene file 
//************************************************************
bool MatList::load( ifstream & file, char *ltag )
{
	if ( strcmp( ltag, "MATERIALS" ) ) 
		return false;
	SCENE_DEF

	char * tag = NULL;
	do {
		tag = tvio_get_next_tag( file );
		if ( tag == NULL ) 
			break;
    	Material *tex = (Material*)(new PovMaterial( app_ref, "MATERIAL" ));
    	if ( tex->load( file, tag ) ) {
    		mat_liste.push_back( tex );
    		tex->add_to_list( select_list_store );
    		scene->set_load_progress( file );
    		continue;
    	}
    	else 
			delete tex;
		
		tvio_skip_section(file );
		} while 
			( tag != NULL );

	update_mat_name_list();	
	current_ref = NULL;
	return true;
}



//************************************************************
// flush load list
//
//************************************************************
void MatList::flush_load_list()
{
	if ( load_list == NULL ) 
		return;
	for ( unsigned int i = 0 ; i < load_list->size() ; i ++ ) {
		mat_liste.push_back( (*load_list)[i] );
		(*load_list)[i]->add_to_list( select_list_store );
	}
	update_mat_name_list();	
	load_list = NULL;
}
