////////////////////////////////////////////////////////////
//
//  TEST_4.CPP - Ray Casting 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 <stdlib.h>
#include <iostream.h>
#include <time.h>
#include "error.h"
#include "parse.h"
#include "ray_cast.h"

// Default entity directory path
static char NoEntityDir[] = "";

static RayCast Ray;             // Ray casting
static Parse Parser;            // World file parser
static Environ Environment;     // Environment

int main( int argc, char **argv )
{
  char *pentdir;        // Entity directory path
  Instance *penv;       // Environment pointer
  Instance *pinst_1;    // Instance pointer
  Instance *pinst_2;    // Instance pointer
  Surface3 *psurf;      // Surface pointer
  Patch3 *ppatch;       // Patch pointer
  Vertex3 *pvert;       // Vertex pointer
  WORD src_id = 1;      // Source patch identifier
  WORD rcv_id;          // Receiving vertex identifier

  // 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;

  // Seed the random number generator
  srand((unsigned) time(NULL));

  // Get environment pointer
  pinst_1 = penv = Environment.GetInstPtr();

  // Walk the instance list
  while (pinst_1 != NULL)
  {
    // Walk the surface list
    psurf = pinst_1->GetSurfPtr();
    while (psurf != NULL)
    {
      // Walk the patch list
      ppatch = psurf->GetPatchPtr();
      while (ppatch != NULL)
      {
        // Initialize the ray casting object
        Ray.Init(ppatch);
        cout << "Patch " << src_id << endl;

        // Walk the instance list
        rcv_id = 1;
        pinst_2 = penv;
        while (pinst_2 != NULL)
        {
          // Walk the vertex list
          pvert = pinst_2->GetVertPtr();
          while (pvert != NULL)
          {
            cout << "  FF(" << rcv_id++ << "," << src_id <<
                ") = " << Ray.CalcFormFactor(pvert, penv)
                << endl;
            pvert = pvert->GetNext();
          }
          pinst_2 = pinst_2->GetNext();
        }
        src_id++;
        ppatch = ppatch->GetNext();
      }
      psurf = psurf->GetNext();
    }
    pinst_1 = pinst_1->GetNext();
  }

  cout << endl << "Number of rays = " << RC_NumRays;

  return 0;
}

