#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
