/*
 * OutputDriver.h
 *
 *  Created on: Aug 2, 2018
 *      Author: Andreas Schneider, Johannes Wendel, Jonas Zeunert
 */

#ifndef _SRC_OUTPUT_IOUTPUTDRIVER_H_
#define _SRC_OUTPUT_IOUTPUTDRIVER_H_

#include <vector>
#include <memory>
#include <map>

#include <boost/optional.hpp>

#include "output/DisplayController.h"

#include "output/items/Solenoid.h"
#include "output/items/Lamp.h"
#include "output/items/Sound.h"
#include "output/items/Display.h"
#include "output/items/Flipper.h"


namespace flippR_driver
{
namespace output
{

class OutputDriver
{
public:
  OutputDriver(std::shared_ptr<output::DisplayController> display_controller, std::map<std::string, std::shared_ptr<items::Solenoid>> solenoids,
               std::map<std::string, std::shared_ptr<items::Lamp>> lamps, std::map<std::string, std::shared_ptr<items::Sound>> sounds,
               std::map<std::string, std::shared_ptr<items::Flipper>> flippers, std::map<std::string, std::shared_ptr<output::items::Display>> displays);

  ~OutputDriver() = default;

  void activate_displays() const;
  void deactivate_displays() const;
  void rotate_displays() const;

  void activate_all_lamps() const;
  void deactivate_all_lamps() const;
  void rotate_all_lamps() const;

  void activate_all_flipper_relays() const;
  void deactivate_all_flipper_relays() const;

  void shut_down_driver() const;

  // todo driver board run for activate/deactivate?
  // todo what is flipper_relay ?
  std::vector<std::shared_ptr<items::Lamp>> get_lamps() const;
  std::vector<std::shared_ptr<items::Solenoid>> get_solenoids() const;
  std::vector<std::shared_ptr<items::Sound>> get_sounds() const;
  std::vector<std::shared_ptr<items::Flipper>> get_flippers() const;
  std::vector<std::shared_ptr<items::Display>> get_displays() const;

  boost::optional<std::shared_ptr<items::Lamp>> get_lamp(const std::string &name) const;
  boost::optional<std::shared_ptr<items::Solenoid>> get_solenoid(const std::string &name) const;
  boost::optional<std::shared_ptr<items::Sound>> get_sound(const std::string &name) const;
  boost::optional<std::shared_ptr<items::Flipper>> get_flipper(const std::string &name) const;
  boost::optional<std::shared_ptr<items::Display>> get_display(const std::string &name) const;

private:
  std::shared_ptr<output::DisplayController> display_controller;

  const std::map<std::string, std::shared_ptr<items::Lamp>> lamps;
  const std::map<std::string, std::shared_ptr<items::Solenoid>> solenoids;
  const std::map<std::string, std::shared_ptr<items::Sound>> sounds;
  const std::map<std::string, std::shared_ptr<items::Flipper>> flippers;
  const std::map<std::string, std::shared_ptr<items::Display>> displays;
};

} /* namespace output */
}
#endif