/// @file symbolweightvector.hpp
/// Helper classes for working with probability/weight vectors
///
/// @remarks
///
///- These classes are basically just wrappers around vectors of numbers
///  which represent the probability or occurrence count of symbols.
///
///- A typical use for one of these classes is as the vector of symbol
///  probabilities which is updated by the modeller and given to the 
///  coder in order to perform arithmetic coding.
///
///- Alternatively it could be used as a vector of frequencies to be given
///  to a huffman coder.
///
///- This class implements the standard octane API, so can save/load state and
///  report on memory usage.
///
/// @author mouser
/// @date   2003.07.29
///
/// @todo I considered making a base class and then derived template classes
///  for integer and floating point weight vectors.  however I'm not sure the
///  memory advantage for integers (the rare case) would offset the speed hit
///  to be paid for virtual functions, and the inconvenience of dealing with
///  different types for different coders/modelers.
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// recursive header protection
#ifndef SymbolWeightVectorH
#define SymbolWeightVectorH
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// application includes
#include "../bitio/bitio.hpp"
#include "../core/octaneclass.hpp"
#include "../parsers/parser.hpp"
// system includes
using namespace std;
#include <assert.h>
//---------------------------------------------------------------------------



//---------------------------------------------------------------------------
/// what kind of precision should we use for the weights (freqs/probabilities)?
/// we could use a typedef here, but that complicates things when we want to write/read with streams
#define TSymbolWeightVectorWeight float
// typedef float TSymbolWeightVectorWeight;
//---------------------------------------------------------------------------



//---------------------------------------------------------------------------
/// The SymbolWeightVector class is a helper class which holds a vector of
///  probabilities, typically associated with a modeler.  It provides
///  basic functionality to save and load state and display debugging information,
///  and report memory usage.
class SymbolWeightVector : public OctaneClass
{
protected:
	/// size of vector (# of symbol probabilities)
	int symbolcount;
	/// vector of probabilities
	vector<TSymbolWeightVectorWeight> weightvector;
public:
	/// constructor
	SymbolWeightVector() { symbolcount=0; }
	/// destructor
	virtual ~SymbolWeightVector() { ; }
public:
	//---------------------------------------------------------------------------
	// OCTANE PUBLIC API - RTTI FUNCTIONS - these are supported by all derived classes
	virtual std::string GetName() {return "SymbolWeightVector";}
	virtual std::string GetDescription() {return "Symbol Weight Vector";}
	virtual std::string GetHelpInformation() {return "";}
	//---------------------------------------------------------------------------
public:
	//---------------------------------------------------------------------------
	// OCTANE PUBLIC API - AUXILIARY FUNCTIONS - these are supported by all derived classes
	virtual void ShowDebuggingInfo();
	virtual unsigned int GetMemoryUsed();
	virtual unsigned int GetDiskspaceUsed(bool fortempdecompressiononly);
	virtual bool SaveState(bitwriter &to,bool fortempdecompressiononly);
	virtual bool LoadState(bitreader &from);
	//---------------------------------------------------------------------------
public:
	//---------------------------------------------------------------------------
	// SYMBOLWEIGHTVECTOR PUBLIC API - SYMBOL ACCESS
	/// Reset all probabilities.
	void ResetWeights();
	/// Normalize vector values into a probability distribution.
	void NormalizeToProbabilityDistribution();
	/// Set the number of symbols we should store weights for; can be called at any time to shrink or grow size.
	void SetSymbolCount(int newsize);
	/// Get count of symbols.
	int GetSymbolCount() {return symbolcount;};
	/// Get the weight (probability or freq count) of a symbol.
	TSymbolWeightVectorWeight GetSymbolWeight(int index) {assert(index<symbolcount);return weightvector[index];};
	/// Set the weight (probability or freq count) of a symbol.
	void SetSymbolWeight(int index,TSymbolWeightVectorWeight weight) {assert(index<symbolcount);weightvector[index]=weight;};
	/// Increment the weight of a given entry.
	void IncremementSymbolWeight(int index) {assert(index<symbolcount);weightvector[index]+=1;};
	/// Higher level function for automatic setting of frequencies with help of parser.
	/// This will actually parse the input using the parser, and count frequency of each symbol, and then normalize it into a probability distribution.
	/// @return true on success
	bool CountSymbolFrequencies(OctaneParser *parserp, bitreader &from);
	/// It's common that we may have symbols for characters we dont see for completeness
	///  and it's common to want to force these to some minimal value (like 1); some coders (like huffman), will break without this.
	void EnforceZeroCountFloor(TSymbolWeightVectorWeight symbolfloorval);
	//---------------------------------------------------------------------------
};
//---------------------------------------------------------------------------



//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------

