//***************************************************************************
#ifndef WAKEVORTEX_H
#define WAKEVORTEX_H
//***************************************************************************
#include <vector>
#include <stdio.h>
#ifdef HPUX
#include <iostream.h>
#else
#include <iostream>
#endif
#include "alloc.h"
#include "wing.h"
#include "airplane.h"
#ifdef _WIN32
using namespace std;
#endif
//***************************************************************************
enum
{
        VWING_STOP_TRACKING = 0,
        VWING_DELETE
};
//***************************************************************************
class Vortex
{
private:
 friend ostream &operator << (ostream &Out, Vortex &V);
 void movewings(int wingID);
 void shiftwake(int wingID);
 void movewakes(int wingID);
 void wakevel(int wingID);
 void agewake(int wingID);
 void findUVW(double u0, double v0, double w0, double delta, double upmag, double x, double y, double z, double *uu, double *vv, double *ww);
 inline void inducedvel(Wing *wing, int i, int j, double *vx, double *vy, double *vz, int sign);
 inline void inducedvel(Wing *wing, int i1, int j1, int i2, int j2, double *vx, double *vy, double *vz, int sign, int sign2);
 void inducedvel(double x1, double y1, double z1, double x2, double y2, double z2, double x, double y, double z, double *velx, double *vely, double *velz, double gamma, double eps);
 void Initialize();

public:
 int nwings;
 int ntotal;
 int nToBeDeleted;
 int nOutOfRange;
 int nwakemax;
 double temperature;    // in Celcius
 double dt;
 double u0;
 double v0;
 double w0;
 double delta;
 double upmag;
 double gtime;
 double glimit;
 double max_tracking_distance;  // in Kilometers
 int inducedvelocity_flag;
 int iter;
 int kn;
 int nvort;
 double curtime;
 vector<Wing> wing;

 Vortex(int n = 0);
 ~Vortex();
 void MarkAllDeleted();
 void CleanUp();

 inline int NextWing(int i);
 inline int NextInRange(int i);
 inline int Begin(void);
 inline int NextToBeDeleted();
 Vortex &operator= (const Vortex &);
 int AddWing(int allocate_flag = 1);
 int AddWingWithoutAllocation();
 void ReAlloc(int n);
 void Allocate(int i);
 void Compress();
 void deleteWing(int i);
 void undeleteWing(int i);
 void stopTrackingWing(int i);
 int CheckForOutOfRangeAircraft(double airport_center[3], int option);
 void ReadInputFile(char *inpfile, int nwake_max);
 double ComputeWake();
 int ComputeWake(int wingID);
 void WriteTecplotFile(int iter);
 int AddNewWing(char *trajfile, char *name, char *type, double x0, double y0, double z0, double span, double area, double weight);
 int AddRandomWing(char *trajfile, double x0, double y0, double z0);
 int Copy(Vortex *dest);

};
//***************************************************************************
inline int Vortex::NextWing(int i)
{
int j = i+1;
while ((j < nwings) && wing[j].ToBeDeleted) ++j;

return j;
}
//***************************************************************************
inline int Vortex::Begin(void)
{
int j = 0;
while ((j < nwings) && wing[j].ToBeDeleted) ++j;

return j;
}
//***************************************************************************
inline int Vortex::NextInRange(int i)
{
int j = (i+1)%nwings;
while ((j < nwings) && (wing[j].ToBeDeleted || wing[j].OutOfRange)) ++j;

return (j%nwings);
}
//***************************************************************************
inline int Vortex::NextToBeDeleted()
{
int j = 0;
while ((j < nwings) && (wing[j].ToBeDeleted == 0)) ++j;

return j;
}
//***************************************************************************
#include "packvortex.h"
//***************************************************************************
#endif // WAKEVORTEX_H
/***************************************************************************/