#include "nr3.h"
#include <fstream>
#include <vector>

// example to read in the names and angles of the cities and
// put them in an array of structures (C) or a vector of classes (C++)
// 

const double DEGRAD=atan(1)/45.0; // to convert 
const double R_earth=6370; // radius earth

// C-style struct definition
struct citystruct {
    char* name;
    double theta; // angle with z-axis
    double phi; // azimuthal angle, projection in x-y plane
};

// C++-style class definition
class City {
   public :
        City(char* nam, double thet, double ph); // needs to be implemented
	char *getname() { return _name;};
        double theta() {return _theta;};
        double phi() {return _phi;};
        double distance(const City &city2); // needs to be implemented
        // use default copy constructor and destructor
   private :
        char  _name[27];
        double _theta;
        double _phi;
};

City::City(char *nam, double thet, double ph) {
// implementation of constructor
     for (int i=0; i<26; i++) _name[i]=nam[i];
    _name[26]='\0'; // make a terminated c-string
    _theta=thet*DEGRAD; // theta in radians
    _phi=ph*DEGRAD; // phi in radians
}  

double City::distance(const City& city2) {
// implementation of distance method
// accuracy for large distances about 1e-12m, for small distances about
// 2*1e-16*R_earth*sqrt(R_earth/dist) - up to a meter for dist=0
    double inp=cos(_phi)*cos(city2._phi)+sin(_phi)*sin(city2._phi);
    inp*=sin(_theta)*sin(city2._theta);
    inp+=cos(_theta)*cos(city2._theta);
    if (inp>0.99999999999999) inp=1; // catch machine-accuracy deviations from 1
    return R_earth*acos(inp);
}

int main() {
    char s[28],sdummy[100]; // to use getline in C++
    ifstream infil("./cities.txt"); // make an input file stream infil
    citystruct city1;
    citystruct citylist[211];
    vector<City> Cityvector;

    // read in the infil
    double theta,phi;
    int i = 0;
    while (i<211) { // read full infil, 211 cities
       infil.getline(s,28,','); // put all characters before , in string s
       infil >> theta; // read out theta
       infil.getline(sdummy,10,','); // put all characters before , in string s
       infil >> phi; // read out theta
       infil.getline(sdummy,10,'\n'); // put all characters before eoln in s
       city1.name=s;
       city1.theta=theta*DEGRAD;
       city1.phi=phi*DEGRAD;
//     made a city1 struct
       citylist[i]=city1; // put it in an array of cities
       City City1(s,theta,phi); // made a City object
       Cityvector.push_back(City1); // make your vector of City objects 1 longer
//       if (!(i%50)) {
		cout << "City struct " << i << " Name " << citylist[i].name << " polar angle " << citylist[i].theta  << " phi "  << citylist[i].phi << " ";
		cout << "City Class vector element " << i << " Name " << Cityvector[i].getname() << " polar angle " << Cityvector[i].theta()  << " phi "  << Cityvector[i].phi() << endl;
                if (i>0) cout << "Distance to previous city " << Cityvector[i].distance(Cityvector[i-1]) << endl;
 //      }
       i++;
    }
    return 0;
}
    

