/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the QtWidgets module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL21$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 or version 3 as published by the Free
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
** following information to ensure the GNU Lesser General Public License
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** As a special exception, The Qt Company gives you certain additional
** rights. These rights are described in The Qt Company LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#ifndef QHEADERVIEW_P_H
#define QHEADERVIEW_P_H

//
//  W A R N I N G
//  -------------
//
// This file is not part of the Qt API.  It exists purely as an
// implementation detail.  This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//

#include "private/qabstractitemview_p.h"

#ifndef QT_NO_ITEMVIEWS

#include "QtCore/qbitarray.h"
#include "QtWidgets/qapplication.h"
#include "QtWidgets/qlabel.h"

QT_BEGIN_NAMESPACE

class QHeaderViewPrivate: public QAbstractItemViewPrivate
{
    Q_DECLARE_PUBLIC(QHeaderView)

public:
    enum StateVersion { VersionMarker = 0xff };

    QHeaderViewPrivate()
        : state(NoState),
          offset(0),
          sortIndicatorOrder(Qt::DescendingOrder),
          sortIndicatorSection(0),
          sortIndicatorShown(false),
          lastPos(-1),
          firstPos(-1),
          originalSize(-1),
          section(-1),
          target(-1),
          pressed(-1),
          hover(-1),
          length(0),
          preventCursorChangeInSetOffset(false),
          movableSections(false),
          clickableSections(false),
          highlightSelected(false),
          stretchLastSection(false),
          cascadingResizing(false),
          resizeRecursionBlock(false),
          allowUserMoveOfSection0(true), // will be false for QTreeView and true for QTableView
          customDefaultSectionSize(false),
          stretchSections(0),
          contentsSections(0),
          minimumSectionSize(-1),
          maximumSectionSize(-1),
          lastSectionSize(0),
          sectionIndicatorOffset(0),
          sectionIndicator(0),
          globalResizeMode(QHeaderView::Interactive),
          sectionStartposRecalc(true),
          resizeContentsPrecision(1000)
    {}


    int lastVisibleVisualIndex() const;
    int sectionHandleAt(int position);
    void setupSectionIndicator(int section, int position);
    void updateSectionIndicator(int section, int position);
    void updateHiddenSections(int logicalFirst, int logicalLast);
    void resizeSections(QHeaderView::ResizeMode globalMode, bool useGlobalMode = false);
    void _q_sectionsRemoved(const QModelIndex &,int,int);
    void _q_layoutAboutToBeChanged();
    void _q_layoutChanged();

    bool isSectionSelected(int section) const;
    bool isFirstVisibleSection(int section) const;
    bool isLastVisibleSection(int section) const;

    inline bool rowIntersectsSelection(int row) const {
        return (selectionModel ? selectionModel->rowIntersectsSelection(row, root) : false);
    }

    inline bool columnIntersectsSelection(int column) const {
        return (selectionModel ? selectionModel->columnIntersectsSelection(column, root) : false);
    }

    inline bool sectionIntersectsSelection(int logical) const {
        return (orientation == Qt::Horizontal ? columnIntersectsSelection(logical) : rowIntersectsSelection(logical));
    }

    inline bool isRowSelected(int row) const {
        return (selectionModel ? selectionModel->isRowSelected(row, root) : false);
    }

    inline bool isColumnSelected(int column) const {
        return (selectionModel ? selectionModel->isColumnSelected(column, root) : false);
    }

    inline void prepareSectionSelected() {
        if (!selectionModel || !selectionModel->hasSelection())
            sectionSelected.clear();
        else if (sectionSelected.count() != sectionCount() * 2)
            sectionSelected.fill(false, sectionCount() * 2);
        else sectionSelected.fill(false);
    }

    inline int sectionCount() const {return sectionItems.count();}

    inline bool reverse() const {
        return orientation == Qt::Horizontal && q_func()->isRightToLeft();
    }

    inline int logicalIndex(int visualIndex) const {
        return logicalIndices.isEmpty() ? visualIndex : logicalIndices.at(visualIndex);
    }

    inline int visualIndex(int logicalIndex) const {
        return visualIndices.isEmpty() ? logicalIndex : visualIndices.at(logicalIndex);
    }

    inline void setDefaultValues(Qt::Orientation o) {
        orientation = o;
        updateDefaultSectionSizeFromStyle();
        defaultAlignment = (o == Qt::Horizontal
                            ? Qt::Alignment(Qt::AlignCenter)
                            : Qt::AlignLeft|Qt::AlignVCenter);
    }

    inline bool isVisualIndexHidden(int visual) const {
        return sectionItems.at(visual).isHidden;
    }

    inline void setVisualIndexHidden(int visual, bool hidden) {
        sectionItems[visual].isHidden = hidden;
    }

    inline bool hasAutoResizeSections() const {
        return stretchSections || stretchLastSection || contentsSections;
    }

    QStyleOptionHeader getStyleOption() const;

    inline void invalidateCachedSizeHint() const {
        cachedSizeHint = QSize();
    }

    inline void initializeIndexMapping() const {
        if (visualIndices.count() != sectionCount()
            || logicalIndices.count() != sectionCount()) {
            visualIndices.resize(sectionCount());
            logicalIndices.resize(sectionCount());
            for (int s = 0; s < sectionCount(); ++s) {
                visualIndices[s] = s;
                logicalIndices[s] = s;
            }
        }
    }

    inline void clearCascadingSections() {
        firstCascadingSection = sectionItems.count();
        lastCascadingSection = 0;
        cascadingSectionSize.clear();
    }

    inline void saveCascadingSectionSize(int visual, int size) {
        if (!cascadingSectionSize.contains(visual)) {
            cascadingSectionSize.insert(visual, size);
            firstCascadingSection = qMin(firstCascadingSection, visual);
            lastCascadingSection = qMax(lastCascadingSection, visual);
        }
    }

    inline bool sectionIsCascadable(int visual) const {
        return headerSectionResizeMode(visual) == QHeaderView::Interactive;
    }

    inline int modelSectionCount() const {
        return (orientation == Qt::Horizontal
                ? model->columnCount(root)
                : model->rowCount(root));
    }

    inline bool modelIsEmpty() const {
        return (model->rowCount(root) == 0 || model->columnCount(root) == 0);
    }

    inline void doDelayedResizeSections() {
        if (!delayedResize.isActive())
            delayedResize.start(0, q_func());
    }

    inline void executePostedResize() const {
        if (delayedResize.isActive() && state == NoState) {
            const_cast<QHeaderView*>(q_func())->resizeSections();
        }
    }

    inline void setAllowUserMoveOfSection0(bool b) {
        allowUserMoveOfSection0 = b;
    }

    void clear();
    void flipSortIndicator(int section);
    void cascadingResize(int visual, int newSize);

    enum State { NoState, ResizeSection, MoveSection, SelectSections, NoClear } state;

    int offset;
    Qt::Orientation orientation;
    Qt::SortOrder sortIndicatorOrder;
    int sortIndicatorSection;
    bool sortIndicatorShown;

    mutable QVector<int> visualIndices; // visualIndex = visualIndices.at(logicalIndex)
    mutable QVector<int> logicalIndices; // logicalIndex = row or column in the model
    mutable QBitArray sectionSelected; // from logical index to bit
    mutable QHash<int, int> hiddenSectionSize; // from logical index to section size
    mutable QHash<int, int> cascadingSectionSize; // from visual index to section size
    mutable QSize cachedSizeHint;
    mutable QBasicTimer delayedResize;

    int firstCascadingSection;
    int lastCascadingSection;

    int lastPos;
    int firstPos;
    int originalSize;
    int section; // used for resizing and moving sections
    int target;
    int pressed;
    int hover;

    int length;
    bool preventCursorChangeInSetOffset;
    bool movableSections;
    bool clickableSections;
    bool highlightSelected;
    bool stretchLastSection;
    bool cascadingResizing;
    bool resizeRecursionBlock;
    bool allowUserMoveOfSection0;
    bool customDefaultSectionSize;
    int stretchSections;
    int contentsSections;
    int defaultSectionSize;
    int minimumSectionSize;
    int maximumSectionSize;
    int lastSectionSize; // $$$
    int sectionIndicatorOffset;
    Qt::Alignment defaultAlignment;
    QLabel *sectionIndicator;
    QHeaderView::ResizeMode globalResizeMode;
    QList<QPersistentModelIndex> persistentHiddenSections;
    mutable bool sectionStartposRecalc;
    int resizeContentsPrecision;
    // header sections

    struct SectionItem {
        uint size : 20;
        uint isHidden : 1;
        uint resizeMode : 5;  // (holding QHeaderView::ResizeMode)
        uint currentlyUnusedPadding : 6;

        union { // This union is made in order to save space and ensure good vector performance (on remove)
            mutable int calculated_startpos; // <- this is the primary used member.
            mutable int tmpLogIdx;         // When one of these 'tmp'-members has been used we call
            int tmpDataStreamSectionCount; // recalcSectionStartPos() or set sectionStartposRecalc to true
        };                                 // to ensure that calculated_startpos will be calculated afterwards.

        inline SectionItem() : size(0), isHidden(0), resizeMode(QHeaderView::Interactive) {}
        inline SectionItem(int length, QHeaderView::ResizeMode mode)
            : size(length), isHidden(0), resizeMode(mode), calculated_startpos(-1) {}
        inline int sectionSize() const { return size; }
        inline int calculatedEndPos() const { return calculated_startpos + size; }
#ifndef QT_NO_DATASTREAM
        inline void write(QDataStream &out) const
        { out << static_cast<int>(size); out << 1; out << (int)resizeMode; }
        inline void read(QDataStream &in)
        { int m; in >> m; size = m; in >> tmpDataStreamSectionCount; in >> m; resizeMode = m; }
#endif
    };

    QVector<SectionItem> sectionItems;

    void createSectionItems(int start, int end, int size, QHeaderView::ResizeMode mode);
    void removeSectionsFromSectionItems(int start, int end);
    void resizeSectionItem(int visualIndex, int oldSize, int newSize);
    void setDefaultSectionSize(int size);
    void updateDefaultSectionSizeFromStyle();
    void recalcSectionStartPos() const; // not really const

    inline int headerLength() const { // for debugging
        int len = 0;
        for (int i = 0; i < sectionItems.count(); ++i)
            len += sectionItems.at(i).size;
        return len;
    }

    QBitArray sectionsHiddenToBitVector() const
    {
        QBitArray sectionHidden;
        if (!hiddenSectionSize.isEmpty()) {
            sectionHidden.resize(sectionItems.size());
            for (int u = 0; u < sectionItems.size(); ++u)
                sectionHidden[u] = sectionItems.at(u).isHidden;
        }
        return sectionHidden;
    }

    void setHiddenSectionsFromBitVector(const QBitArray &sectionHidden) {
        SectionItem *sectionData = sectionItems.data();
        for (int i = 0; i < sectionHidden.count(); ++i)
            sectionData[i].isHidden = sectionHidden.at(i);
    }

    int headerSectionSize(int visual) const;
    int headerSectionPosition(int visual) const;
    int headerVisualIndexAt(int position) const;

    // resize mode
    void setHeaderSectionResizeMode(int visual, QHeaderView::ResizeMode mode);
    QHeaderView::ResizeMode headerSectionResizeMode(int visual) const;
    void setGlobalHeaderResizeMode(QHeaderView::ResizeMode mode);

    // other
    int viewSectionSizeHint(int logical) const;
    int adjustedVisualIndex(int visualIndex) const;
    void setScrollOffset(const QScrollBar *scrollBar, QAbstractItemView::ScrollMode scrollMode);

#ifndef QT_NO_DATASTREAM
    void write(QDataStream &out) const;
    bool read(QDataStream &in);
#endif

};

QT_END_NAMESPACE

#endif // QT_NO_ITEMVIEWS

#endif // QHEADERVIEW_P_H
