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

enum stype3d {
	TV_SPLINE3D_LINEAR = 0,
	TV_SPLINE3D_CUBIC,
	TV_SPLINE3D_BSPLINE,	
};
typedef stype3d SplineType3D;



class Spline3DPoint {
	private:
		float x, y, z;
		float extra_param;
	
	public:
		Spline3DPoint() { x=0; y=0; z=0; }
		Spline3DPoint( float a, float b, float c );
		Spline3DPoint( float a, float b, float c, float ext );
		Spline3DPoint * auto_copy() { return new Spline3DPoint( x, y, z, extra_param ); }
		
		void display( ) { glVertex3f( x, y, z ); }
		void save( ofstream & file );
		void load(  ifstream & file, char *tag );
		void output_to_povray( ofstream & file, int spline_type, bool first, bool for_lathe );
		float getx() { return x; }
		float gety() { return y; }
		float getz() { return z; }
		float get_extra_param() { return extra_param; }
		void get( float * target ) { target[0] = x; target[1] = y; target[2] = z; }
		void set( float a, float b, float c ) { x = a; y = b; z = c; }
		void set( float a, float b, float c, float ext ) { x = a; y = b; z = c; extra_param = ext; }
};

 class Spline3D {
	 private:
		vector<Spline3DPoint*> Points;
	 	SplineType3D type;
	 	int subdivisions;
		bool closed;
		
	public:
		Spline3D( SplineType3D type, int subdivisions );
		~Spline3D();
		Spline3D * auto_copy();
	
		void set_type( SplineType3D atype ) { type = atype; }
		void set_subdivisions( int sub ) { subdivisions = sub; }
	
		void add_point( Spline3DPoint *pt ) { Points.push_back( pt ); }
		void add_point( float x, float y, float z );
		void add_point( float x, float y, float z, float extra_param );
		void set_point( int i, float x, float y, float z ) { Points[i]->set( x, y, z ); }
		void set_point( int i, float x, float y, float z, float extra )  { Points[i]->set( x, y, z, extra ); }
		float getx( int pt ) { return Points[pt]->getx(); }
		float gety( int pt ) { return Points[pt]->gety(); }
		float getz( int pt ) { return Points[pt]->getz(); }
		float get_extra_param( int pt ) { return Points[pt]->get_extra_param(); }
		void append();
		void prepend();
		void insert( int i );
		void delete_point( int selected );
		
		void display_point( int i ) { Points[i]->display( ); }
		void save( ofstream & file );
		bool load( ifstream & file, char *tag );
		void output_to_povray( ofstream & file );
		
		void get_segments( int & pt_num, float  * & xcoords, float * & ycoords, float * & zcoords );
		void interpolate_extra_param( int & pt_num, float * & extra_params );
		void gl_display_segments();
		int size() { return Points.size(); }
 };

#endif
