/*
    Copyright (C) 1998 by Jorrit Tyberghein
    Metaballs Demo (C) 1999 by Denis Dmitriev

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library 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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef __METADEMO__H__
#define __METADEMO__H__

#include <stdarg.h>

#include "igraph2d.h"
#include "igraph3d.h"
#include "csgeom/math2d.h"
#include "csgeom/math3d.h"
#include "cssys/common/sysdriv.h"

class csWorld;
class csTextureHandle;

struct GridCell
{
   csVector3 p[8];
   float val[8];
   GridCell() {} // NextStep 3.3 compiler barfs without this.
};

struct Triangle
{
   csVector3 p[3];
   Triangle() {} // NextStep 3.3 compiler barfs without this.
};

struct MetaBall
{
  csVector3 center;
};

enum EnvMappingModes    {TRUE_ENV_MAP,FAKE_ENV_MAP};
enum TextAlignmentModes {ALIGN_LEFT,ALIGN_RIGHT,ALIGN_CENTER};

/*
 * Main demo class. I know it's overloaded, but... That's okay ;)
 */
class MetaDemo:public SysSystemDriver
{
public:
  csWorld* world;
  csTextureHandle *tm;
  G3DPolygonDPFX* poly;

  int triangles_tesselated;
  int h_height,h_width,z_crit;
  int num_meta_balls,max_triangles;

  MetaBall *meta_balls;
  Triangle *triangles_array;

  float timeFPS,liveFPS;
  float iso_level,alpha,charge,d_alpha;

  char frame;
  int count,num_frames;

  int env_mapping;
  float env_map_mult;

  MetaDemo();
  virtual ~MetaDemo();

  void InitApp();
  virtual void Help();
  virtual void SetSystemDefaults();
  virtual bool ParseArg(int argc, char* argv[], int& i);

  virtual void NextFrame(long elapsed_time,long current_time);
  void eatkeypress(int key,bool shift,bool alt,bool ctrl,float elapsed_time);

  void DrawSomething(void);
  int Tesselate(const GridCell &grid,Triangle *triangles);
  void CalculateMetaBalls(void);
  void CalculateBlob(int x,int y,int z);
  void FillCell(int x,int y,int z,GridCell &c);
  void InitTables(void);

  float map(float x);
  float potential(const csVector3 &p);
  int check_cell_assume_inside(const GridCell &c);

  void WriteShadow(int align,int x,int y,int fg,char *str,...);
  void Write(int align,int x,int y,int fg,int bg,char *str,...);
};

#endif // __METADEMO__H__
