#ifndef PARAQ_H
#define PARAQ_H

#include <string>
#include <map>
#include <vector>

#define LINK_1TO1 0
#define LINK_NEGATIVE 1

using namespace std;

class paraq {
 private:
  struct paralink {
    string first;
    string second;
    int linktype;
  };

 public: 
  paraq(int nprocs, int rank);
  void addRange(const string& paraid, double min, double max, double step);
  int nextParas();
  double& operator[] (string paraid);
  void addRange(const string& paraid, double range[3]) { addRange(paraid, range[0], range[1], range[2]); }
  void addRange(const string& paraid, char *range);
  void setDefault(const string& paraid, double value) { defaultPara[paraid] = value; uniqueAllParaIdsAdd(paraid); }
  
  void linkParas(const string& paraid1, const string &paraid2, int linktype=LINK_1TO1) {
    paralink tmpLink;

    tmpLink.first = paraid1;
    tmpLink.second = paraid2;
    tmpLink.linktype = linktype;

    linkedParas.push_back( tmpLink );
    //linkedParas.push_back( make_pair(paraid1,paraid2) );
  }
  int getTotalJobs();
  string rangeString();
  vector<string> allParaIds;
  string getParaNames();
  string getParaVals();

 private:
  int nprocs, rank;
  int thisjob;
  map<string,double> defaultPara;
  map< string, vector<double> > paraMap;
  map< string, vector<double*> > rangeMap;
  vector<paralink> linkedParas;
  vector< map<string,double>  > jobList;
  void initJobList();
  bool inParas(vector<double>& paraVec, double& tofind);
  double masterdefault;
  bool jobListInitialized;
  void uniqueAllParaIdsAdd(const string& paraid);
  double linkTypeFunction (double linkval, int linktype);
};

#endif
