//*****************************************************************************************
// Truevision - a 3d modeler for gnome and povray
//
// mapedit.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 MAPEDIT_H
#define MAPEDIT_H
using namespace std;
#include "tvwidgets.h"
#include <vector>

class TvWidget_map_editor;

//********************************************
// MapItem
//********************************************
class MapItem {
	friend class TvWidget_map_editor;
	protected:
		char *name;
		int num;
		guint8 color[4];
		float value;
		int cursor_pos;
		GtkWidget *button;

		virtual void refresh_name() {}
 
	public:	
		MapItem( char *nom, float val  );
		MapItem( MapItem & res );
		virtual MapItem *duplicate_yourself() { MapItem *item = new MapItem( *this ); return item; }
		virtual ~MapItem() {}
		virtual guint8 *get_color() { return color; }
		void set_color( guint8 r, guint8 g, guint8 b, guint8 a = 255 ) { color[0]=r; color[1]=g; color[2]=b; color[3]=a; }

		virtual void get_widget( GtkWidget *box, bool tt, TvWidget_map_editor *mother );
		virtual void destroy_widget() { gtk_widget_destroy(button); }
		virtual void flush() {}
		virtual void add_to_tree( GtkCTree *tree, GtkCTreeNode *node, GtkCTreeNode *sibling = NULL ) {}
		virtual void remove_from_tree() {}
		virtual void connect_signal(  void(*f)(gpointer), gpointer data ) {}

		virtual void get_editor( GtkWidget *box, bool tt ) {}
		virtual void destroy_editor() {}
		virtual void output_to_povray( ofstream & file ) {}

		void toggle() { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(button), TRUE ); }
		void untoggle() { gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(button), FALSE ); }
		virtual void update_editor() {}

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

class MapItem_test : public MapItem {
	protected:
		
	public:
		MapItem_test( float val = -1 ) : MapItem( "Test item", val) {}
		~MapItem_test() {}
};

//********************************************
// MapEditor
//********************************************
class TvWidget_map_editor: public TvWidget {
	#define SENDER ((TvWidget_map_editor*)data)
	friend void sign_mapedit_expose( GtkWidget *wid, GdkEventExpose *ev, gpointer data ) { SENDER->expose(ev); }
	friend void sign_mapedit_configure( GtkWidget *wid, GdkEventConfigure *ev, gpointer data ) { SENDER->configure(); }
	friend void sign_mapedit_realize( GtkWidget *wid, gpointer data ) { SENDER->realize(); }

	friend void sign_mapedit_mouse_moved( GtkWidget *wid, GdkEventMotion *ev, gpointer data ) { SENDER->mouse_moved(ev); }	
	friend void sign_mapedit_mouse_click( GtkWidget *wid, GdkEventButton *ev, gpointer data ) { SENDER->mouse_click(ev); }
	friend void sign_mapedit_mouse_release( GtkWidget *wid, GdkEventButton *ev, gpointer data ) { SENDER->mouse_release(); }

	friend void sign_mapedit_selection( GtkWidget *wid, gpointer data ) { SENDER->select(wid); }
	friend void sign_mapedit_delete_item( GtkWidget *wid, gpointer data ) { SENDER->delete_item(); }
	friend void sign_mapedit_append_item( GtkWidget *wid, gpointer data ) { SENDER->append_item(); }
	friend void sign_mapedit_prepend_item( GtkWidget *wid, gpointer data ) { SENDER->prepend_item(); }
	friend void sign_mapedit_duplicate_item( GtkWidget *wid, gpointer data ) { SENDER->duplicate_item(); }

	friend void sign_mapedit_item_changed( gpointer data ) { SENDER->item_changed(); }
	friend void sign_mapedit_valentry_changed( GtkWidget *wid, gpointer data ) { SENDER->value_entry_changed(); }	
	#undef SENDER

	protected:
		vector<MapItem*> item_list;
		
		GtkWidget *drawing_area;
		GdkPixmap *drawing_pix;
		int width, height;
		int grad_h;
		int linebreak1;
		int drag_y;
		bool in_drag;
		float drag_min, drag_max;
		GdkPixmap *cursor, *cursor_mask;
		GdkCursor *pointer;
		guchar *grad_image;
		bool in_change;
		int selected;
		MapItem* (*item_feeder)(gpointer);
		gpointer item_feeder_param;

		GtkWidget *items_box, *horbox, *editor_box;
		GtkWidget *value_entry;
		//GtkWidget *status;
		GtkCTree *ctree;
		GtkCTreeNode *ctree_node;

		void value_entry_changed();
		bool valentry_inchange;
		
	public:
		TvWidget_map_editor(  const char *name, const char *sname, const char *tooltip, app_objs *appref, MapItem* (*func)(gpointer), gpointer par );
		TvWidget_map_editor( TvWidget_map_editor & res );
		virtual ~TvWidget_map_editor();

		void expose( GdkEventExpose *ev );
		void configure();
		void realize();

		int test_mouse_pos( int x, int y, int sens, bool ignore_current, int current );
		void mouse_moved( GdkEventMotion *ev );
		void mouse_click( GdkEventButton *ev );
		void mouse_release() { in_drag = false; }
		void invalidate_drawing_area();
		void rebuild_item_list();
		void set_item_editor();
		
		void select( GtkWidget *wid );
		int get_sender_item( GtkWidget *wid );
		void delete_item();
		void append_item();
		void prepend_item();
		void duplicate_item();

		void add( MapItem *item ) { item_list.push_back( item ); }
		void item_changed() { invalidate_drawing_area(); }
		
		void get_widget( GtkWidget *box, bool tt );
		void update_gradient();
		void draw_gradient_line( int pos, guint8 *col );
		void clear_widget();
		void flush();
		void add_to_tree( GtkCTree *tree, GtkCTreeNode *node );
		void remove_from_tree();

		void output_to_povray( ofstream & file );
		void save( ofstream & file );
		bool load( ifstream & file, char *tag );
		
		void save_node_state() { for ( unsigned int i = 0 ; i < item_list.size() ; i++ ) item_list[i]->save_node_state(); }
};


#endif
