////////////////////////////////////////////////////////////
//
//  TEST_1.CPP - Environment Data File Parser Test Program
//
//  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.
//
////////////////////////////////////////////////////////////

// NOTE: _NOT_WIN_APP must be globally defined for this
//       program to be successfully compiled

#include <stdio.h>
#include <iostream.h>
#include "parse.h"

// Default entity directory path
static char NoEntityDir[] = "";

static Parse Parser;            // World file parser
static Environ Environment;     // Environment

int main( int argc, char **argv )
{
  int inst_num;         // Instance number
  WORD surf_num;        // Surface number
  WORD patch_num;       // Patch number
  WORD elem_num;        // Element number
  WORD vert_num;        // Vertex number
  WORD list_num;        // Polylist number
  char *pentdir;        // Entity directory path
  Instance *pinst;      // Instance pointer
  Surface3 *psurf;      // Surface pointer
  ElemList *pelist;     // Element list pointer
  Patch3 *ppatch;       // Polygon pointer
  Element3 *pelem;      // Element pointer
  Vertex3 *pvert;       // Vertex pointer
  Spectra color;        // Temporary color
  Point3 posn;          // Point co-ordinates
  Vector3 normal;       // Normal vector

  // Get entity directory path (if any)
  if (argc > 2)
    pentdir = argv[2];
  else
    pentdir = NoEntityDir;

  // Parse the environment file
  if (Parser.ParseFile(argv[1], pentdir, &Environment) ==
      FALSE)
    return 1;

  // Get environment pointer
  pinst = Environment.GetInstPtr();

  // Walk the instance list
  inst_num = 1;
  while (pinst != NULL)
  {
    cout << "Instance #" << inst_num++ << endl;

    // Walk the surface list
    surf_num = 1;
    psurf = pinst->GetSurfPtr();
    while (psurf != NULL)
    {
      cout << "  Surface #" << surf_num++ << endl;
      color = psurf->GetReflectance();
      cout << "    reflectance = [ " << color.GetRedBand()
          << " " << color.GetGreenBand() << " " << 
          color.GetBlueBand() << " ]" << endl;
      color = psurf->GetEmittance();
      cout << "    emittance = [ " << color.GetRedBand() <<
          " " << color.GetGreenBand() << " " << 
          color.GetBlueBand() << " ]" << endl;

      // Walk the patch list
      patch_num = 1;
      ppatch = psurf->GetPatchPtr();
      while (ppatch != NULL)
      {
        cout << "    Patch #" << patch_num++ << endl;
        cout << "      area = " << ppatch->GetArea() <<
            endl;
        posn = ppatch->GetCenter();
        cout << "      center = < " << posn.GetX() << " "
            << posn.GetY() << " " << posn.GetZ() << " >" <<
            endl;
        normal = ppatch->GetNormal();
        cout << "      normal = < " << normal.GetX() << " "
            << normal.GetY() << " " << normal.GetZ() <<
            " >" << endl;
        color = ppatch->GetExitance();
        cout << "      exitance = [ " << color.GetRedBand()
            << " " << color.GetGreenBand() << " " << 
            color.GetBlueBand() << " ]" << endl;

        // Walk the patch element list
        elem_num = 1;
        pelem = ppatch->GetElementPtr();
        while (pelem != NULL)
        {
          cout << "      Element #" << elem_num++ << endl;
          cout << "        area = " << pelem->GetArea() <<
              endl;
          normal = pelem->GetNormal();
          cout << "        normal = < " << normal.GetX() <<
              " " << normal.GetY() << " " << normal.GetZ()
              << " >" << endl;
          color = pelem->GetExitance();
          cout << "        exitance = [ " <<
              color.GetRedBand() << " " <<
              color.GetGreenBand() << " " << 
              color.GetBlueBand() << " ]" << endl;

          pelem = pelem->GetNext();
        }
        ppatch = ppatch->GetNext();
      }
      psurf = psurf->GetNext();
    }

    // Walk the vertex list
    vert_num = 1;
    pvert = pinst->GetVertPtr();
    while (pvert != NULL)
    {
      cout << "  Vertex #" << vert_num++ << endl;
      posn = pvert->GetPosn();
      cout << "    position = < " << posn.GetX() << " " <<
          posn.GetY() << " " << posn.GetZ() << " >" << endl;
      normal = pvert->GetNormal();
      cout << "    normal = < " << normal.GetX() << " " <<
          normal.GetY() << " " << normal.GetZ() << " >" <<
          endl;
      color = pvert->GetExitance();
      cout << "    color = [ " <<  color.GetRedBand() << " "
          << color.GetGreenBand() << " " <<
          color.GetBlueBand() << " ]" << endl;

      // Walk the vertex element list
      list_num = 0;
      pelist = pvert->GetElemListPtr();
      while (pelist != NULL)
      {
        list_num++;
        pelist = pelist->GetNext();
      }
      cout << "    vertex shared by " << list_num <<
          " elements" << endl;
      pvert = pvert->GetNext();
    }
    pinst = pinst->GetNext();
  }

  return 0;
}

