/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



#ifndef SVTOOLS_TABLECONTROL_IMPL_HXX
#define SVTOOLS_TABLECONTROL_IMPL_HXX

#include "svtools/table/tablemodel.hxx"
#include "svtools/table/tablecontrolinterface.hxx"

#include "svtaccessiblefactory.hxx"

#include <vcl/seleng.hxx>

#include <vector>

#include <boost/scoped_ptr.hpp>

class ScrollBar;
class ScrollBarBox;

//........................................................................
namespace svt { namespace table
{
//........................................................................

    struct MutableColumnMetrics : protected ColumnMetrics
    {
        MutableColumnMetrics()
            :ColumnMetrics()
        {
        }

        MutableColumnMetrics( long const i_startPixel, long const i_endPixel )
            :ColumnMetrics( i_startPixel, i_endPixel )
        {
        }

        long getStart() const { return nStartPixel; }
        long getEnd() const { return nEndPixel; }

        void setEnd( long const i_end ) { nEndPixel = i_end; }
        void move( long const i_offset ) { nStartPixel += i_offset; nEndPixel += i_offset; }

        long getWidth() const { return nEndPixel - nStartPixel; }

        ColumnMetrics const & operator()() { return *this; }
    };

    struct ColumnInfoPositionLess
    {
        bool operator()( MutableColumnMetrics const& i_colInfo, long const i_position )
        {
            return i_colInfo.getEnd() < i_position;
        }
        bool operator()( long const i_position, MutableColumnMetrics const& i_colInfo )
        {
            return i_position < i_colInfo.getStart();
        }
    };

    typedef ::std::vector< MutableColumnMetrics >    ColumnPositions;

    class TableControl;
    class TableDataWindow;
    class TableFunctionSet;

    //====================================================================
	//= TableControl_Impl
	//====================================================================
    class TableControl_Impl :public ITableControl
                            ,public ITableModelListener
    {
        friend class TableGeometry;
        friend class TableRowGeometry;
        friend class TableColumnGeometry;
        friend class SuspendInvariants;

    private:
        /// the control whose impl-instance we implement
        TableControl&       	m_rAntiImpl;
        /// the model of the table control
        PTableModel         	m_pModel;
        /// the input handler to use, usually the input handler as provided by ->m_pModel
        PTableInputHandler  	m_pInputHandler;
        /// info about the widths of our columns
        ColumnPositions         m_aColumnWidths;

        /// the height of a single row in the table, measured in pixels
        long                	m_nRowHeightPixel;
        /// the height of the column header row in the table, measured in pixels
        long                	m_nColHeaderHeightPixel;
        /// the width of the row header column in the table, measured in pixels
        long                	m_nRowHeaderWidthPixel;

        /// the number of columns in the table control. Cached model value.
        TableSize           	m_nColumnCount;

        /// the number of rows in the table control. Cached model value.
        TableSize           	m_nRowCount;

        /// denotes whether or not the columns fitted into the available width, last time we checked
        long                    m_bColumnsFit;

        ColPos              	m_nCurColumn;
        RowPos              	m_nCurRow;
        ColPos              	m_nLeftColumn;
        RowPos              	m_nTopRow;

        sal_Int32           	m_nCursorHidden;

        /** the window to contain all data content, including header bars

            The window's upper left corner is at position (0,0), relative to the
            table control, which is the direct parent of the data window.
        */
        ::boost::scoped_ptr< TableDataWindow >
                                m_pDataWindow;
        /// the vertical scrollbar, if any
        ScrollBar*          	m_pVScroll;
        /// the horizontal scrollbar, if any
        ScrollBar*              m_pHScroll;
        ScrollBarBox*       	m_pScrollCorner;
	    //selection engine - for determining selection range, e.g. single, multiple
	    SelectionEngine*    	m_pSelEngine;
	    //vector which contains the selected rows
	    std::vector<RowPos> 	m_aSelectedRows;
	    //part of selection engine
	    TableFunctionSet*   	m_pTableFunctionSet;
	    //part of selection engine
	    RowPos		    	    m_nAnchor;
        bool                    m_bUpdatingColWidths;

    	Link                    m_aSelectHdl;

	    AccessibleFactoryAccess     m_aFactoryAccess;
	    IAccessibleTableControl*    m_pAccessibleTable;

#if DBG_UTIL
    #define INV_SCROLL_POSITION     1
        /** represents a bitmask of invariants to check

            Actually, impl_checkInvariants checks more invariants than denoted in this
            bit mask, but only those present here can be disabled temporarily.
        */
        sal_Int32           m_nRequiredInvariants;
#endif

    public:
        void        setModel( PTableModel _pModel );

        inline  const PTableInputHandler&   getInputHandler() const { return m_pInputHandler; }

		inline	RowPos  getCurRow() const           { return m_nCurRow; }
		inline	void	setCurRow( RowPos i_curRow ){ m_nCurRow = i_curRow; }

        RowPos  getAnchor() const { return m_nAnchor; }
        void    setAnchor( RowPos const i_anchor ) { m_nAnchor = i_anchor; }

        inline  RowPos  getTopRow() const       { return m_nTopRow; }
        inline  ColPos  getLeftColumn() const { return m_nLeftColumn; }

        inline  const TableControl&   getAntiImpl() const { return m_rAntiImpl; }
        inline        TableControl&   getAntiImpl()       { return m_rAntiImpl; }

    public:
        TableControl_Impl( TableControl& _rAntiImpl );
        ~TableControl_Impl();

#if DBG_UTIL
        const sal_Char* impl_checkInvariants() const;
#endif
        /** to be called when the anti-impl instance has been resized
        */
        void    onResize();

        /** paints the table control content which intersects with the given rectangle
        */
        void    doPaintContent( const Rectangle& _rUpdateRect );

        /** moves the cursor to the cell with the given coordinates

            To ease the caller's code, the coordinates must not necessarily denote a
            valid position. If they don't, <FALSE/> will be returned.
        */
        bool    goTo( ColPos _nColumn, RowPos _nRow );

        /** ensures that the given coordinate is visible
            @param _nColumn
                the column position which should be visible. Must be non-negative, and smaller
                than the column count.
            @param _nRow
                the row position which should be visibleMust be non-negative, and smaller
                than the row count.
            @param _bAcceptPartialVisibility
                <TRUE/> if it's okay that the given coordinate is only partially visible
        */
        void    ensureVisible( ColPos _nColumn, RowPos _nRow, bool _bAcceptPartialVisibility );

        /** retrieves the content of the given cell, converted to a string
        */
        ::rtl::OUString getCellContentAsString( RowPos const i_row, ColPos const i_col );

        /** returns the position of the current row in the selection vector */
	    int	getRowSelectedNumber(const ::std::vector<RowPos>& selectedRows, RowPos current);

        /** ??? */
	    void    invalidateSelectedRegion( RowPos _nPrevRow, RowPos _nCurRow );

        /** invalidates the part of the data window which is covered by the given rows
            @param i_firstRow
                the index of the first row to include in the invalidation
            @param i_lastRow
                the index of the last row to include in the invalidation, or ROW_INVALID if the invalidation
                should happen down to the bottom of the data window.
        */
        void    invalidateRowRange( RowPos const i_firstRow, RowPos const i_lastRow );

        /** invalidates the part of the data window which is covered by the given row
        */
        void    invalidateRow( RowPos const i_row ) { invalidateRowRange( i_row, i_row ); }

        /** invalidates all selected rows
        */
        void    invalidateSelectedRows();

	    void    checkCursorPosition();

        bool    hasRowSelection() const { return !m_aSelectedRows.empty(); }
        size_t  getSelectedRowCount() const { return m_aSelectedRows.size(); }
        RowPos  getSelectedRowIndex( size_t const i_selectionIndex ) const;

        /** removes the given row index from m_aSelectedRows

            @return
                <TRUE/> if and only if the row was previously marked as selected
        */
        bool        markRowAsDeselected( RowPos const i_rowIndex );

        /** marks the given row as selectged, by putting it into m_aSelectedRows
            @return
                <TRUE/> if and only if the row was previously <em>not</em> marked as selected
        */
        bool        markRowAsSelected( RowPos const i_rowIndex );

        /** marks all rows as deselected
            @return
                <TRUE/> if and only if the selection actually changed by this operation
        */
        bool        markAllRowsAsDeselected();

        /** marks all rows as selected
            @return
                <FALSE/> if and only if all rows were selected already.
        */
        bool        markAllRowsAsSelected();

        void        setSelectHandler( Link const & i_selectHandler ) { m_aSelectHdl = i_selectHandler; }
        Link const& getSelectHandler() const { return m_aSelectHdl; }

        void commitAccessibleEvent( sal_Int16 const i_eventID, const com::sun::star::uno::Any& i_newValue, const com::sun::star::uno::Any& i_oldValue );
        void commitCellEvent( sal_Int16 const i_eventID, const com::sun::star::uno::Any& i_newValue, const com::sun::star::uno::Any& i_oldValue );
        void commitTableEvent( sal_Int16 const i_eventID, const com::sun::star::uno::Any& i_newValue, const com::sun::star::uno::Any& i_oldValue );

        // ITableControl
        virtual void                hideCursor();
        virtual void                showCursor();
        virtual bool                dispatchAction( TableControlAction _eAction );
	    virtual SelectionEngine*    getSelEngine();
        virtual PTableModel         getModel() const;
        virtual ColPos              getCurrentColumn() const;
        virtual RowPos              getCurrentRow() const;
        virtual bool                activateCell( ColPos const i_col, RowPos const i_row );
        virtual ::Size              getTableSizePixel() const;
        virtual void                setPointer( Pointer const & i_pointer );
        virtual void                captureMouse();
        virtual void                releaseMouse();
        virtual void                invalidate( TableArea const i_what );
        virtual long                pixelWidthToAppFont( long const i_pixels ) const;
        virtual void                hideTracking();
        virtual void                showTracking( Rectangle const & i_location, sal_uInt16 const i_flags );
	    virtual RowPos	            getRowAtPoint( const Point& rPoint ) const;
        virtual ColPos              getColAtPoint( const Point& rPoint ) const;
        virtual TableCell           hitTest( const Point& rPoint ) const;
        virtual ColumnMetrics       getColumnMetrics( ColPos const i_column ) const;
	    virtual bool                isRowSelected( RowPos i_row ) const;


        long                        appFontWidthToPixel( long const i_appFontUnits ) const;

        TableDataWindow&        getDataWindow()       { return *m_pDataWindow; }
        const TableDataWindow&  getDataWindow() const { return *m_pDataWindow; }
	    ScrollBar* getHorzScrollbar();
	    ScrollBar* getVertScrollbar();

	    Rectangle calcHeaderRect( bool bColHeader );
        Rectangle calcHeaderCellRect( bool bColHeader, sal_Int32 nPos );
	    Rectangle calcTableRect();
        Rectangle calcCellRect( sal_Int32 nRow, sal_Int32 nCol );

        // A11Y
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
                        getAccessible( Window& i_parentWindow );
        void            disposeAccessible();

        inline bool     isAccessibleAlive() const { return impl_isAccessibleAlive(); }

        // ITableModelListener
        virtual void    rowsInserted( RowPos first, RowPos last );
        virtual void    rowsRemoved( RowPos first, RowPos last );
        virtual void    columnInserted( ColPos const i_colIndex );
        virtual void    columnRemoved( ColPos const i_colIndex );
        virtual void    allColumnsRemoved();
        virtual void    cellsUpdated( ColPos const i_firstCol, ColPos i_lastCol, RowPos const i_firstRow, RowPos const i_lastRow );
        virtual void    columnChanged( ColPos const i_column, ColumnAttributeGroup const i_attributeGroup );
        virtual void    tableMetricsChanged();

    private:
        bool            impl_isAccessibleAlive() const;
        void            impl_commitAccessibleEvent(
                            sal_Int16 const i_eventID,
                            ::com::sun::star::uno::Any const & i_newValue,
                            ::com::sun::star::uno::Any const & i_oldValue
                        );

        /** toggles the cursor visibility

            The method is not bound to the classes public invariants, as it's used in
            situations where the they must not necessarily be fullfilled.
        */
        void        impl_ni_doSwitchCursor( bool _bOn );

        /** returns the number of visible rows.

            @param _bAcceptPartialRow
                specifies whether a possible only partially visible last row is
                counted, too.
        */
        TableSize   impl_getVisibleRows( bool _bAcceptPartialRow ) const;

        /** returns the number of visible columns

            The value may change with different horizontal scroll positions, as
            different columns have different widths. For instance, if your control is
            100 pixels wide, and has three columns of width 50, 50, 100, respectively,
            then this method will return either "2" or "1", depending on which column
            is the first visible one.

            @param _bAcceptPartialRow
                specifies whether a possible only partially visible last row is
                counted, too.
        */
        TableSize   impl_getVisibleColumns( bool _bAcceptPartialCol ) const;

        /** determines the rectangle occupied by the given cell
        */
        void        impl_getCellRect( ColPos _nColumn, RowPos _nRow, Rectangle& _rCellRect ) const;

        /** updates all cached model values

            The method is not bound to the classes public invariants, as it's used in
            situations where the they must not necessarily be fullfilled.
        */
        void        impl_ni_updateCachedModelValues();

        /** updates the cached table metrics (row height etc.)
        */
        void        impl_ni_updateCachedTableMetrics();

        /** does a relayout of the table control

            Column widths, and consequently the availability of the vertical and horizontal scrollbar, are updated
            with a call to this method.

            @param i_assumeInflexibleColumnsUpToIncluding
                the index of a column up to which all columns should be considered as inflexible, or
                <code>COL_INVALID</code>.
        */
        void        impl_ni_relayout( ColPos const i_assumeInflexibleColumnsUpToIncluding = COL_INVALID );

        /** calculates the new width of our columns, taking into account their min and max widths, and their relative
            flexibility.

            @param i_assumeInflexibleColumnsUpToIncluding
                the index of a column up to which all columns should be considered as inflexible, or
                <code>COL_INVALID</code>.

            @param i_assumeVerticalScrollbar
                controls whether or not we should assume the presence of a vertical scrollbar. If <true/>, and
                if the model has a VerticalScrollbarVisibility != ScrollbarShowNever, the method will leave
                space for a vertical scrollbar.

            @return
                the overall width of the grid, which is available for columns
        */
        long        impl_ni_calculateColumnWidths(
                        ColPos const i_assumeInflexibleColumnsUpToIncluding,
                        bool const i_assumeVerticalScrollbar,
                        ::std::vector< long >& o_newColWidthsPixel
                    ) const;

        /** positions all child windows, e.g. the both scrollbars, the corner window, and the data window
        */
        void        impl_ni_positionChildWindows(
                        Rectangle const & i_dataCellPlayground,
                        bool const i_verticalScrollbar,
                        bool const i_horizontalScrollbar
                    );

        /** scrolls the view by the given number of rows

            The method is not bound to the classes public invariants, as it's used in
            situations where the they must not necessarily be fullfilled.

            @return
                the number of rows by which the viewport was scrolled. This may differ
                from the given numbers to scroll in case the begin or the end of the
                row range were reached.
        */
        TableSize   impl_ni_ScrollRows( TableSize _nRowDelta );

        /** equivalent to impl_ni_ScrollRows, but checks the instances invariants beforehand (in a non-product build only)
        */
        TableSize   impl_scrollRows( TableSize const i_rowDelta );

        /** scrolls the view by the given number of columns

            The method is not bound to the classes public invariants, as it's used in
            situations where the they must not necessarily be fullfilled.

            @return
                the number of columns by which the viewport was scrolled. This may differ
                from the given numbers to scroll in case the begin or the end of the
                column range were reached.
        */
        TableSize   impl_ni_ScrollColumns( TableSize _nColumnDelta );

        /** equivalent to impl_ni_ScrollColumns, but checks the instances invariants beforehand (in a non-product build only)
        */
        TableSize   impl_scrollColumns( TableSize const i_columnDelta );

        /** retrieves the area occupied by the totality of (at least partially) visible cells

            The returned area includes row and column headers. Also, it takes into
            account the fact that there might be less columns than would normally
            find room in the control.

            As a result of respecting the partial visibility of rows and columns,
            the returned area might be larger than the data window's output size.
        */
        Rectangle   impl_getAllVisibleCellsArea() const;

        /** retrieves the area occupied by all (at least partially) visible data cells.

            Effectively, the returned area is the same as returned by ->impl_getAllVisibleCellsArea,
            minus the row and column header areas.
        */
        Rectangle   impl_getAllVisibleDataCellArea() const;

        /** retrieves the column which covers the given ordinate
        */
        ColPos      impl_getColumnForOrdinate( long const i_ordinate ) const;

        /** retrieves the row which covers the given abscissa
        */
        RowPos      impl_getRowForAbscissa( long const i_abscissa ) const;

        /// invalidates the window area occupied by the given column
        void        impl_invalidateColumn( ColPos const i_column );

        DECL_LINK( OnScroll, ScrollBar* );
        DECL_LINK( OnUpdateScrollbars, void* );
    };

	//see seleng.hxx, seleng.cxx, FunctionSet overridables, part of selection engine
	class TableFunctionSet : public FunctionSet
	{
	private:
		TableControl_Impl*  m_pTableControl;
		RowPos              m_nCurrentRow;

	public:
		TableFunctionSet(TableControl_Impl* _pTableControl);
		virtual ~TableFunctionSet();

	   virtual void BeginDrag();
	   virtual void CreateAnchor();
	   virtual void DestroyAnchor();
	   virtual sal_Bool SetCursorAtPoint(const Point& rPoint, sal_Bool bDontSelectAtCursor);
	   virtual sal_Bool IsSelectionAtPoint( const Point& rPoint );
	   virtual void DeselectAtPoint( const Point& rPoint );
	   virtual void DeselectAll();
	};


//........................................................................
} } // namespace svt::table
//........................................................................

#endif // SVTOOLS_TABLECONTROL_IMPL_HXX
