#ifndef PRESET_CHOOSER_HPP
#define PRESET_CHOOSER_HPP

#include "Preset.hpp"

#include "PresetLoader.hpp"
#include "RandomNumberGenerators.hpp"
#include <cassert>
#include <memory>
#include <iostream>
class PresetChooser;

///  A simple iterator class to traverse back and forth a preset directory
class PresetIterator {

public:
    PresetIterator()  {}

    /// Instantiate a preset iterator at the given starting position
    PresetIterator(std::size_t start);

    /// Move iterator forward
    void operator++();

    /// Move iterator backword
    void operator--() ;

    /// Not equal comparator
    bool operator !=(const PresetIterator & presetPos) const ;

    /// Equality comparator
    bool operator ==(const PresetIterator & presetPos) const ;

    /// Returns an integer value representing the iterator position
    /// @bug might become internal
    /// \brief Returns the indexing value used by the current iterator.
    std::size_t operator*() const;

    ///  Allocate a new preset given this iterator's associated preset name
    /// \param presetInputs the preset inputs to associate with the preset upon construction
    /// \param presetOutputs the preset outputs to associate with the preset upon construction
    /// \returns an autopointer of the newly allocated preset
    std::auto_ptr<Preset> allocate();

    ///  Set the chooser asocciated with this iterator
    void setChooser(const PresetChooser & chooser);

private:
    std::size_t _currentIndex;
    const PresetChooser * _presetChooser;

};

/// Provides functions and iterators to select presets. Requires a preset loader upon construction
class PresetChooser {

public:
    typedef PresetIterator iterator;

    /// Initializes a chooser with an established preset loader.
    /// \param presetLoader an initialized preset loader to choose presets from
    /// \note The preset loader is refreshed via events or otherwise outside this class's scope
    PresetChooser(const PresetLoader & presetLoader, bool 	softCutRatingsEnabled);

    inline void setSoftCutRatingsEnabled(bool enabled) {
	_softCutRatingsEnabled = enabled;
    }

    /// Choose a preset via the passed in index. Must be between 0 and num valid presets in directory
    /// \param index An index lying in the interval [0, this->getNumPresets())
    /// \param presetInputs the preset inputs to associate with the preset upon construction
    /// \param presetOutputs the preset outputs to associate with the preset upon construction
    /// \returns an auto pointer of the newly allocated preset
    std::auto_ptr<Preset> directoryIndex(std::size_t index) const;

    /// Gets the number of presets last believed to exist in the preset loader's filename collection
    /// \returns the number of presets in the collection
    std::size_t size() const;

    /// An STL-esque iterator to begin traversing presets from a directory
    /// \param index the index to begin iterating at. Assumed valid between [0, num presets)
    /// \returns the position of the first preset in the collection
    PresetIterator begin(unsigned int index) const;

    /// An STL-esque iterator to begin traversing presets from a directory
    /// \returns the position of the first preset in the collection
    PresetIterator begin();

    /// An STL-esque iterator to retrieve an end position from a directory
    /// \returns the end position of the collection
    PresetIterator end() const;

    /// Perform a weighted sample to select a preset (uses preset rating values)
    /// \returns an iterator to the randomly selected preset
    iterator weightedRandom(bool hardCut) const;

    /// True if no presets in directory
    bool empty() const;


    inline void nextPreset(PresetIterator & presetPos);
    inline void previousPreset(PresetIterator & presetPos);

private:
    std::vector<float> sampleWeights;
    const PresetLoader * _presetLoader;
    bool _softCutRatingsEnabled;
};


inline PresetChooser::PresetChooser(const PresetLoader & presetLoader, bool softCutRatingsEnabled):_presetLoader(&presetLoader), _softCutRatingsEnabled(softCutRatingsEnabled) {

}

inline std::size_t PresetChooser::size() const {
    return _presetLoader->size();
}

inline void PresetIterator::setChooser(const PresetChooser & chooser) {
    _presetChooser = &chooser;
}

inline std::size_t PresetIterator::operator*() const {
    return _currentIndex;
}

inline PresetIterator::PresetIterator(std::size_t start):_currentIndex(start) {}

inline void PresetIterator::operator++() {
    assert(_currentIndex < _presetChooser->size());
    _currentIndex++;
}

inline void PresetIterator::operator--() {
    assert(_currentIndex > 0);
    _currentIndex--;
}

inline bool PresetIterator::operator !=(const PresetIterator & presetPos) const {
    return (*presetPos != **this);
}


inline bool PresetIterator::operator ==(const PresetIterator & presetPos) const {
    return (*presetPos == **this);
}

inline std::auto_ptr<Preset> PresetIterator::allocate() {
    return _presetChooser->directoryIndex(_currentIndex);
}

inline void PresetChooser::nextPreset(PresetIterator & presetPos) {

		if (this->empty()) {
			return;
		}

		// Case: idle preset currently running, selected first preset of chooser
		else if (presetPos == this->end())
			presetPos = this->begin();
		else
			++(presetPos);

		// Case: already at last preset, loop to beginning
		if (((presetPos) == this->end())) {
			presetPos = this->begin();
		}

}


inline void PresetChooser::previousPreset(PresetIterator & presetPos) {
		if (this->empty())
			return;

		// Case: idle preset currently running, selected last preset of chooser
		else if (presetPos == this->end()) {
			--(presetPos);
		}

		else if (presetPos != this->begin()) {
			--(presetPos);
		}

		else {
		   presetPos = this->end();
		   --(presetPos);
		}
}

inline PresetIterator PresetChooser::begin() {
    PresetIterator pos(0);
    pos.setChooser(*this);
    return pos;
}

inline PresetIterator PresetChooser::begin(unsigned int index) const{
    PresetIterator pos(index);
    pos.setChooser(*this);
    return pos;
}

inline PresetIterator PresetChooser::end() const {
    PresetIterator pos(_presetLoader->size());
    pos.setChooser(*this);
    return pos;
}


inline bool PresetChooser::empty() const {
	return _presetLoader->size() == 0;
}

inline std::auto_ptr<Preset> PresetChooser::directoryIndex(std::size_t index) const {

	return _presetLoader->loadPreset(index);
}


inline PresetChooser::iterator PresetChooser::weightedRandom(bool hardCut) const {

	
	

	// TODO make a sophisticated function object interface to determine why a certain rating
	// category is chosen, or weighted distribution thereover.
	const PresetRatingType ratingType = hardCut || (!_softCutRatingsEnabled) ? 
		HARD_CUT_RATING_TYPE : SOFT_CUT_RATING_TYPE;		

	const std::size_t ratingsTypeIndex = static_cast<std::size_t>(ratingType);
	
	const std::vector<int> & weights = _presetLoader->getPresetRatings()[ratingsTypeIndex];

	const std::size_t index = RandomNumberGenerators::weightedRandom
		(weights,
		 _presetLoader->getPresetRatingsSums()[ratingsTypeIndex]);
	
	return begin(index);
}

#endif
