// Main program of STOKES containing the declaration of all objects
// and the main loop for a model run. The code of STOKES was written
// by Rene Goosmann. A manual can be downloaded from the web page
// www.stokes-program.info. If you have feedback or questions please
// contact admin@stokes-program.info.
//
// STOKES, version 1.0, Nov 2004


#include <iostream.h>
#include <stdlib.h>
#include <time.h>
#include "model-stokes-v1.0.h"
#include "mie-stokes-v1.0.h"
#include "photon-stokes-v1.0.h"
#include "observe-stokes-v1.0.h"


int main()
{
  long int i;

  // object containing all model parameters
  Model M;

  // object computing and storing Mie data of dust
  Mie Dust;

  // object managing the model photons
  Photon p;

  // object for the detector system
  Monitor MT;

  // initialize model parameters
  if (M.Initialize(Dust))
  {

    // set a new seed for the random number generator,
    // take it from the computer's internal clock
    srand((unsigned)time(NULL));

    cout << "Starting to sample photons...\n";

    // main loop to sample photons
    for (i=0; i<M.PhotonNum(); i++)
    {

      // create a new photon
      p.Reset(M);

      // search for scattering clouds
      while(p.ShiftToNextScatt(M,Dust))
      {

	// photon meets scattering region, proceeds
	// and eventually becomes scattered
        while(p.Proceed(M))
        {
          if (M.GetCloud(p.GetFlag()).dust)
          {
            p.DustScattering(M,Dust);
            if (p.Absorbed()) break;
          }
          else
          {
            p.ElectronScattering(M);
          }
        }
        if (p.Absorbed()) break;

      }

      // photon escaped or absorbed
      if (!p.Absorbed())
      {
           MT.RegisterPhoton(p,M);
      }

      // regularly show photon number and save results
      if ((i+1)%500000==0)
      {
        cout << "... " << (i+1) << " photons sampled\n";
        MT.SaveResults(i+1,M);
      }

    }
    cout << "Simulation completed\n";

    // save final results
    MT.SaveResults(i,M);
    cout << "Final results saved\n";

    cout << "Program finished.\n\n\n";
  }
  return 0;
}
