#ifndef SURFACE_H
#define SURFACE_H

#include <stdio.h>
#include <stdlib.h>

#include "color.h"
#include "patch.h"
#include "vector.h"

#include "vector2d.h"
#include "CoefficientStream.h"
#include "SE/include/ply.h"

class Surface
{
protected:
  PATCH*    patch;           // The patch this surface is relative to.
  
public:
  // Constructor
  Surface(PATCH* p);

  // Virtual destructor
  virtual ~Surface() = 0;

  // Display the surface on screen
  virtual void display() = 0;

  // Write a VRML object
  virtual void writeVRML(FILE*) = 0;

  // Return the number of bytes required to represent this surface
  virtual int  getNumBytes() = 0;
};


class ConstantSurface : public Surface
{
private:
  COLOR c;

public:
  ConstantSurface(PATCH* p,const COLOR &col);
  ~ConstantSurface();

  void display();
  void writeVRML(FILE*);
  int  getNumBytes();
};


class DiffuseDecimatedSurface : public Surface
{
private:
  int     nv;
  VECTOR  *va;
  COLOR   *ca;

  int     nf;
  int     *fa;

public:
  DiffuseDecimatedSurface(PATCH *p,int fid,PlyFile *&);
  ~DiffuseDecimatedSurface();

  void display();
  void writeVRML(FILE*);
  int  getNumBytes();
};



class DiffuseCompressedSurface : public Surface
{
protected:
  int                rpos;       // Recursion level.
  CoefficientStore   *cs;        // Data stream.

public:
  DiffuseCompressedSurface(PATCH* patch,int recursionpos,CoefficientStore *cs);
  ~DiffuseCompressedSurface();

  void display();
  void writeVRML(FILE*);
  int  getNumBytes();
};



class NonDiffuseSurface : public Surface
{
private:
  int                     rdir;
  Surface                 **sap;

public:
  NonDiffuseSurface(PATCH *patch,int recursiondir);
  ~NonDiffuseSurface();

  void display();
  void writeVRML(FILE*);
  int  getNumBytes();

  void setDiffuseSurface(const int idx,Surface *sp);
};


#endif


