/**************************************************************
 * 
 * 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 implemnt
        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 cooordinate 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 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
