/**************************************************************
 *
 * 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.
 *
 *************************************************************/



#include "precompiled_svtools.hxx"

#include "tabbargeometry.hxx"

#include <basegfx/range/b2drange.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <basegfx/numeric/ftools.hxx>

#include <vcl/window.hxx>

#include <algorithm>

// the width (or height, depending on alignment) of the scroll buttons
#define BUTTON_FLOW_WIDTH       20
// the space between the scroll buttons and the items
#define BUTTON_FLOW_SPACE       2
// outer space to apply between the tab bar borders and any content. Note that those refer to a "normalized" geometry,
// i.e. if the tab bar were aligned at the top
#define OUTER_SPACE_LEFT        2
#define OUTER_SPACE_TOP         4
#define OUTER_SPACE_RIGHT       4
#define OUTER_SPACE_BOTTOM      2

// outer space to apply between the area for the items, and the actual items. They refer to a normalized geometry.
#define ITEMS_INSET_LEFT        4
#define ITEMS_INSET_TOP         3
#define ITEMS_INSET_RIGHT       4
#define ITEMS_INSET_BOTTOM      0

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

	//==================================================================================================================
	//= helper
	//==================================================================================================================
    namespace
    {
	    //--------------------------------------------------------------------------------------------------------------
        static void lcl_transform( Rectangle& io_rRect, const ::basegfx::B2DHomMatrix& i_rTransformation )
        {
            ::basegfx::B2DRange aRect( io_rRect.Left(), io_rRect.Top(), io_rRect.Right(), io_rRect.Bottom() );
            aRect.transform( i_rTransformation );
            io_rRect.Left() = long( aRect.getMinX() );
            io_rRect.Top() = long( aRect.getMinY() );
            io_rRect.Right() = long( aRect.getMaxX() );
            io_rRect.Bottom() = long( aRect.getMaxY() );
        }

	    //--------------------------------------------------------------------------------------------------------------
        /** transforms the given, possible rotated playground,
        */
        void lcl_rotate( const Rectangle& i_rReference, Rectangle& io_rArea, const bool i_bRight )
        {
            // step 1: move the to-be-upper-left corner (left/bottom) of the rectangle to (0,0)
            ::basegfx::B2DHomMatrix aTransformation;
            aTransformation.translate(
                i_bRight ? -i_rReference.Left() : -i_rReference.Right(),
                i_bRight ? -i_rReference.Bottom() : -i_rReference.Top()
            );

            // step 2: rotate by -90 degrees
            aTransformation.rotate( i_bRight ? +F_PI2 : -F_PI2 );
                // note:
                // on the screen, the ordinate goes top-down, while basegfx calculates in a system where the
                // ordinate goes bottom-up; thus the "wrong" sign before F_PI2 here

            // step 3: move back to original coordinates
            aTransformation.translate( i_rReference.Left(), i_rReference.Top() );

            // apply transformation
            lcl_transform( io_rArea, aTransformation );
        }
    }

	//------------------------------------------------------------------------------------------------------------------
    void lcl_mirrorHorizontally( const Rectangle& i_rReferenceArea, Rectangle& io_rArea )
    {
        io_rArea.Left() = i_rReferenceArea.Left() + i_rReferenceArea.Right() - io_rArea.Left();
        io_rArea.Right() = i_rReferenceArea.Left() + i_rReferenceArea.Right() - io_rArea.Right();
        ::std::swap( io_rArea.Left(), io_rArea.Right() );
    }

	//------------------------------------------------------------------------------------------------------------------
    void lcl_mirrorVertically( const Rectangle& i_rReferenceArea, Rectangle& io_rArea )
    {
        io_rArea.Top() = i_rReferenceArea.Top() + i_rReferenceArea.Bottom() - io_rArea.Top();
        io_rArea.Bottom() = i_rReferenceArea.Top() + i_rReferenceArea.Bottom() - io_rArea.Bottom();
        ::std::swap( io_rArea.Top(), io_rArea.Bottom() );
    }

	//==================================================================================================================
	//= NormalizedArea
	//==================================================================================================================
	//------------------------------------------------------------------------------------------------------------------
    NormalizedArea::NormalizedArea()
        :m_aReference()
    {
    }

	//------------------------------------------------------------------------------------------------------------------
    NormalizedArea::NormalizedArea( const Rectangle& i_rReference, const bool i_bIsVertical )
        :m_aReference( i_bIsVertical ? Rectangle( i_rReference.TopLeft(), Size( i_rReference.GetHeight(), i_rReference.GetWidth() ) ) : i_rReference )
    {
    }

	//------------------------------------------------------------------------------------------------------------------
    Rectangle NormalizedArea::getTransformed( const Rectangle& i_rArea, const TabAlignment i_eTargetAlignment ) const
    {
        Rectangle aResult( i_rArea );

        if  (   ( i_eTargetAlignment == TABS_RIGHT )
            ||  ( i_eTargetAlignment == TABS_LEFT )
            )
        {
            lcl_rotate( m_aReference, aResult, true );

            if ( i_eTargetAlignment == TABS_LEFT )
            {
                Rectangle aReference( m_aReference );
                aReference.Transpose();
                lcl_mirrorHorizontally( aReference, aResult );
            }
        }
        else
        if  ( i_eTargetAlignment == TABS_BOTTOM )
        {
            lcl_mirrorVertically( m_aReference, aResult );
        }

        return aResult;
    }

	//------------------------------------------------------------------------------------------------------------------
    Rectangle NormalizedArea::getNormalized( const Rectangle& i_rArea, const TabAlignment i_eTargetAlignment ) const
    {
        Rectangle aResult( i_rArea );

        if  (   ( i_eTargetAlignment == TABS_RIGHT )
            ||  ( i_eTargetAlignment == TABS_LEFT )
            )
        {
            Rectangle aReference( m_aReference );
            lcl_rotate( m_aReference, aReference, true );

            if ( i_eTargetAlignment == TABS_LEFT )
            {
                lcl_mirrorHorizontally( aReference, aResult );
            }

            lcl_rotate( aReference, aResult, false );
        }
        else
        if  ( i_eTargetAlignment == TABS_BOTTOM )
        {
            lcl_mirrorVertically( m_aReference, aResult );
        }
        return aResult;
    }

	//==================================================================================================================
	//= TabBarGeometry
	//==================================================================================================================
	//------------------------------------------------------------------------------------------------------------------
    TabBarGeometry::TabBarGeometry( const TabItemContent i_eItemContent )
        :m_eTabItemContent( i_eItemContent )
        ,m_aItemsInset()
        ,m_aButtonBackRect()
        ,m_aItemsRect()
        ,m_aButtonForwardRect()
    {
        m_aItemsInset.Left()   = ITEMS_INSET_LEFT;
        m_aItemsInset.Top()    = ITEMS_INSET_TOP;
        m_aItemsInset.Right()  = ITEMS_INSET_RIGHT;
        m_aItemsInset.Bottom() = ITEMS_INSET_BOTTOM;
    }

	//------------------------------------------------------------------------------------------------------------------
    TabBarGeometry::~TabBarGeometry()
    {
    }

    //------------------------------------------------------------------------------------------------------------------
    bool TabBarGeometry::impl_fitItems( ItemDescriptors& io_rItems ) const
    {
        if ( io_rItems.empty() )
            // nothing to do, "no items" perfectly fit into any space we have ...
            return true;

        // the available size
        Size aOutputSize( getItemsRect().GetSize() );
        // shrunk by the outer space
        aOutputSize.Width() -= m_aItemsInset.Right();
        aOutputSize.Height() -= m_aItemsInset.Bottom();
        const Rectangle aFitInto( Point( 0, 0 ), aOutputSize );

        TabItemContent eItemContent( getItemContent() );
        if ( eItemContent == TABITEM_AUTO )
        {
            // the "content modes" to try
            TabItemContent eTryThis[] =
            {
                TABITEM_IMAGE_ONLY,     // assumed to have the smallest rects
                TABITEM_TEXT_ONLY,
                TABITEM_IMAGE_AND_TEXT  // assumed to have the largest rects
            };


            // determine which of the different version fits
            eItemContent = eTryThis[0];
            size_t nTryIndex = 2;
            while ( nTryIndex > 0 )
            {
                const Point aBottomRight( io_rItems.rbegin()->GetRect( eTryThis[ nTryIndex ] ).BottomRight() );
                if ( aFitInto.IsInside( aBottomRight ) )
                {
                    eItemContent = eTryThis[ nTryIndex ];
                    break;
                }
                --nTryIndex;
            }
        }

        // propagate to the items
        for (   ItemDescriptors::iterator item = io_rItems.begin();
                item != io_rItems.end();
                ++item
            )
        {
            item->eContent = eItemContent;
        }

        const ItemDescriptor& rLastItem( *io_rItems.rbegin() );
        const Point aLastItemBottomRight( rLastItem.GetCurrentRect().BottomRight() );
        return  aFitInto.Left() <= aLastItemBottomRight.X()
            &&  aFitInto.Right() >= aLastItemBottomRight.X();
    }

	//------------------------------------------------------------------------------------------------------------------
    Size TabBarGeometry::getOptimalSize( ItemDescriptors& io_rItems, const bool i_bMinimalSize ) const
    {
        if ( io_rItems.empty() )
            return Size(
                m_aItemsInset.Left() + m_aItemsInset.Right(),
                m_aItemsInset.Top() + m_aItemsInset.Bottom()
            );

        // the rect of the last item
        const Rectangle& rLastItemRect( i_bMinimalSize ? io_rItems.rbegin()->aIconOnlyArea : io_rItems.rbegin()->aCompleteArea );
        return Size(
                    rLastItemRect.Left() + 1 + m_aItemsInset.Right(),
                    rLastItemRect.Top() + 1 + rLastItemRect.Bottom() + m_aItemsInset.Bottom()
                );
    }

	//------------------------------------------------------------------------------------------------------------------
    void TabBarGeometry::relayout( const Size& i_rActualOutputSize, ItemDescriptors& io_rItems )
    {
        // assume all items fit
        Point aButtonBackPos( OUTER_SPACE_LEFT, OUTER_SPACE_TOP );
        m_aButtonBackRect = Rectangle( aButtonBackPos, Size( 1, 1 ) );
        m_aButtonBackRect.SetEmpty();

        Point aButtonForwardPos( i_rActualOutputSize.Width(), OUTER_SPACE_TOP );
        m_aButtonForwardRect = Rectangle( aButtonForwardPos, Size( 1, 1 ) );
        m_aButtonForwardRect.SetEmpty();

        Point aItemsPos( OUTER_SPACE_LEFT, 0 );
        Size aItemsSize( i_rActualOutputSize.Width() - OUTER_SPACE_LEFT - OUTER_SPACE_RIGHT, i_rActualOutputSize.Height() );
        m_aItemsRect = Rectangle( aItemsPos, aItemsSize );

        if ( !impl_fitItems( io_rItems ) )
        {
            // assumption was wrong, the items do not fit => calculate rects for the scroll buttons
            const Size aButtonSize( BUTTON_FLOW_WIDTH, i_rActualOutputSize.Height() - OUTER_SPACE_TOP - OUTER_SPACE_BOTTOM );

            aButtonBackPos = Point( OUTER_SPACE_LEFT, OUTER_SPACE_TOP );
            m_aButtonBackRect = Rectangle( aButtonBackPos, aButtonSize );

            aButtonForwardPos = Point( i_rActualOutputSize.Width() - BUTTON_FLOW_WIDTH - OUTER_SPACE_RIGHT, OUTER_SPACE_TOP );
            m_aButtonForwardRect = Rectangle( aButtonForwardPos, aButtonSize );

            aItemsPos.X() = aButtonBackPos.X() + aButtonSize.Width() + BUTTON_FLOW_SPACE;
            aItemsSize.Width() = aButtonForwardPos.X() - BUTTON_FLOW_SPACE - aItemsPos.X();
            m_aItemsRect = Rectangle( aItemsPos, aItemsSize );

            // fit items, again. In the TABITEM_AUTO case, the smaller playground for the items might lead to another
            // item content.
            impl_fitItems( io_rItems );
        }
    }

	//------------------------------------------------------------------------------------------------------------------
    Point TabBarGeometry::getFirstItemPosition() const
    {
        return Point( m_aItemsInset.Left(), m_aItemsInset.Top() );
    }

//......................................................................................................................
} // namespace svt
//......................................................................................................................
