//*****************************************************************************************
// Truevision - a 3d modeler for gnome and povray
//
// material.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/dlgutils.h"
#include "include/material.h"
#include "include/matlist.h"
#include "include/preferences.h"
#include "config.h"

app_objs *MaterialItem::app_ref = NULL;

//**************************************
// Constructeur
//**************************************
Material::Material( app_objs *appref, char *tagname ) : MaterialItem( appref, tagname )
{
PREF_DEF
clist = NULL;
current = NULL;
item_type = TV_MITEM_MATERIAL;
author= new TvWidget_entry( N_("Author"), "AUTHOR", NULL, app_ref );
author->set( pref->author->value() );
comment= new TvWidget_text( N_("Comment"), "COMMENT", NULL, app_ref );
}

//**************************************
// Set name
//**************************************
char *def_name = "Material#1";

void Material::set_name( char *nm )
{
MATLIST_DEF
if ( nm == NULL ) nm = def_name;
if ( strlen(nm) < 1 ) nm = def_name;
char *test = new char[ strlen(nm) + 1 ];
strcpy( test, nm );

char *res = matlist->create_name( test );
name->store();
if ( res != NULL ) 
	{
	name->set(res);
	delete res;
	}
else name->set(test);
delete test;
}

//**************************************
// Add to list
//**************************************
void Material::add_to_list( GtkListStore *store, int position )
{
GtkTreeIter   iter; 
if ( position == -1 ) gtk_list_store_append( store, &iter );
else gtk_list_store_insert( store, &iter, position );
gtk_list_store_set( store, &iter, 0, name->value(), -1 );
}


//**************************************
// Destroy
//**************************************
Material::~Material()
{
delete author;
delete comment;
}

void Material::get_underscore_name( ofstream & file )
{
char *nom = name->value();
//file << nom;
int len = strlen( nom );
file << "mat_";
for ( int i = 0 ; i < len ; i++ )
	file << (( nom[i] == ' ' || nom[i] == '#' || nom[i] == '-' || 
		nom[i] == '+' || nom[i] == '=' || nom[i] == '\'') 
		? '_' : nom[i]);
}

//**************************************
// Editor
//**************************************
void Material::get_editor(  GtkTreeView *view, GtkTreeStore *store, GtkTreeSelection *selection, GtkWidget *box )
{
box_editor = box;
current = NULL;
tree_view = view;
tree_store = store;
tree_selection = selection;
add_to_tree( view, store, selection, NULL, NULL );
}

void Material::destroy_editor()
{
if ( current != NULL ) current->destroy_widget();
remove_from_tree();
}

// MATERIAL SELECTED
void Material::mat_tree_select( GtkTreeSelection *selection )
{
if ( in_tree == false ) return;
GtkTreeIter iter;
GtkTreeModel *model;
gpointer objdef_ptr;
if (gtk_tree_selection_get_selected (selection, &model, &iter))
    gtk_tree_model_get (model, &iter, 1, &objdef_ptr, -1);
MaterialItem *sel = (MaterialItem*)objdef_ptr;
if ( sel == NULL ) return;

if ( current != NULL )
	{
	current->flush();
	current->destroy_widget();
	}
current = sel;
current->edit_widget( box_editor );
}


// Name changed
void Material::name_changed()
{
if ( name->in_update ) return;
MATLIST_DEF
set_name( name->get_current_value() );
gtk_tree_store_set( tree_store, &node_iter, 0, name->value(), -1 );
matlist->rename_list_row( this, name->value() );
}


// Delete item
void Material::delete_mat_item(  )
{
if ( current != NULL ) current->delete_yourself();
}

// Move item
void Material::move_mat_item( int sens )
{
if ( current != NULL ) current->move_yourself( sens );
}


//**************************************
//
// Material Item
// 
//**************************************
/*GtkTreeStore *MaterialItem::tree_store = NULL;
GtkTreeView *MaterialItem::tree_view = NULL;
GtkTreeSelection *MaterialItem::tree_selection = NULL;*/

MaterialItem::MaterialItem( app_objs *appref, char *tagname )
{
app_ref = appref;
sname = tagname;
in_tree = false;
widget = NULL;
edit_cont = NULL;
name = new TvWidget_entry( N_("Name"), "NAME", NULL, app_ref );
expand = new TvWidget_bool( NULL, "EXP", NULL, app_ref, true );
}


MaterialItem::MaterialItem( MaterialItem & ref )
{
sname = ref.sname;
app_ref = ref.app_ref;
tree_store = NULL;
in_tree = false;
widget = NULL;
edit_cont = NULL;
name = new TvWidget_entry( *ref.name );
expand = new TvWidget_bool( *ref.expand );
item_type = ref.item_type;
}

void MaterialItem::add_to_tree( GtkTreeView *view, GtkTreeStore *store, GtkTreeSelection *selection, GtkTreeIter *parent, GtkTreeIter *sibling  )
{
//cout << "\nadded to tree -> " << name->value(); cout.flush();
tree_view = view;
tree_store = store;
tree_selection = selection;
tree_node_parent = parent;
if ( in_tree ) return;

gtk_tree_store_insert_before( tree_store, &node_iter, parent, sibling );
gtk_tree_store_set( tree_store, &node_iter, 0, name->value(), 1, this, -1 );

in_tree = true;
//cout << "\nadded to tree -> " << name->value() << " - ctree = " << ctree << " - cree_node = " << ctree_node; cout.flush();
}


void MaterialItem::remove_from_tree()
{ 
if ( ! in_tree ) { return; }
gtk_tree_store_remove( tree_store, &node_iter );
in_tree = false;
}

void MaterialItem::set_node_state()
{
GtkTreePath *path = gtk_tree_model_get_path( GTK_TREE_MODEL(tree_store), &node_iter );
bool test = false;
if ( expand->value() == true ) test = gtk_tree_view_expand_row( tree_view, path, TRUE );
else gtk_tree_view_collapse_row( tree_view, path );
gtk_tree_path_free( path );
}

void MaterialItem::save_node_state()
{
//cout << "\nSave_node_state..." << name->value() << " - ctree = " << ctree << " - ctree_node =" << ctree_node ; cout.flush();
if ( tree_store == NULL || in_tree == false ) return;
gboolean isexp;
//gtk_ctree_get_node_info( GTK_CTREE(ctree), ctree_node, &text, &spacing, &pc, &mc, &po, &mo, &isleaf, &isexp );
GtkTreePath *path = gtk_tree_model_get_path( GTK_TREE_MODEL(tree_store), &node_iter );
isexp = gtk_tree_view_row_expanded( tree_view, path );
g_free( path );
expand->set( isexp );
}

void MaterialItem::edit_widget( GtkWidget *box, char *type )
{
widget = gtk_vbox_new( FALSE, 2 );
gtk_widget_set_usize( widget, 250, 400 );
gtk_box_pack_start( GTK_BOX(box), widget, TRUE, TRUE, 2 );
GtkWidget *frame = gtk_frame_new(NULL);
gtk_box_pack_start( GTK_BOX(widget), frame, FALSE, TRUE, 0 );
GtkWidget *label = gtk_label_new( type );
gtk_container_add( GTK_CONTAINER(frame), label );

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(widget), scrolled, TRUE, TRUE, 4 );
GtkWidget *viewp = gtk_viewport_new( NULL, NULL );
gtk_viewport_set_shadow_type( GTK_VIEWPORT(viewp), /*GTK_SHADOW_ETCHED_IN*/ GTK_SHADOW_NONE );
gtk_container_add( GTK_CONTAINER(scrolled), viewp );
edit_cont = gtk_vbox_new( FALSE, 0 );
gtk_container_set_border_width( GTK_CONTAINER(edit_cont), 1 );
gtk_container_add( GTK_CONTAINER(viewp), edit_cont );

name->get_widget( edit_cont, false );
name->connect_signal_changed( GTK_SIGNAL_FUNC(sign_miname_changed), this );
gtk_widget_show_all( widget );
}

void MaterialItem::set_name( char *nom )
{
name->set( nom );
}


void MaterialItem::name_changed()
{
if ( name->in_update ) return;
name->flush();
gtk_tree_store_set( tree_store, &node_iter, 0, name->value(), -1 );
}


void MaterialItem::paste_basics( MaterialItem *item )
{
name->copy( item->name );
reset_name_in_tree( name->value() );
}
