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

PovTexInterior::PovTexInterior( app_objs *appref, char *tagname ) : MaterialItem( app_ref, tagname )
{
set_name( _("Interior") );
item_type = TV_MITEM_INTERIOR;

interior = new TvWidget_bool_activator( N_("Use interior"), "USED", NULL, app_ref, false );
ior = new TvWidget_float( _("IOR"), "IOR", NULL, app_ref, 1.0 );
	ior->set_range( 5, 0, 0.01, 2 );
caustics = new TvWidget_float( N_("Caustics"), "CAUSTICS", NULL, app_ref, 1.0 );
	caustics->set_range( 100, 0, 0.1 );
dispersion = new TvWidget_float( N_("Dispersion"), "DISP", NULL, app_ref, 1.0 );
	dispersion->set_range( 100, 0, 0.1 );
dispersion_samples = new TvWidget_int( N_("Dispersion samples"), "DISPSAMP", N_("Dispersion samples"), app_ref, 7 );
	dispersion_samples->set_range( 30, 1, 1 );
	
fade = new TvWidget_bool_activator( N_("Use attenuation"), "ATTUSED", NULL, app_ref, false );
fade_power = new TvWidget_float( N_("Fade power"), "FADEPOW", NULL, app_ref, 2 );
	fade_power->set_range( 100, 0, 0.1, 1 );
fade_distance = new TvWidget_float( N_("Fade distance"), "FADEDIST", NULL, app_ref, 10 );
	fade_distance->set_range( 100, 0, 0.1, 1 );
fade_color = new TvWidget_color( N_("Fade color"), "FADECOL", NULL, app_ref );
	fade_color->set( 0, 0, 0 );
media_liste.clear();
}


PovTexInterior::PovTexInterior( PovTexInterior & ref ) : MaterialItem( ref )
{
set_name( ref.get_name() );
item_type = TV_MITEM_INTERIOR;

interior = new TvWidget_bool_activator( *ref.interior );
ior = new TvWidget_float( *ref.ior );
caustics = new TvWidget_float( *ref.caustics );
dispersion = new TvWidget_float( *ref.dispersion );
dispersion_samples = new TvWidget_int( *ref.dispersion_samples );
fade = new TvWidget_bool_activator( *ref.fade );
fade_power = new TvWidget_float( *ref.fade_power );
fade_distance = new TvWidget_float( *ref.fade_distance );
fade_color = new TvWidget_color( *ref.fade_color );
for ( unsigned int i = 0 ; i < ref.media_liste.size() ; i++ )
	{
	PovTexMedia *item =  new PovTexMedia( *ref.media_liste[i] );
	media_liste.push_back( item );
	}
}


PovTexInterior::~PovTexInterior()
{
delete interior;
delete ior;
delete caustics;
delete dispersion;
delete dispersion_samples;
delete fade;
delete fade_power;
delete fade_distance;
delete fade_color;
for ( unsigned int i = 0 ; i < media_liste.size() ; i++ )
	delete media_liste[i];
}


void PovTexInterior::edit_widget( GtkWidget *box )
{
PREF_DEF
bool tt = pref->tooltips->value();
MaterialItem::edit_widget( box, _("Interior") );

GtkWidget *frame_box;
interior->get_widget_no_toggle( edit_cont, tt );
GtkWidget *vbox = gtk_vbox_new( FALSE, 0 );
gtk_box_pack_start( GTK_BOX(edit_cont), vbox, TRUE, TRUE, 0 );
GtkWidget *table = new_table_no_frame( vbox, 4 );
interior->set_target( vbox );
	ior->get_widget( table, tt, 1 );
	caustics->get_widget( table, tt, 2 );
	dispersion->get_widget( table, tt, 3 );
	dispersion_samples->get_widget( table, tt, 4  );

	frame_box = dlg_simple_box_frame( _("Attenuation"), vbox );
	fade->get_widget_no_toggle( frame_box, tt );
	GtkWidget *fade_box = new_table_no_frame( frame_box, 3 );
	fade->set_target( fade_box );
	fade_distance->get_widget( fade_box, tt, 1 );
	fade_power->get_widget( fade_box, tt, 2 );
	fade_color->get_widget( fade_box, tt, 3 );

	GtkWidget *button = gtk_button_new_with_label( _("Add media") );
	gtk_box_pack_start( GTK_BOX(vbox), button, FALSE, TRUE, 5 );
	gtk_signal_connect( GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(sign_int_addmedia), this );

gtk_widget_show_all( widget );
interior->update_widget();
fade->update_widget();
}

void PovTexInterior::destroy_widget()
{
MaterialItem::destroy_widget();
interior->clear_widget();
ior->clear_widget();
caustics->clear_widget();
dispersion->clear_widget();
dispersion_samples->clear_widget();
fade->clear_widget();
fade_distance->clear_widget();
fade_power->clear_widget();
fade_color->clear_widget();
}

void PovTexInterior::flush()
{
interior->flush();
ior->flush();
caustics->flush();
dispersion->flush();
dispersion_samples->flush();
fade->flush();
fade_distance->flush();
fade_power->flush();
fade_color->flush();
}

void PovTexInterior::output_to_povray( ofstream & file )
{
if ( !interior->value() ) return;
file << "\n\tinterior {\n\t\tior ";
ior->output_to_povray( file );
file << "\n\t\tcaustics ";
caustics->output_to_povray( file );
file << "\n\t\tdispersion ";
dispersion->output_to_povray( file );
file << "\n\t\tdispersion_samples ";
dispersion_samples->output_to_povray( file );

if ( fade->value() )
	{
	file << "\n\t\tfade_distance ";
	fade_distance->output_to_povray( file );
	file << "\n\t\tfade_power ";
	fade_power->output_to_povray( file );
	file << "\n\t\tfade_color ";
	fade_color->output_to_povray( file );
	}
file << "\n\t\t";
for ( unsigned int i = 0 ; i < media_liste.size() ; i ++ )
	media_liste[i]->output_to_povray( file );
file << "\n\t}\n";
}


void PovTexInterior::output_to_povray_media( ofstream & file )
{
if ( !interior->value() ) return;
file << "\n\n// Atmospheric Media ";
for ( unsigned int i = 0 ; i < media_liste.size() ; i ++ )
	media_liste[i]->output_to_povray( file );
}


void PovTexInterior::save( ofstream & file )
{
if ( !interior->value() ) return;
file << "INTERIOR{";
name->save( file );
expand->save( file );
ior->save( file );
caustics->save( file );
dispersion->save( file );
dispersion_samples->save( file );

if ( fade->value() )
	{
	fade->save( file );
	fade_distance->save( file );
	fade_power->save( file );
	fade_color->save( file );
	}
for ( unsigned int i = 0 ; i < media_liste.size() ; i ++ )
	media_liste[i]->save( file );
file << "}\n";
}


bool PovTexInterior::load( ifstream & file, char * ltag )
{
if ( strcmp( "INTERIOR", ltag ) ) return false;
char * tag = NULL;
interior->set( true );

do
	{
	tag = tvio_get_next_tag( file );
	if ( tag == NULL ) break;
	if (name->load( file , tag ) ) continue;	
	if (expand->load( file , tag ) ) continue;	
	if (ior->load( file , tag ) ) continue;
	if (caustics->load( file , tag ) ) continue;
	if (dispersion->load( file , tag ) ) continue;
	if (dispersion_samples->load( file , tag ) ) continue;
	if (fade->load( file , tag ) ) continue;	
	if (fade_distance->load( file , tag ) ) continue;
	if ( fade_power->load( file , tag ) ) continue;
	if ( fade_color->load( file , tag ) ) continue;
	if ( ! strcmp( "MEDIA", tag ) ) 
		{
		PovTexMedia *newone = new PovTexMedia( app_ref, "MEDIA", sign_int_media_suicide, (gpointer)this );
		newone->load( file, tag );
		media_liste.push_back( newone );
		continue;
		}
	tvio_skip_section( file );
	}
while( tag != NULL );
return true;
}


void PovTexInterior::add_to_tree( GtkTreeView *view, GtkTreeStore *store, GtkTreeSelection *selection, GtkTreeIter *parent, GtkTreeIter *sibling )
{
MaterialItem::add_to_tree( view, store, selection, parent, sibling );
for ( unsigned int i = 0 ; i < media_liste.size() ; i++ )
	media_liste[i]->add_to_tree( view, store, selection, &node_iter );
}


void PovTexInterior::save_node_state()
{
MaterialItem::save_node_state();
for ( unsigned int i = 0 ; i < media_liste.size() ; i++ )
	media_liste[i]->save_node_state();
}


void PovTexInterior::add_media()
{
PovTexMedia *newone = new PovTexMedia( app_ref, "MEDIA", sign_int_media_suicide, (gpointer)this );
media_liste.push_back( newone );
newone->add_to_tree( tree_view, tree_store, tree_selection, &node_iter );
}

void PovTexInterior::delete_media( PovTexMedia *media )
{
vector<PovTexMedia*>::iterator it = media_liste.begin();
while ( it != media_liste.end() )
	{
	if ( *it == media )
		{
		select_tree_row();
		media->remove_from_tree();
		media_liste.erase( it );
		delete media;		
		break;
		}
	it++;
	}
}


bool PovTexInterior::paste( MaterialItem *item )
{
switch ( item->get_type() )
	{
	default:
		return false;
		break;
		
	case TV_MITEM_MEDIA:
		{
		PovTexMedia *media = new PovTexMedia( *(PovTexMedia*)item );
		media->set_params(  sign_int_media_suicide, (gpointer)this );
		media_liste.push_back( media );
		media->add_to_tree( tree_view, tree_store, tree_selection, &node_iter );
		}
		break;
		
	case TV_MITEM_INTERIOR:
		{
		PovTexInterior *inte = (PovTexInterior*)item;
		for ( unsigned int i = 0 ; i < media_liste.size() ; i ++ ) delete media_liste[i];
		media_liste.clear();
       for ( unsigned int i = 0 ; i < inte->media_liste.size() ; i++ )
			{
			PovTexMedia *med =  new PovTexMedia( *(inte->media_liste[i]) );
			med->set_params( sign_int_media_suicide, (gpointer)this );
			media_liste.push_back( med );
			}
		if ( GTK_IS_WIDGET(widget) )
			{
			gtk_widget_destroy( edit_cont );
			interior->clear_widget();
			ior->clear_widget();
			fade->clear_widget();
			fade_power->clear_widget();
			fade_distance->clear_widget();
			fade_color->clear_widget();
			dispersion->clear_widget();
			dispersion_samples->clear_widget();
			caustics->clear_widget();
			}
		interior->copy( inte->interior );
		ior->copy( inte->ior );
		fade->copy( inte->fade );
		fade_power->copy( inte->fade_power );
		fade_distance ->copy( inte->fade_distance );
		caustics->copy( inte->caustics );
		dispersion->copy( inte->caustics );
		dispersion_samples->copy( inte->caustics );
		fade_color->copy( inte->caustics );
	
		GtkTreeIter *old_node = gtk_tree_iter_copy( &(inte->node_iter) );
		add_to_tree( tree_view, tree_store, tree_selection, tree_node_parent, old_node );
		gtk_tree_selection_unselect_iter( tree_selection, &node_iter );
		select_tree_row();
		gtk_tree_iter_free( old_node );
			
			
		}
		break;
	}
return true;
}

void PovTexInterior::remove_from_tree()
{
for ( unsigned int i = 0 ; i < media_liste.size() ; i++ )
	media_liste[i]->remove_from_tree();
MaterialItem::remove_from_tree();
}
