//*****************************************************************************************
// Truevision - a 3d modeler for gnome and povray
//
// mateditor.cc
//
// The material editror
// class definition in matlist.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 *edit_butt_tt_text[MAX_EDIT_BUTTONS] = { _("New material"), _("Delete"), _("Copy"), _("Paste"), _("Move up"), _("Move down") };
const char *edit_butt_pix[MAX_EDIT_BUTTONS] = { GNOME_STOCK_PIXMAP_NEW, GNOME_STOCK_PIXMAP_CLOSE, GNOME_STOCK_PIXMAP_COPY,
	GNOME_STOCK_PIXMAP_PASTE, GNOME_STOCK_PIXMAP_UP, GNOME_STOCK_PIXMAP_DOWN };

//**************************************
// Raise texeditor	
//	
// Material editor dialog
//**************************************
void MatList::raise_texeditor( int mat )
{
	if ( GTK_IS_DIALOG(ed_dialog) ) {
		gdk_window_raise( ed_dialog->window );
		return;
	}
	if ( mat_liste.size() < 1 ) 
		return;
	PREF_DEF
	ed_applied = false;
	bool tt = pref->tooltips->value();

	// Dialog creation
	ed_dialog = gtk_dialog_new_with_buttons( _("Material editor"), NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, GTK_STOCK_HELP, GTK_RESPONSE_HELP, NULL );
	g_signal_connect( G_OBJECT(ed_dialog), "response", G_CALLBACK(sign_ed_dlg_click), this );
	g_signal_connect( G_OBJECT(ed_dialog), "close", G_CALLBACK(sign_ed_dlg_destroy), this );
	
	// Restore geometry if wanted
	if ( pref->save_dlg_geo->value() ) {
		if ( pref->med_xpos->value() < 0 ) pref->med_xpos->set(0);
		if ( pref->med_ypos->value() < 0 ) pref->med_ypos->set(0);	
		gtk_widget_set_uposition( ed_dialog, pref->med_xpos->value(), pref->med_ypos->value() );
		gtk_window_set_default_size( GTK_WINDOW(ed_dialog), pref->med_xsize->value(), pref->med_ysize->value() );
	}

	// Boxes
	GtkWidget *hbox = gtk_hbox_new( FALSE, 2 );
	gtk_box_pack_start( GTK_BOX(GTK_DIALOG(ed_dialog)->vbox), hbox, TRUE, TRUE, 2 );
	GtkWidget *vbox1 = gtk_vbox_new( FALSE, 2 );
	gtk_box_pack_start( GTK_BOX(hbox), vbox1, FALSE, TRUE, 2 );
	
	// Material selector
	edited = ( current != -1 ) ? current : 0;
	if ( mat != -1 ) 
		edited = mat;
	texed_select->set_list( (const char **)&(mat_name_list[1]), mat_liste.size(), edited );
	texed_select->get_widget( vbox1, tt );
	texed_select->connect_signal( GTK_SIGNAL_FUNC(sign_ed_dlg_select), this );

	// Material items tree
	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(vbox1), scrolled, TRUE, TRUE, 4 );

	editor_tree_store = gtk_tree_store_new( 2, G_TYPE_STRING, G_TYPE_POINTER );
	editor_tree = gtk_tree_view_new_with_model( GTK_TREE_MODEL(editor_tree_store) );
	gtk_container_add( GTK_CONTAINER(scrolled), editor_tree );

	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(editor_tree), column );

	editor_tree_selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(editor_tree) );
	gtk_tree_selection_set_mode ( editor_tree_selection, GTK_SELECTION_SINGLE );
	g_signal_connect( G_OBJECT(editor_tree_selection), "changed", G_CALLBACK(sign_matlist_editor_tree_select), this );

	// Material management buttons
	GtkWidget *bbox = gtk_hbox_new( FALSE, 3 );
	gtk_box_pack_start( GTK_BOX(vbox1), bbox, FALSE, TRUE, 2 );

	GtkWidget *pix = NULL;
	for ( int i = 0 ; i < MAX_EDIT_BUTTONS ; i ++ ) {
		edit_butt_wid[i] = gtk_button_new();
		gtk_box_pack_start( GTK_BOX(bbox), edit_butt_wid[i], TRUE, FALSE, 0 );
		gtk_signal_connect( GTK_OBJECT(edit_butt_wid[i]), "clicked", GTK_SIGNAL_FUNC(sign_edit_button_clicked), this );	
		pix = gtk_image_new_from_stock( edit_butt_pix[i], GTK_ICON_SIZE_BUTTON );
		gtk_container_add( GTK_CONTAINER(edit_butt_wid[i]), pix );
		edit_butt_tt_wid[i] = gtk_tooltips_new();
		gtk_tooltips_set_tip( edit_butt_tt_wid[i], edit_butt_wid[i], edit_butt_tt_text[i], NULL );
		if ( !pref->tooltips->value() ) 
			gtk_tooltips_disable( edit_butt_tt_wid[i] );
	}
	
	edit_box = gtk_vbox_new( FALSE, 2 );
	gtk_box_pack_start( GTK_BOX(hbox), edit_box, TRUE, TRUE, 2 );
	mat_liste[edited]->get_editor( GTK_TREE_VIEW(editor_tree), editor_tree_store, editor_tree_selection, edit_box );

	// Material preview
	GtkWidget *prev_box = gtk_vbox_new( FALSE, 2 );
	gtk_box_pack_start( GTK_BOX(hbox), prev_box, TRUE, TRUE, 2 );
	preview = new MaterialPreview( app_ref );
	preview->set_size( 140, 140 );
	preview->set_current_material( mat_liste[edited] );
	preview->get_widget( prev_box, tt );
	gtk_widget_show_all(ed_dialog);
}



//****************************************************
// ed_dlg_select
//
// Material selection callback from editor combo box
// ***************************************************
void MatList::ed_dlg_select()
{
	if ( texed_select->in_update ) 
		return;
	texed_select->flush();
	if ( edited == texed_select->value() ) 
		return;
	if ( edited != -1 ) {
		mat_liste[edited]->flush_material();
		mat_liste[edited]->save_node_state();
		mat_liste[edited]->destroy_editor();
		mat_liste[edited]->remove_from_tree();
	}
	edited = texed_select->value() ;
	if ( edited == -1 ) 
		return;
	mat_liste[edited]->get_editor( GTK_TREE_VIEW(editor_tree), editor_tree_store, editor_tree_selection, edit_box );
	preview->set_current_material( mat_liste[edited] );
}

//****************************************************
// clicked ed_dlg
//
// Material editor dialog callbacks
// ***************************************************
void MatList::clicked_ed_dlg( gint button )
{
	if ( edited != -1 ) 
		mat_liste[edited]->flush_material();
	VMAN_DEF

	switch( button ) {
		default:
		case GTK_RESPONSE_CLOSE:	
			preview->cancel_preview();
			close_ed_dlg();
			vmanager->force_refresh();
			break;

		case GTK_RESPONSE_HELP:
			truevision_help_display( "truevision.xml",  "sect-gui-mateditor", NULL );
			break;

		case GTK_RESPONSE_APPLY:
			vmanager->force_refresh();
			break;
	}
}


//****************************************************
// close ed_dlg
//
// Material editor close
// ***************************************************
void  MatList::close_ed_dlg()
{ 
	if ( !GTK_IS_DIALOG(ed_dialog) ) 
		return;
	preview->save_preview_settings();
	PREF_DEF
	if ( pref->save_dlg_geo->value() ) {
		gint x,y;
		gdk_window_get_root_origin( ed_dialog->window, &x, &y );
		pref->med_xpos->set( x );
		pref->med_ypos->set( y );
		pref->med_xsize->set( ed_dialog->allocation.width );
		pref->med_ysize->set( ed_dialog->allocation.height );
	}

	if ( edited != -1 ) 
		mat_liste[edited]->destroy_editor();
	gtk_widget_destroy( ed_dialog ); 
	ed_dialog = NULL;
	delete preview;
}



//****************************************************
// edit button clicked
//
// Material editor dialog buttons callbacks
// ***************************************************

// Material editor buttons : cut / copy / paste / move up / move down
const char *matnames[] ={ N_("Material"), N_("Texture"), N_("Interior"), N_("Finish"), N_("pigment"), N_("Normal"), N_("Media"), N_("Density") };

// Material editor tree button clicked callback
void  MatList::edit_button_clicked( GtkWidget *wid )
{
	int button = -1;
	for ( int i = 0 ; i < MAX_EDIT_BUTTONS ; i ++ )
		if ( wid == edit_butt_wid[i] ) { 
			button = i; 
			break; 
		}
	if ( button == -1 ) 
		return;
	if ( edited == -1 ) 
		return;
	SCENE_DEF
	UNDO_DEF

	switch ( button )
		{
		// New
		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 );
			undoman->push( TV_UNDO_MAT_CREATE, tex, -1 );
			texed_select->set( mat_liste.size() -1 );
			texed_select->update_widget();
			ed_dlg_select();
		}
		break;
	
		// Delete
		case 1:
			mat_liste[edited]->delete_mat_item();
			break;
		
		// Copy
		case 2: {
			if ( copied_item != NULL ) 
				delete copied_item;
			MaterialItem *target = mat_liste[edited]->get_selected_item();
			target->flush();
			copied_item = target->duplicate_yourself();
		}
		break;
		
		// Paste
		case 3: {	
			if ( copied_item == NULL ) 
				return;
			bool res = mat_liste[edited]->get_selected_item()->paste( copied_item );
			if ( ! res ) 
				app_warning( _("Cannot paste here item of type :"), matnames[ (int)copied_item->get_type() ] );
		}
		break;
		
		// Move up
		case 4:
			mat_liste[edited]->move_mat_item( 0 );
			break;
	
		// Move up
		case 5:
			mat_liste[edited]->move_mat_item( 1 );
			break;
	
		default:
			break;
	}
}



//****************************************************
// update texeditor
//
// Update tex list from outside ( the editor )
// ***************************************************
void  MatList::update_texeditor()
{
	if ( !GTK_IS_DIALOG(ed_dialog) ) 
		return;
	if ( mat_liste.size() < 1 ) { 
		close_ed_dlg(); 
		return; 
	}

	int current_index = edited;
	if ( current_index == -1 ) {
		current_index = 0;
		edited = -1;
	}
	texed_select->set_list( (const char **)&mat_name_list[1], mat_liste.size(), current_index );
	texed_select->update_widget();
}
