/*  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>
#include <limits>
#include <ctype.h>

using namespace std;

class priors {
	// class to read in and store a covariance matrix prior on effect sizes
 public:
  double *Sigma; //the prior on effect sizes
  double covarsigma; //the prior on nuassiance parameters
  int readPriors(string infile, int Npheno, int Npred, int Ncovar, int Ncondition, double covarsigma = 1);
};


int priors::readPriors(string infile, int Npheno, int Npred, int Ncovar, int Ncondition, double covarsigma){
  // read a covariance prior from a text file
  int Nparam = Npheno*(Npred + 1 + Ncovar + Ncondition);
  string line;
  double value;
  ifstream priorfile;
  priorfile.open(infile.c_str());
  int i,j, k;
  istringstream linestream, tempstream;
  vector<string> splitline;
  
  Sigma = new double [Nparam*Nparam];
  for (i = 0; i < Nparam*Nparam; i++) Sigma[i] = 0;
  for (i = 0; i < Nparam; i++) Sigma[i + i*Nparam] = covarsigma;

  for (i = 0; i < Npheno; i++){
	  getline(priorfile,line);
	  splitline.clear();
    linestream.clear();
    linestream.str(line);
    copy(istream_iterator<string>(linestream), istream_iterator<string>(), back_inserter<vector<string> >(splitline));
    if (splitline.size() != Npheno){
      cout << "Error: Prior file has incorrect dimensions." << endl;
      return(1);
    }
    
    for (j = 0; j < Npheno; j++){
		tempstream.clear();	    
      tempstream.str(splitline[j]);
      tempstream >> value;
      if (!tempstream) {
	cout << "Error: Non-numeric input present in prior file!" << endl;
	throw(2);
      }
      Sigma[1 + i*(Npred + Ncovar + 1 + Ncondition) + (1 + j*(Npred + Ncovar + 1 + Ncondition))*Nparam] = value;
      for (k = 0; k < Ncondition; k++)
	Sigma[(1 + Npred + Ncovar + k) + i*(Npred + Ncovar + 1 + Ncondition) + ((1 + Npred + Ncovar + k) + j*(Npred + Ncovar + 1 + Ncondition))*Nparam] = value;
    } 
  }
  return(0);
}


