//*****************************************************************************************
// Truevision - a 3d modeler for gnome and povray
//
// matpov.h
//
// 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.  */ 
//*******************************************************************************************
#ifndef TV_TEXPOV_H
#define TV_TEXPOV_H
using namespace std;
#include "material.h"
#include "interior.h"
#include "texpigment.h"
#include "texnormal.h"
#include "texfinish.h"
#include <vector>


//****************************************************
// Classe Texture POV
//****************************************************
class PovTexture : public MaterialItem {
	#define SENDER ((PovTexture*)data)
	friend void sign_texture_type_changed( GtkWidget *wid, gpointer data ) { SENDER->type_changed(); }
	friend void sign_texture_delete( GtkWidget *wid, gpointer data ) { SENDER->del_texture(); }
	friend void sign_texture_add( GtkWidget *wid, gpointer data ) { SENDER->add_texture(); }	
	friend void sign_blockpat_changed( gpointer data ) { SENDER->blockpattern_changed(); }	

	friend void sign_texture_child_delete( gpointer data, gpointer child ) { SENDER->del_texture_child( (PovTexture*)child ); }
	friend void sign_texture_child_move( gpointer data, gpointer child, int sens )  { SENDER->move_texture_child( (PovTexture*)child, sens ); }	
	friend MapItem *mapedit_feeder_tex( gpointer data );
	#undef SENDER

	private:
		PovTexPigment *pigment;
		PovTexNormal *normal;
		PovTexFinish *finish;
		vector<PovTexture*> texture_list;
		void (*suicidal_func)(gpointer, gpointer);
		void (*move_func)(gpointer, gpointer, int );
		PovTexture *mother;
		bool is_mother;

		TvWidget_option_combo *type;
		TvWidget_map_editor *mapedit;
		TvWidget_blendmap *blendmap;
		TvWidget_blendmap_mod *blendmap_mod;
		TvWidget_bitmap *bitmap;
		TvWidget_transformation_rb *transfo;
		TvWidget_blockpattern *blockpattern;
		TvWidget_noise_rb *noise;
		TvWidget_warp_rb *warp;
		GtkWidget *changing_box1, *changing_box2, *vbox;

		void set_changing_box();
		void type_changed();
		void constructor_base();
		void blockpattern_changed();
		
		// count
		static int count;
		int texture_num;
		
	public:
		PovTexture( app_objs *appref );
		PovTexture( app_objs *appref, void (*suicidal_func)(gpointer, gpointer), void (*move_func)(gpointer, gpointer, int ), gpointer mother );
		PovTexture( PovTexture & ref );
		MaterialItem *duplicate_yourself() { PovTexture *res = new PovTexture( *this ); return res; }
		void set_params(  void (*suicidal_func)(gpointer, gpointer), void (*move_func)(gpointer, gpointer, int ), gpointer mother );
		virtual ~PovTexture();
		
		virtual void add_to_tree( GtkCTree *tree, GtkCTreeNode *node, GtkCTreeNode *sibling = NULL );
		void edit_widget( GtkWidget *box );
		void destroy_widget();
		void flush();
		void output_to_povray( ofstream & file, bool inmap = false );
		void output_to_povray_pigment( ofstream & file ) {  pigment->output_to_povray( file ); }
		bool has_pigment() { return pigment->is_used(); }
		bool has_normal() { return normal->is_used(); }
		void output_to_povray_normal( ofstream & file ) {  normal->output_to_povray( file ); }
		void output_to_povray_define_layered( ofstream & file );
		bool is_layered();

		bool is_used() { if ( type->value() == 0 ) return ( pigment->is_used() || finish->is_used() ) || normal->is_used(); else return true;}

		void del_texture() {  if ( !is_mother && suicidal_func!= NULL ) suicidal_func( mother, this ); }
		void delete_yourself() { if ( !is_mother && suicidal_func!= NULL ) suicidal_func( mother, this ); }
		void add_texture();
		void move_yourself( int sens ) { if ( !is_mother && move_func!= NULL ) move_func( mother, this, sens ); }
		void del_texture_child( PovTexture *child );
		void move_texture_child( PovTexture *child, int sens );

		void save( ofstream & file );
		bool load( ifstream & file, char * tag );
		
		bool paste( MaterialItem *item );
		virtual void save_node_state();
};

//****************************************************
// MapItem texture class
//****************************************************
class MapItem_texture : public MapItem {
	protected:
		PovTexture *texture;
		void refresh_name() { name = texture->get_name(); }

	public:
		MapItem_texture( float val, guint8 c, app_objs *appref );
		MapItem_texture( float val, guint8 c, PovTexture *tex );
		MapItem_texture( MapItem_texture & ref );
		MapItem *duplicate_yourself() { MapItem_texture *res = new MapItem_texture( *this ); return res; }
		~MapItem_texture() { delete texture; }

		void add_to_tree( GtkCTree *tree, GtkCTreeNode *node, GtkCTreeNode *sibling = NULL ) { texture->add_to_tree( tree, node, sibling ); }
		void remove_from_tree() { texture->remove_from_tree(); }
		void output_to_povray( ofstream & file ) { texture->output_to_povray( file, true ); }

		void save( ofstream & file );
		bool load( ifstream & file, char * tag );
		void save_node_state() { texture->save_node_state(); }
};


//****************************************************
// Classe Material POV
//****************************************************
class PovMaterial : public Material {
	private:
		PovTexture *texture;
		PovTexInterior *interior;
		TvWidget_glmat *quick_color;
		TvWidget_transformation *transfo;
		
	public:
		PovMaterial( app_objs *appref );
		~PovMaterial();
		void get_editor( GtkWidget *tree, GtkWidget *box );
		void edit_widget( GtkWidget *box );
		void destroy_widget();
		void flush();

		void output_to_povray( ofstream & file );
		void output_to_povray_pigment( ofstream & file ) {  texture->output_to_povray_pigment( file ); }
		bool has_pigment() { return texture->has_pigment(); }
		bool has_normal() { return texture->has_normal(); }
		void output_to_povray_normal( ofstream & file ) {  texture->output_to_povray_normal( file ); }
		void output_to_povray_media( ofstream & file ) {  interior->output_to_povray_media( file ); }
		bool is_used() { return ( texture->is_used() || interior->is_used() ); }
		void save( ofstream & file );
		bool load( ifstream & file );
		bool load( ifstream & file, char *tag );

		void set_gl_material() { quick_color->gl_set_material(); }
		virtual bool paste( MaterialItem *item );
		
		virtual void save_node_state() { MaterialItem::save_node_state(); texture->save_node_state(); interior->save_node_state(); }
};

#endif

