/* Blinker
   Copyright 2011-2019 Stefan Schuermans <stefan@blinkenarea.org>
   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
   a blinkenarea.org project */

#ifndef BLINKER_PRIORITY_H
#define BLINKER_PRIORITY_H

#include <list>
#include <string>

#include <BlinkenLib/BlinkenFrame.h>

#include "Directory.h"
#include "File.h"
#include "ListTracker.h"
#include "Mgrs.h"
#include "Module.h"
#include "OutStreamFile.h"

namespace Blinker {

/// a priority based stream selector
class Priority: public Module
{
protected:
  /// input to priority based selector
  class Input;

  /// input list tracker
  typedef ListTracker<Priority, Input, Directory> InListTracker;

  /// input list iterator
  typedef InListTracker::ListRevIt InListIt;

public:
  /**
   * @brief constructor
   * @param[in] name module name
   * @param[in] mgrs managers
   * @param[in] dirBase base directory
   */
  Priority(const std::string &name, Mgrs &mgrs, const Directory &dirBase);

  /// virtual destructor
  virtual ~Priority();

private:
  /// copy constructor disabled
  Priority(const Priority &that);

  /// assignment operator disabled
  const Priority & operator=(const Priority &that);

public:
  /// check for update of configuration
  virtual void updateConfig();

protected:
  /**
   * @brief select specific input (called by inputs)
   * @param[in] input input to select
   */
  void select(const Input *pInput);

  /// select lower priority input (called by inputs)
  void selectLower();

  /// update current selection
  void updateSelection();

  /// send current frame to output stream
  void curFrame();

protected:
  OutStreamFile m_fileOutStream;  ///< output stream name file
  InListTracker m_inListTracker;  ///< input list tracker
  InListIt      m_itCurIn;        ///< current input
  bool          m_updateNeeded;   ///< additional update of selection needed
}; // class Priority

} // namespace Blinker

#endif // #ifndef BLINKER_PRIORITY_H

