/*
 *  TTextToGraph.cpp
 *  TTextToGraph
 *
 *  Created by Hugh Dickinson on 16/01/2008.
 *  Copyright 2008 __MyCompanyName__. All rights reserved.
 *
 */

#include "TTextToGraph.h"

template <class GraphType>
TTextToGraph<GraphType>::TTextToGraph(const char * infile, const char * fieldList, Int_t cOr):
fFileName(new TString(infile)),
fFields(new TString(fieldList)),
fColsOrRows(cOr),
fNumFields(0),
fType(WhichGraph<GraphType>::type)
{
GetFields();
MakeGraph();
}

template <class GraphType>
TTextToGraph<GraphType>::~TTextToGraph(){

}

template <class GraphType>
void TTextToGraph<GraphType>::GetFields(){
// Process the text file.
fTtov = new TTextToVector(fFileName->Data());
// get std::vector of integer field descriptors
fFieldArray = StringToInts();

// preliminary check to be establish whether the requested rows/columns for plotting even exist.
// checks for the appropriate number of rows/columns for the requested graph type happen later.
Int_t maxField = maximum_element(fFieldArray->begin(),fFieldArray->end());
if(fColsOrRows == 0 && fTtov->GetNumCols() < maxField){
	std::cerr << "There are not enough columns in the file to for the field list you have entered! Aborting." << std::endl;
	delete fFieldArray;
	fFieldArray=0;
	return;
	}
else if(fColsOrRows == 1 && fTtov->GetNumRows() < maxField){
	std::cerr << "There are not enough rows in the file to for the field list you have entered! Aborting." << std::endl;
	delete fFieldArray;
	fFieldArray=0;
	return;
	}
else{
	std::cout << "Successfully parsed requested plotting fields." << std::endl;
	return;
	}
}

template <class GraphType>
std::vector<int> * TTextToGraph<GraphType>::StringToInts(){
TObjArray * stringTokens = fFields->Tokenize(", ");
std::vector<Int_t> * ints = new std::vector<Int_t>(stringTokens->GetEntriesFast());
TIter it(stringTokens);

TObjString * tokenObj = 0;
Int_t tokenInt;
int i=0;

while((tokenObj = (TObjString*)it.Next())){
	if((tokenObj->GetString().IsInt())){
		tokenInt = tokenObj->GetString().Atof();
		ints->push_back(tokenInt);
		}
	else{
		std::cout << "Warning! Non-integer entry \"" << tokenObj->GetString().Data() << "\" found! Replacing with 0." << std::endl;
		ints->push_back(0);
		}
	i++;
	}
if(fNumFields==0){
	fNumFields = ints->size();
	}

delete tokenObj;
delete stringTokens;
	
return ints;
}

template <class GraphType>
GraphType * TTextToGraph<GraphType>::GetGraph(){
return fGraph;
}

// generic graph maker using template
template <class GraphType>
GraphType * TTextToGraph<GraphType>::MakeGraph(){
if(fType == 1){
	std::cout << "Making TGraph..." << std::endl;
	fGraph = MakeTGraph();
	}

if(fType == 1){
	std::cout << "Making TGraphErrors..." << std::endl;
	fGraph = MakeTGraphErrors();
	}
	
if(fType == 2){
	std::cout << "Making TGraphAsymmErrors..." << std::endl;
	fGraph = MakeTGraphAsymmErrors();
	}
	
if(fType == 3){
	std::cout << "Making TGraphBentErrors..." << std::endl;
	fGraph = MakeTGraphBentErrors();
	}
	
if(fType == 4){
	std::cout << "Making TGraph2D..." << std::endl;
	fGraph = MakeTGraph2D();
	}
	
if(fType == 5){
	std::cout << "Making TGraph2DErrors..." << std::endl;
	fGraph = MakeTGraph2DErrors();
	}

if(fGraph==0){
	std::cerr << "Graph creation failed!" << std::endl;
	}
else{
	std::cout << "Done." << std::endl;
	}
}

// Type specific graph makers.
template <class GraphType>
TGraph * TTextToGraph<GraphType>::MakeTGraph(){

TGraph * graph = 0;

if(fNumFields != 2){
	std::cerr << "Wrong number of fields specified to make a TGraph. Expected 2, found " << fNumFields << "!" << std::endl;
	return 0;
	}
if(fColsOrRows == 0){
	graph = new TGraph(fTtov->GetNumRows(), fTtov->GetCol(fFieldArray->at(0)), fTtov->GetCol(fFieldArray->at(1)));
	}
else if(fColsOrRows ==1){
	graph = new TGraph(fTtov->GetNumCols(), fTtov->GetRow(fFieldArray->at(0)), fTtov->GetRow(fFieldArray->at(1)));
	}

return graph;
}

template <class GraphType>
TGraphErrors * TTextToGraph<GraphType>::MakeTGraphErrors(){

TGraphErrors * graph = 0;

if(fNumFields != 4){
	std::cerr << "Wrong number of fields specified to make a TGraphErrors. Expected 4, found " << fNumFields << "!" << std::endl;
	return 0;
	}
if(fColsOrRows == 0){
	graph = new TGraphErrors(fTtov->GetNumRows(), fTtov->GetCol(fFieldArray->at(0)), fTtov->GetCol(fFieldArray->at(1)), 
		fTtov->GetCol(fFieldArray->at(2)),fTtov->GetCol(fFieldArray->at(3)));
	}
else if(fColsOrRows ==1){
	graph = new TGraphErrors(fTtov->GetNumCols(), fTtov->GetRow(fFieldArray->at(0)), fTtov->GetRow(fFieldArray->at(1)), 
		fTtov->GetRow(fFieldArray->at(2)),fTtov->GetRow(fFieldArray->at(3)));
	}

return graph;
}

template <class GraphType>
TGraphAsymmErrors * TTextToGraph<GraphType>::MakeTGraphAsymmErrors(){

TGraphAsymmErrors * graph = 0;

if(fNumFields != 6){
	std::cerr << "Wrong number of fields specified to make a TGraphAsymmErrors. Expected 6, found " << fNumFields << "!" << std::endl;
	return 0;
	}
if(fColsOrRows == 0){
	graph = new TGraphAsymmErrors(fTtov->GetNumRows(), fTtov->GetCol(fFieldArray->at(0)), fTtov->GetCol(fFieldArray->at(1)), 
		fTtov->GetCol(fFieldArray->at(2)),fTtov->GetCol(fFieldArray->at(3)), fTtov->GetCol(fFieldArray->at(4)), fTtov->GetCol(fFieldArray->at(5)));
	}
else if(fColsOrRows ==1){
	graph = new TGraphAsymmErrors(fTtov->GetNumCols(), fTtov->GetRow(fFieldArray->at(0)), fTtov->GetRow(fFieldArray->at(1)), 
		fTtov->GetRow(fFieldArray->at(2)),fTtov->GetRow(fFieldArray->at(3)), fTtov->GetRow(fFieldArray->at(4)), fTtov->GetRow(fFieldArray->at(5)));
	}
	
return graph;
}

template <class GraphType>
TGraphBentErrors * TTextToGraph<GraphType>::MakeTGraphBentErrors(){

TGraphBentErrors * graph = 0;

if(fNumFields != 10){
	std::cerr << "Wrong number of fields specified to make a TGraphBentErrors. Expected 10, found " << fNumFields << "!" << std::endl;
	return 0;
	}
if(fColsOrRows == 0){
	graph = new TGraphBentErrors(fTtov->GetNumRows(), fTtov->GetCol(fFieldArray->at(0)), fTtov->GetCol(fFieldArray->at(1)), 
		fTtov->GetCol(fFieldArray->at(2)),fTtov->GetCol(fFieldArray->at(3)), fTtov->GetCol(fFieldArray->at(4)), fTtov->GetCol(fFieldArray->at(5)), 
		fTtov->GetCol(fFieldArray->at(6)),fTtov->GetCol(fFieldArray->at(7)), fTtov->GetCol(fFieldArray->at(8)), fTtov->GetCol(fFieldArray->at(9)));
	}
else if(fColsOrRows ==1){
	graph = new TGraphBentErrors(fTtov->GetNumCols(), fTtov->GetRow(fFieldArray->at(0)), fTtov->GetRow(fFieldArray->at(1)), 
		fTtov->GetRow(fFieldArray->at(2)),fTtov->GetRow(fFieldArray->at(3)), fTtov->GetRow(fFieldArray->at(4)), fTtov->GetRow(fFieldArray->at(5)), 
		fTtov->GetRow(fFieldArray->at(6)),fTtov->GetRow(fFieldArray->at(7)), fTtov->GetRow(fFieldArray->at(8)), fTtov->GetRow(fFieldArray->at(9)));
	}
	
return graph;
}

template <class GraphType>
TGraph2D * TTextToGraph<GraphType>::MakeTGraph2D(){

TGraph2D * graph = 0;

if(fNumFields != 3){
	std::cerr << "Wrong number of fields specified to make a TGraph2D. Expected 3, found " << fNumFields << "!" << std::endl;
	return 0;
	}
if(fColsOrRows == 0){
	graph = new TGraph2D(fTtov->GetNumRows(), fTtov->GetCol(fFieldArray->at(0)), fTtov->GetCol(fFieldArray->at(1)), 
		fTtov->GetCol(fFieldArray->at(2)));
	}
else if(fColsOrRows ==1){
	graph = new TGraph2D(fTtov->GetNumCols(), fTtov->GetRow(fFieldArray->at(0)), fTtov->GetRow(fFieldArray->at(1)), 
		fTtov->GetRow(fFieldArray->at(2)));
	}

return graph;
}

template <class GraphType>
TGraph2DErrors * TTextToGraph<GraphType>::MakeTGraph2DErrors(){

TGraph2DErrors * graph = 0;

if(fNumFields != 6){
	std::cerr << "Wrong number of fields specified to make a TGraph2DErrors. Expected 6, found " << fNumFields << "!" << std::endl;
	return 0;
	}
if(fColsOrRows == 0){
	graph = new TGraph2DErrors(fTtov->GetNumRows(), fTtov->GetCol(fFieldArray->at(0)), fTtov->GetCol(fFieldArray->at(1)), 
		fTtov->GetCol(fFieldArray->at(2)),fTtov->GetCol(fFieldArray->at(3)), fTtov->GetCol(fFieldArray->at(4)), fTtov->GetCol(fFieldArray->at(5)));
	}
else if(fColsOrRows ==1){
	graph = new TGraph2DErrors(fTtov->GetNumCols(), fTtov->GetRow(fFieldArray->at(0)), fTtov->GetRow(fFieldArray->at(1)), 
		fTtov->GetRow(fFieldArray->at(2)),fTtov->GetRow(fFieldArray->at(3)), fTtov->GetRow(fFieldArray->at(4)), fTtov->GetRow(fFieldArray->at(5)));
	}
	
return graph;
}

templateClassImp(TTextToGraph)
