/***************************************************************************
 *   Copyright (C) 2004 by David Sansome                                   *
 *   me@davidsansome.com                                                   *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#ifndef __lattice_H__
#define __lattice_H__

#include <qdialog.h>
#include <kscreensaver.h>
#include <kdialogbase.h>
#include <qgl.h>
#include <math.h>
#include <qtimer.h>
#include <fstream>
#include "latticesetup.h"

#define fabstrunc(f) (f >= 0.0f ? (f <= 1.0f ? f : 1.0f) : (f >= -1.0f ? -f : 1.0f))

#define PI 3.14159265359f
#define PIx2 6.28318530718f
#define D2R 0.0174532925f
#define R2D 57.2957795131f
#define NUMOBJECTS 10
#define LATSIZE 10


class camera
{
public:
	float farplane;
	float cullVec[4][3];  // vectors perpendicular to viewing volume planes

	camera(){};
	~camera(){};
	void init(float* mat, float f);
	bool inViewVolume(float* pos, float radius);
};

class LatticeWidget : public QGLWidget
{
	Q_OBJECT

public:
	LatticeWidget( QWidget* parent, const char* name, int lon, int lat, int thick, int dense, int depth, int fov, int path, int speed, int tex, bool smooth, bool fog, bool wide );
	~LatticeWidget();

protected:
	void paintGL();
	void resizeGL( int w, int h );
	void initTexture(int w, int h);
	void initializeGL();

private slots:
	void nextFrame();

private:
	int myMod(int x);
	float interpolate(float a, float b, float c, float d, float where);
	void initTextures();
	void makeLatticeObjects();
	void makeTorus(int smooth, int longitude, int latitude, float centerradius, float thickradius);
	void reconfigure();
	
	int _frameTime;
	QTimer* _timer;
	
	// Globals
	float elapsedTime;
	unsigned int lastTime;
	int lattice[LATSIZE][LATSIZE][LATSIZE];
	float bPnt[10][6];  // Border points and direction vectors where camera can cross from cube to cube
	float path[7][6];
	int globalxyz[3];
	int lastBorder;
	int segments;
	camera* theCamera;
	
	// Parameters edited in the dialog box
	int dLongitude;
	int dLatitude;
	int dThick;
	int dDensity;
	int dDepth;
	int dFov;
	int dPathrand;
	int dSpeed;
	int dTexture;
	bool dSmooth;
	bool dFog;
	bool dWidescreen;
	
};



class KLatticeScreenSaver : public KScreenSaver
{
	Q_OBJECT
	
public:
	KLatticeScreenSaver( WId id );
	KLatticeScreenSaver( WId id, int lon, int lat, int thick, int dense, int depth, int fov, int path, int speed, int tex, bool smooth, bool fog, bool wide );
	KLatticeScreenSaver( WId id, int preset );
	virtual ~KLatticeScreenSaver();
	
	int preset() { return dPreset; }
	int longitude() { return dLongitude; }
	int latitude() { return dLatitude; }
	int thick() { return dThick; }
	int density() { return dDensity; }
	int depth() { return dDepth; }
	int fov() { return dFov; }
	int pathrand() { return dPathrand; }
	int speed() { return dSpeed; }
	int texture() { return dTexture; }
	bool smooth() { return dSmooth; }
	bool fog() { return dFog; }
	bool widescreen() { return dWidescreen; }
	
	
private:
	void readSettings();
	void setPreset (int which);
	
	LatticeWidget* _effect;
	
	int dPreset;
	int dLongitude;
	int dLatitude;
	int dThick;
	int dDensity;
	int dDepth;
	int dFov;
	int dPathrand;
	int dSpeed;
	int dTexture;
	bool dSmooth;
	bool dFog;
	bool dWidescreen;
};



class KLatticeSetup : public KDialogBase
{
	Q_OBJECT

public:
	KLatticeSetup( QWidget* parent = 0, const char* name = 0 );
	~KLatticeSetup();

private slots:
	void slotHelp();
	void slotOk();
	void slotDefault();
	void slotApply();
	void resetTimer();
	void updatePreview();
	void presetChanged();

private:
	void saveSettings();
	void setPreset (int which);
	
	LatticeSetup* setupWidget;
	QWidget* preview;
	KLatticeScreenSaver* _saver;
	QTimer* timer;
};

#endif
