//*****************************************************************************************
// Truevision - a 3d modeler for gnome and povray
//
// interior.cc
//
// Vincent LE PRINCE <vincentleprince@users.sourceforge.net>
// Copyright (C) 2000-2001 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"

PovTexInterior::PovTexInterior( app_objs *appref ) : MaterialItem( app_ref )
{
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 );
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 );
}


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 );
fade = new TvWidget_bool_activator( *ref.fade );
fade_power = new TvWidget_float( *ref.fade_power );
fade_distance = new TvWidget_float( *ref.fade_distance );
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 fade;
delete fade_power;
delete fade_distance;
for ( unsigned int i = 0 ; i < media_liste.size() ; i++ )
	delete media_liste[i];
}


void PovTexInterior::edit_widget( GtkWidget *box )
{
bool tt = true;
MaterialItem::edit_widget( box, _("Interior") );

GtkWidget *frame_box;
GtkWidget *vbox = gtk_vbox_new( FALSE, 0 );
interior->set_target( vbox );
interior->get_widget_no_toggle( edit_cont, tt );
gtk_box_pack_start( GTK_BOX(edit_cont), vbox, TRUE, TRUE, 0 );
	ior->get_widget( vbox, tt );
	caustics->get_widget( vbox, tt );

	frame_box = dlg_simple_box_frame( _("Attenuation"), vbox );
	GtkWidget *fade_box = gtk_vbox_new( FALSE, 0 );
	fade->set_target( fade_box );
	fade->get_widget_no_toggle( frame_box, tt );
	gtk_box_pack_start( GTK_BOX(frame_box), fade_box, TRUE, TRUE, 0 );
	fade_distance->get_widget( fade_box, tt );
	fade_power->get_widget( fade_box, tt );

	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();
fade->clear_widget();
fade_distance->clear_widget();
fade_power->clear_widget();
}

void PovTexInterior::flush()
{
interior->flush();
ior->flush();
caustics->flush();
fade->flush();
fade_distance->flush();
fade_power->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 );

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\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 );

if ( fade->value() )
	{
	fade->save( file );
	fade_distance->save( file );
	fade_power->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 (fade->load( file , tag ) ) continue;	
	if (fade_distance->load( file , tag ) ) continue;
	if ( fade_power->load( file , tag ) ) continue;
	if ( ! strcmp( "MEDIA", tag ) ) 
		{
		PovTexMedia *newone = new PovTexMedia( app_ref, 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( GtkCTree *tree, GtkCTreeNode *node, GtkCTreeNode *sibling )
{
MaterialItem::add_to_tree( GTK_CTREE(tree), node, sibling );
for ( unsigned int i = 0 ; i < media_liste.size() ; i++ )
	media_liste[i]->add_to_tree( ctree, ctree_node );
}


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, sign_int_media_suicide, (gpointer)this );
media_liste.push_back( newone );
newone->add_to_tree( ctree, ctree_node );
}

void PovTexInterior::delete_media( PovTexMedia *media )
{
vector<PovTexMedia*>::iterator it = media_liste.begin();
while ( it != media_liste.end() )
	{
	if ( *it == media )
		{
		gtk_ctree_select( ctree, ctree_node );
		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( ctree, ctree_node );
		}
		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();
			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 );
		
       TEXLIST_DEF
		GtkCTreeNode *old_node = ctree_node;
		gtk_clist_freeze( GTK_CLIST(ctree) );
		add_to_tree( ctree, parent_node, old_node );
		gtk_ctree_remove_node( ctree, old_node );
		texlist->select_matedit_tree_node( ctree_node );
		gtk_clist_thaw( GTK_CLIST(ctree) );		
		}
		break;
	}
return true;
}
