/* 
 * ionmapFile.h - Ion to Composition mapping file reader/writer 
 * Copyright (C) 2018, D Haley
 * 
 * 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/>.
 */


#ifndef IONMAPFILE_H
#define IONMAPFILE_H

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

#include "common/xmlHelper.h"

//!A class that can be used to define break-ups of ions, to recompute compositions
class IonMapTable
{
	private:

		//!Ions that are somehow a compound, which can be broken apart.
		std::vector<std::string> parentIons;
		//First entry in mapping is the mapped-to ion name
		// and the number of counts.
		// e.g., {Mo,2} could be an entry that describes a species which consists of 2 molybdenum ions
		std::vector<std::vector<std::pair<std::string, unsigned int> > > targetIons;

		bool isSelfConsistent() const;
	public:
		IonMapTable();
	
		bool operator==(const IonMapTable &oth) const;

		unsigned int getNumParentIons() const {return parentIons.size();}

		//!Read an XML ion map file, returns nonzero on error
		unsigned int read(const char *filename);
		//!Write an XML ion map front,returns nonzero on error
		unsigned int write(const char *filename);

	

		//!Remap count table from some source names to target names. Will renormalise composition. 
		// If errorOnUnmappable is true, then returns nonzero if ion name cannot be mapped. Otherwise, silently ignored
		unsigned int remapCounts(const std::vector<std::string> &ionNames, 
			const std::vector<unsigned int> &inCounts, std::vector<std::string> &mappedNames, 
			std::vector<unsigned int> &mappedCount, bool errorOnUnmappable=true) const;

		//!Remap 2D count table from some source names to target names. Will renormalise composition.
		// Inner part of table contains the independant values, and the outer vector (inCounts) must match ionNames.size()
		// If errorOnUnmappable is true, then returns nonzero if ion name cannot be mapped. Otherwise, silently ignored
		unsigned int remapCounts(const std::vector<std::string> &ionNames, 
			const std::vector<std::vector<unsigned int> > &inCounts, std::vector<std::string> &mappedNames, 
			std::vector<std::vector<unsigned int> > &mappedCount, bool errorOnUnmappable=true) const;



};

#ifdef DEBUG
bool testIonMapFile();
#endif

#endif
