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

//**************************************
// Constructeur
//**************************************
LinkObj::LinkObj( app_objs *appref ) : Object3D( appref )
{
type = TV_OBJ3D_LINK;
category = TV_OBJ3D_OBJECTS;
set_name( "Link" );

// Base
link = new ObjParam_objref( N_("Link to"), "OBJREF", NULL, app_ref, true );
translation = new ObjParam_point( N_("Translation"), "LOC", NULL, app_ref, true );
translation->set( 0, 0, 0 );
size = new ObjParam_scale( N_("Scale"), "SIZE", NULL, app_ref, true );
size->set( 1, 1, 1 );
rotation = new ObjParam_rotation( N_("Rotation"), "ROT", NULL, app_ref, true );
rotation->set( 0, 0, 0 );
}

LinkObj::LinkObj( LinkObj & ref ) : Object3D( ref )
{
link = new ObjParam_objref( *ref.link );
translation = new ObjParam_point( *ref.translation );
size = new ObjParam_scale( *ref.size );
rotation = new ObjParam_rotation( *ref.rotation );
}

LinkObj::~LinkObj()
{
delete link;
delete translation;
delete size;
delete rotation;
}

//**************************************
// Display
// Dessin de la boite
//**************************************
void LinkObj::display( glview *view, bool set_col )
{
if ( link->get_current() == NULL ) return;
if ( hidden->value() ) return;
if ( translation->changed() || size->changed() || rotation->changed() || link->changed() )
	list.invalidate();

Object3D::display( view );	
	if ( set_col ) set_color();
	// mise à zero des parametres
	translation->unchange();
	size->unchange();
	rotation->unchange();
	link->unchange();

	// creation de la liste si necessaire
	list.begin();
	glPushMatrix();

	
	// Position et direction
	gfloat x, y, z;
	gfloat a, b, c;
	translation->get( x, y, z );
	glTranslatef( x, y, z );
	size->get( a, b, c );
	glScalef( a, b, c );
	rotation->gl_rotate();

	link->get_current()->display( false );

	glPopMatrix();
	list.end();
}


//***********************************************
// Edit
//***********************************************
void LinkObj::edit_widget( GtkWidget *wid )
{
PREF_DEF
bool tt = pref->tooltips->value();
edit_widget_base( wid );
hidden->get_widget( edit_cont, tt );
hidden->connect_signal( GTK_SIGNAL_FUNC(sign_hidden_changed), this );
render->get_widget( edit_cont, tt );
render->connect_signal( GTK_SIGNAL_FUNC(sign_render_changed), this );
	
// Options de geometrie
new_table( edit_cont, _("General settings"), 4 );
	link	->get_widget( table, tt, 1 );
	translation->get_widget( table, tt, 2 );
	size->get_widget( table, tt, 3 );
	rotation->get_widget( table, tt, 4 );

gtk_widget_show_all( wid );
}

//***********************************************
// Mouse drag
//***********************************************
void LinkObj::mouse_drag( struct drag_info *drag )
{
VMAN_DEF
OBJLIST_DEF

switch( vmanager->get_pointer_mode() )
	{
	case TV_PMODE_SELECT:
	case TV_PMODE_TRANSLATE:
		translation->mouse_drag( drag );
		break;

	case TV_PMODE_SCALE:
		{ size->mouse_drag( drag ); }
		break;

	case TV_PMODE_ROTATE:
		{ rotation->mouse_drag( drag ); break; }

	case TV_PMODE_CUSTOM:
		((ObjParam_point*)(objlist->get_current_param()))->mouse_drag( drag );
		break;

	default: 
		break;
	}
}

//***********************************************
// Pref_changed
//***********************************************
void LinkObj::pref_changed()
{
Object3D::pref_changed();
link->pref_changed();
translation->pref_changed();
size->pref_changed();
rotation->pref_changed();
}

//***********************************************
// Destroy editor
//***********************************************
void LinkObj::destroy_editor()
{
Object3D::destroy_editor();
link->clear_widget();
translation->clear_widget();
size->clear_widget();
rotation->clear_widget();
}

//***********************************************
// Output to povray
//***********************************************
void LinkObj::output_to_povray_pass2( ofstream & file )
{
if ( !render->value()) return;
if ( link->get_current() == NULL ) return;
file << "\n\n// Link : " << name->value();
file << "\nobject { "; link->get_current()->get_underscore_name( file ); 

file << "\t";
rotation->output_to_povray( file );
float x, y, z;
size->get( x, y, z );
file << "\n\tscale <" << x << ',' << y << ',' << z << ">\n\t";
translation->get( x, y, z );
file << "\n\ttranslate <" << x << "," << y << "," << -z << ">";
file << "\n}  ";
}

//***********************************************
// Save & load
//***********************************************
void LinkObj::save( ofstream & file )
{
file << "\nLINK{\n";
save_basics( file );
link->save( file );
translation->save( file );
size->save( file );
rotation->save( file );
file << "\n}";
}

bool LinkObj::load( ifstream & file, char *ltag )
{
if ( strcmp( ltag, "LINK" ) ) return false;
set_load_progress( file );

char * tag = NULL;
do {
	tag = tvio_get_next_tag( file );
	if ( tag == NULL ) break;
	
	if ( load_basics( file, tag ) ) continue;
 	if ( translation->load( file, tag ) ) continue;
 	if ( size->load( file, tag ) ) continue;
 	if ( rotation->load( file, tag ) ) continue;
 	if ( link->load( file, tag ) ) continue;
	
	tvio_skip_section(file );
	} while ( tag != NULL );

return true;
}
