////////////////////////////////////////////////////////////
//
//  INSTANCE.H - Instance Class
//
//  Version:    1.03A
//
//  History:    94/08/23 - Version 1.00A release.
//              94/12/16 - Version 1.01A release.
//              95/02/05 - Version 1.02A release.
//              95/07/21 - Version 1.02B release.
//              96/02/14 - Version 1.02C release.
//              96/04/01 - Version 1.03A release.
//
//  Compilers:  Microsoft Visual C/C++ Professional V1.5
//              Borland C++ Version 4.5
//
//  Author:     Ian Ashdown, P.Eng.
//              byHeart Software Limited
//              620 Ballantree Road
//              West Vancouver, B.C.
//              Canada V7S 1W3
//              Tel. (604) 922-6148
//              Fax. (604) 987-7621
//
//  Copyright 1994-1996 byHeart Software Limited
//
//  The following source code has been derived from:
//
//    Ashdown, I. 1994. Radiosity: A Programmer's
//    Perspective. New York, NY: John Wiley & Sons.
//
//  It may be freely copied, redistributed, and/or modified
//  for personal use ONLY, as long as the copyright notice
//  is included with all source code files.
//
////////////////////////////////////////////////////////////

#ifndef _INSTANCE_H
#define _INSTANCE_H

#include "surface3.h"

class Instance          // Instance (also entity)
{
  private:
    Surface3 *pshead;   // Surface list head pointer
    Vertex3 *pvhead;    // Vertex list head pointer
    Instance *pnext;    // Next instance pointer

    double max_x, max_y, max_z;
    double min_x, min_y, min_z;

  public:
    Instance( Vertex3 *pv, Surface3 *ps )
    {
      pvhead = pv;
      pshead = ps;
      pnext = NULL;

    }

    ~Instance()
    {
      Surface3 *psnext;
      Surface3 *ps = pshead;
      Vertex3 *pvnext;
      Vertex3 *pv = pvhead;

      // Delete surfaces
      while (ps != NULL)
      {
        psnext = ps->GetNext();
        delete ps;
        ps = psnext;
      }

      // Delete vertices
      while (pv != NULL)
      {
        pvnext = pv->GetNext();
        delete pv;
        pv = pvnext;
      }
    }

    Instance *GetNext() { return pnext; }
    Surface3 *GetSurfPtr() { return pshead; }
    Vertex3 *GetVertPtr() { return pvhead; }
    void SetNext( Instance *pn ) { pnext = pn; }
    void SetSurfPtr( Surface3 *ps ) { pshead = ps; }
    void SetVertPtr( Vertex3 *pv ) { pvhead = pv; }
    double GetMax_X() { return max_x; }
    double GetMax_Y() { return max_y; }
    double GetMax_Z() { return max_z; }
    double GetMin_X() { return min_x; }
    double GetMin_Y() { return min_y; }
    double GetMin_Z() { return min_z; }
    void CalcExtents()
    {
      double vx,vy,vz;
      Vertex3 *pvert;

      // Initialize extents
      max_x = max_y = max_z = -MAX_VALUE;
      min_x = min_y = min_z = MAX_VALUE;

      // Walk the vertex list
      pvert = pvhead;
      while (pvert != NULL)
      {

        // Get vertex co-ordinates
        vx = pvert->GetPosn().GetX();
        vy = pvert->GetPosn().GetY();
        vz = pvert->GetPosn().GetZ();

        // Update x-axis extents
        if (vx > max_x)
          max_x = vx;
        if (vx < min_x)
          min_x = vx;

        // Update y-axis extents
        if (vy > max_y)
          max_y = vy;
        if (vy < min_y)
          min_y = vy;

        // Update z-axis extents
        if (vz > max_z)
          max_z = vz;
        if (vz < min_z)
          min_z = vz;

        pvert = pvert->GetNext();
      }
    }
};

#endif

