/*  trinculo, Flexible tools for multinomial association
    Copyright (C) 2014  Luke Jostins

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.*/

#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <string.h>
#include <stdlib.h>
#include <iterator>
#include <map>

using namespace std;


class dosagefile {
	// class to read and store genotype dosage inforamtion
  vector<double> doseblock; //the dosage information for each individual and SNP (linear representation of Ninds x Nvars matrix)
   
 public:
  int Nvars, Ninds; //number of variables and individuals stored
  vector<string> IID, RSID; //IDs of individuals and variants
  map<string,int> IDMap; //a map from IIDs to positions in the doseblock (used for matching across objects with different ID orderings)
  double getDosage(int i, int j); 
  void readDosage(string infile);
  void makeIDMap();
};

void dosagefile::makeIDMap() {
  //populate the ID map
  for (int i = 0; i < Ninds; i++) IDMap[IID[i] + ":" + IID[i]] = i;
}

void dosagefile::readDosage(string infile){
	// read dosage from a text file
  string line;
  double value;
  int i, j;
  double value2;
  ifstream dosage;
  istringstream linestream, tempstream;
  vector<string> splitline;
  dosage.open(infile.c_str());
  getline(dosage,line);
  linestream.str(line);
  copy(istream_iterator<string>(linestream), istream_iterator<string>(), back_inserter<vector<string> >(splitline));
  Nvars = splitline.size() - 1;
  for (i = 0; i < Nvars; i++) RSID.push_back(splitline[i + 1]);

  Ninds=0;
  j = 0;
  if (dosage.is_open()){
    cout << "Reading dosage file" << endl;
    while (!dosage.eof()){
      if (Ninds % 1000 == 0) cout << "Read " << Ninds << endl;
      getline(dosage,line);
      if (line.length() == 0) break;

      splitline.clear(); 
      linestream.clear();
      tempstream.clear();
      
      //cout << line;

      linestream.str(line);
      copy(istream_iterator<string>(linestream), istream_iterator<string>(), back_inserter<vector<string> >(splitline));
      
      for (i = 1; i < splitline.size(); i++){

	tempstream.str(splitline[i]);
	tempstream >> value;
	doseblock.push_back(value);
	j++;
	tempstream.clear();
      }
      Ninds++;
      IID.push_back(splitline[0]);
    }
    dosage.close();
  } else 
    cout << "Error: Cannot open dosage file" << endl;
}

double dosagefile::getDosage (int i,int j){
  //extract the dosage for a specified individual and SNP
  return(doseblock[i + j*Nvars]);
  }
