// Created on: 2020-01-25
// Created by: Natalia ERMOLAEVA
// Copyright (c) 2020 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement. 

#ifndef ViewControl_TableModelValues_H
#define ViewControl_TableModelValues_H

#include <Standard.hxx>

#include <inspector/TreeModel_HeaderSection.hxx>
#include <inspector/TreeModel_ItemProperties.hxx>
#include <inspector/ViewControl_EditType.hxx>

#include <Standard_WarningsDisable.hxx>
#include <QAbstractTableModel>
#include <QColor>
#include <QList>
#include <QModelIndexList>
#include <QVariant>
#include <Standard_WarningsRestore.hxx>

//! \class ViewControl_TableModelValues
//! \brief This is an interface for ViewControl_TableModel to give real values of the model
//! It should be filled or redefined.
class ViewControl_TableModelValues
{
public:

  //! Constructor
  ViewControl_TableModelValues (const Qt::Orientation& theOrientation = Qt::Vertical) { SetOrientation (theOrientation); }

  //! Destructor
  virtual ~ViewControl_TableModelValues() {}

  //! Returns item table properties builder
  const Handle(TreeModel_ItemProperties)& Properties() const { return myProperties; }

  //! Sets item table properties builder
  void SetProperties (const Handle(TreeModel_ItemProperties)& theProperties) { myProperties = theProperties; }

  //! Sets direction of the values applying, whether it should be placed by rows or by columns
  //! \param theOrientation if horizontal, the values are applied by rows, otherwise by columns
  void SetOrientation (const Qt::Orientation& theOrientation) { myOrientation = theOrientation; }

  //! Fills the model header values for orientation.
  //! \param theValues a container of header text values
  //! \param theOrientation an orientation of header
  void SetHeaderValues (const QList<TreeModel_HeaderSection>& theValues, const Qt::Orientation theOrientation)
  { myHeaderValues.insert (theOrientation, theValues); }

  //! Returns whether the column is hidden by default
  //! \param theColumnId a column index
  //! \return header section values container
  TreeModel_HeaderSection HeaderItem (const Qt::Orientation theOrientation, const int theColumnId) const
  { return myHeaderValues.contains(theOrientation) ? myHeaderValues[theOrientation][theColumnId] : TreeModel_HeaderSection(); }

  //! Stores information about table view header visibility
  //! \param theOrientation an orientation of header
  //! \param theVisibility if true, header is visible
  void SetHeaderVisible (const Qt::Orientation theOrientation, const bool theVisibility)
  { myVisibleHeader.insert (theOrientation, theVisibility); }

  //! Stores information about table view header visibility
  //! \param theOrientation an orientation of header
  //! \param theVisibility if true, header is visible
  bool IsHeaderVisible (const Qt::Orientation theOrientation) const
  { return myVisibleHeader.contains(theOrientation) ? myVisibleHeader[theOrientation] : true; }

  //! Get default section size if defined
  //! \param theOrientation an orientation of header
  //! \param theVisibility if true, header is visible
  bool DefaultSectionSize (const Qt::Orientation theOrientation, int& theSectionSize)
  {
    theSectionSize = myDefaultSectionSize.contains (theOrientation) ? myDefaultSectionSize[theOrientation] : -1;
    return myDefaultSectionSize.contains (theOrientation);
  }

  //! Set default section size if defined
  //! \param theOrientation an orientation of header
  //! \param theVisibility if true, header is visible
  void SetDefaultSectionSize (const Qt::Orientation theOrientation, const int& theSectionSize)
  { myDefaultSectionSize.insert(theOrientation, theSectionSize); }

  //! Returns number of columns, size of header values
  //! \param theParent an index of the parent item
  //! \return an integer value
  Standard_EXPORT virtual int ColumnCount (const QModelIndex& theParent = QModelIndex()) const;

  //! Returns number of rows, depending on orientation: myColumnCount or size of values container
  //! \param theParent an index of the parent item
  //! \return an integer value
  Standard_EXPORT virtual int RowCount (const QModelIndex& theParent = QModelIndex()) const;

  //! Returns content of the model index for the given role, it is obtained from internal container of values
  //! It returns value only for DisplayRole.
  //! \param theRow a model index row
  //! \param theColumn a model index column
  //! \param theRole a view role
  //! \return value interpreted depending on the given role
  Standard_EXPORT virtual QVariant Data (const int theRow, const int theColumn, int theRole = Qt::DisplayRole) const;

  //! Sets content of the model index for the given role, it is applied to internal container of values
  //! \param theRow a model index row
  //! \param theColumn a model index column
  //! \param theRole a view role
  //! \return true if the value is changed
  Standard_EXPORT virtual bool SetData (const int theRow, const int theColumn, const QVariant& theValue,
                                        int theRole = Qt::DisplayRole);

  //! Returns content of the model index for the given role, it is obtainer from internal container of header values
  //! It returns value only for DisplayRole.
  //! \param theSection an index of value in the container 
  //! \param theIndex a model index
  //! \param theRole a view role
  //! \return value interpreted depending on the given role
  Standard_EXPORT virtual QVariant HeaderData (int theSection, Qt::Orientation theOrientation, int theRole = Qt::DisplayRole) const;

  //! Returns flags for the item: ItemIsEnabled | Qt::ItemIsSelectable
  //! \param theIndex a model index
  //! \return flags
  Standard_EXPORT virtual Qt::ItemFlags Flags (const QModelIndex& theIndex) const;

  //! Returns type of edit control for the model index. By default, it is an empty control
  //! \param theRow a model index row
  //! \param theColumn a model index column
  //! \return edit type
  Standard_EXPORT virtual ViewControl_EditType EditType (const int theRow, const int theColumn) const;

  //! Returns default color for editable cell
  //! \return color value
  static QColor EditCellColor() { return QColor (Qt::darkBlue); }

protected:
  //! Returns true if the header item is italic of the parameter index
  //! \param theRow a model index row
  //! \param theColumn a model index column
  //! \param boolean value
  bool isItalicHeader (const int theRow, const int theColumn) const;

protected:

  Qt::Orientation myOrientation; //!< orientation how the values should fill the current table view
  QMap<Qt::Orientation, QList<TreeModel_HeaderSection> > myHeaderValues; //!< table header values
  QMap<Qt::Orientation, bool> myVisibleHeader; //!< table header visibility
  QMap<Qt::Orientation, int> myDefaultSectionSize; //!< table section default size

  Handle(TreeModel_ItemProperties) myProperties; //!< item properties
};

#endif