// -*- C++ -*-
#ifndef Fireworks_Core_FWTableViewManager_h
#define Fireworks_Core_FWTableViewManager_h
//
// Package:     Core
// Class  :     FWTableViewManager
//
/**\class FWTableViewManager FWTableViewManager.h Fireworks/Core/interface/FWTableViewManager.h

   Description: Base class for a Manger for a specific type of View

   Usage:
   <usage>

*/
//
// Original Author:
//         Created:  Sat Jan  5 10:29:00 EST 2008
//

// system include files
#include <string>
#include <vector>
#include <set>
#include <map>
#include "FWCore/Reflection/interface/TypeWithDict.h"

// user include files

#include "Fireworks/Core/interface/FWViewManagerBase.h"
#include "Fireworks/Core/interface/FWTableView.h"
#include "Fireworks/Core/interface/FWConfigurable.h"

class FWViewBase;
class FWGUIManager;
class TEveWindowSlot;

class FWTableViewManager : public FWViewManagerBase, public FWConfigurable {
  friend class FWTableView;
  friend class FWTableViewTableManager;

public:
  struct TableEntry {
    enum { INT = 0, INT_HEX = -1, BOOL = -2 };
    std::string expression;
    std::string name;
    int precision;
  };

  /** Container for the event items which have a table. */
  typedef std::vector<const FWEventItem *> Items;
  /** Container for the description of the columns of a given table. */
  typedef std::vector<TableEntry> TableEntries;
  /** Type for the collection specific (i.e. those that do not use
       default) table definition. */
  typedef std::map<std::string, TableEntries> TableSpecs;

  FWTableViewManager(FWGUIManager *);
  ~FWTableViewManager() override;

  // ---------- const member functions ---------------------
  FWTypeToRepresentations supportedTypesAndRepresentations() const override;
  // ---------- static member functions --------------------

  // ---------- member functions ---------------------------
  void newItem(const FWEventItem *) override;
  void destroyItem(const FWEventItem *item);
  void removeAllItems(void);
  FWViewBase *buildView(TEveWindowSlot *iParent, const std::string &type);
  const Items &items() const { return m_items; }
  TableSpecs::iterator tableFormats(const edm::TypeWithDict &key);
  TableSpecs::iterator tableFormats(const TClass &key);
  void addTo(FWConfiguration &) const override;
  void addToImpl(FWConfiguration &) const;
  void setFrom(const FWConfiguration &) override;

  void notifyViews();

  static const std::string kConfigTypeNames;
  static const std::string kConfigColumns;

protected:
  FWTableViewManager();

  /** Called when models have changed and so the display must be updated. */
  void modelChangesComing() override;
  void modelChangesDone() override;
  void colorsChanged() override;
  void dataChanged();

  typedef std::vector<std::shared_ptr<FWTableView> > Views;

  Views m_views;
  Items m_items;
  TableSpecs m_tableFormats;

private:
  TableSpecs::iterator tableFormatsImpl(const edm::TypeWithDict &key);
  FWTableViewManager(const FWTableViewManager &);                   // stop default
  const FWTableViewManager &operator=(const FWTableViewManager &);  // stop default

  void beingDestroyed(const FWViewBase *);

  class TableHandle {
  public:
    TableHandle &column(const char *formula, int precision, const char *name);
    TableHandle &column(const char *label, int precision) { return column(label, precision, label); }

    TableHandle(const char *name, TableSpecs &specs) : m_name(name), m_specs(specs) { m_specs[name].clear(); }

  private:
    std::string m_name;
    TableSpecs &m_specs;
  };

  TableHandle table(const char *collection);
};

#endif
