/**************************************************************
 * 
 * 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 "vclxtabcontrol.hxx"

#include <com/sun/star/awt/PosSize.hpp>
#include <sal/macros.h>
#include <toolkit/helper/property.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <vcl/tabctrl.hxx>
#include <vcl/tabpage.hxx>

#include "forward.hxx"

namespace layoutimpl
{

using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star;

VCLXTabControl::ChildProps::ChildProps( VCLXTabControl::ChildData *pData )
{
    addProp( RTL_CONSTASCII_USTRINGPARAM( "Title" ),
             ::getCppuType( static_cast< const rtl::OUString* >( NULL ) ),
             &(pData->maTitle) );
}

VCLXTabControl::ChildData::ChildData( uno::Reference< awt::XLayoutConstrains > const& xChild )
    : Box_Base::ChildData( xChild )
    , maTitle()
{
}

VCLXTabControl::ChildData*
VCLXTabControl::createChild( uno::Reference< awt::XLayoutConstrains > const& xChild )
{
    return new ChildData( xChild );
}

VCLXTabControl::ChildProps*
VCLXTabControl::createChildProps( Box_Base::ChildData *pData )
{
    return new ChildProps( static_cast<VCLXTabControl::ChildData*> ( pData ) );
}

DBG_NAME( VCLXTabControl );

#if !defined (__GNUC__)
#define __PRETTY_FUNCTION__ __FUNCTION__
#endif /* !__GNUC__ */

VCLXTabControl::VCLXTabControl()
  : VCLXWindow()
  , VCLXTabControl_Base()
  , Box_Base()
  , mTabId (1)
  , bRealized (false)
{
#ifndef __SUNPRO_CC
    OSL_TRACE ("\n********%s:%x", __PRETTY_FUNCTION__, this);
#endif
    DBG_CTOR( VCLXTabControl, NULL );
}

VCLXTabControl::~VCLXTabControl()
{
    DBG_DTOR( VCLXTabControl, NULL );
}

IMPLEMENT_2_FORWARD_XINTERFACE2( VCLXTabControl, VCLXWindow, Container, VCLXTabControl_Base );

IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXTabControl, VCLXWindow, VCLXTabControl_Base );

void SAL_CALL VCLXTabControl::dispose( ) throw(uno::RuntimeException)
{
    {
        ::vos::OGuard aGuard( GetMutex() );

        EventObject aDisposeEvent;
        aDisposeEvent.Source = W3K_EXPLICIT_CAST (*this);
//            maTabListeners.disposeAndClear( aDisposeEvent );
    }

    VCLXWindow::dispose();
}

#if 0
void SAL_CALL VCLXTabControl::addTabListener( const Reference< XTabListener >& listener ) throw (uno::RuntimeException)
{
    if ( listener.is() )
        maTabListeners.addInterface( listener );
}

void SAL_CALL VCLXTabControl::removeTabListener( const Reference< XTabListener >& listener ) throw (uno::RuntimeException)
{
    if ( listener.is() )
        maTabListeners.removeInterface( listener );
}
#endif

TabControl *VCLXTabControl::getTabControl() const throw (uno::RuntimeException)
{
    TabControl *pTabControl = static_cast< TabControl* >( GetWindow() );
    if ( pTabControl )
        return pTabControl;
    throw uno::RuntimeException();
}

sal_Int32 SAL_CALL VCLXTabControl::insertTab() throw (uno::RuntimeException)
{
    TabControl *pTabControl = getTabControl();
    sal_uInt16 id = sal::static_int_cast< sal_uInt16 >( mTabId++ );
    rtl::OUString title (RTL_CONSTASCII_USTRINGPARAM( "" ) );
    pTabControl->InsertPage( id, title.getStr(), TAB_APPEND );
    pTabControl->SetTabPage( id, new TabPage( pTabControl ) );
    return id;
}

void SAL_CALL VCLXTabControl::removeTab( sal_Int32 ID ) throw (uno::RuntimeException, IndexOutOfBoundsException)
{
    TabControl *pTabControl = getTabControl();
    if ( pTabControl->GetTabPage( sal::static_int_cast< sal_uInt16 >( ID ) ) == NULL )
        throw IndexOutOfBoundsException();
    pTabControl->RemovePage( sal::static_int_cast< sal_uInt16 >( ID ) );
}

void SAL_CALL VCLXTabControl::activateTab( sal_Int32 ID ) throw (uno::RuntimeException, IndexOutOfBoundsException)
{
    TabControl *pTabControl = getTabControl();
    if ( pTabControl->GetTabPage( sal::static_int_cast< sal_uInt16 >( ID ) ) == NULL )
        throw IndexOutOfBoundsException();
    pTabControl->SelectTabPage( sal::static_int_cast< sal_uInt16 >( ID ) );
}

sal_Int32 SAL_CALL VCLXTabControl::getActiveTabID() throw (uno::RuntimeException)
{
    return getTabControl()->GetCurPageId( );
}

void SAL_CALL VCLXTabControl::addTabListener( const uno::Reference< awt::XTabListener >& xListener ) throw (uno::RuntimeException)
{
    for ( std::list< uno::Reference
              < awt::XTabListener > >::const_iterator it
              = mxTabListeners.begin(); it != mxTabListeners.end(); it++ )
    {
        if ( *it == xListener )
            // already added
            return;
    }
    mxTabListeners.push_back( xListener );
}

void SAL_CALL VCLXTabControl::removeTabListener( const uno::Reference< awt::XTabListener >& xListener ) throw (uno::RuntimeException)
{
    for ( std::list< uno::Reference
              < awt::XTabListener > >::iterator it
              = mxTabListeners.begin(); it != mxTabListeners.end(); it++ )
    {
        if ( *it == xListener )
        {
            mxTabListeners.erase( it );
            break;
        }
    }
}

void SAL_CALL VCLXTabControl::setTabProps( sal_Int32 ID, const uno::Sequence< NamedValue >& Properties ) throw (uno::RuntimeException, IndexOutOfBoundsException)
{
    TabControl *pTabControl = getTabControl();
    if ( pTabControl->GetTabPage( sal::static_int_cast< sal_uInt16 >( ID ) ) == NULL )
        throw IndexOutOfBoundsException();

    for ( int i = 0; i < Properties.getLength(); i++ )
    {
        const rtl::OUString &name = Properties[i].Name;
        const uno::Any &value = Properties[i].Value;

        if ( name  == rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) ) )
        {
            rtl::OUString title = value.get<rtl::OUString>();
            pTabControl->SetPageText( sal::static_int_cast< sal_uInt16 >( ID ), title.getStr() );
        }
    }
}

uno::Sequence< NamedValue > SAL_CALL VCLXTabControl::getTabProps( sal_Int32 ID )
    throw (IndexOutOfBoundsException, uno::RuntimeException)
{
    TabControl *pTabControl = getTabControl();
    if ( pTabControl->GetTabPage( sal::static_int_cast< sal_uInt16 >( ID ) ) == NULL )
        throw IndexOutOfBoundsException();

#define ADD_PROP( seq, i, name, val ) {                                \
        NamedValue value;                                                  \
        value.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( name ) ); \
        value.Value = uno::makeAny( val );                                      \
        seq[i] = value;                                                    \
    }

    uno::Sequence< NamedValue > props( 2 );
    ADD_PROP( props, 0, "Title", rtl::OUString( pTabControl->GetPageText( sal::static_int_cast< sal_uInt16 >( ID ) ) ) );
    ADD_PROP( props, 1, "Position", pTabControl->GetPagePos( sal::static_int_cast< sal_uInt16 >( ID ) ) );
#undef ADD_PROP
    return props;
}

// TODO: draw tab border here
void SAL_CALL VCLXTabControl::draw( sal_Int32 nX, sal_Int32 nY ) throw(uno::RuntimeException)
{
    ::vos::OGuard aGuard( GetMutex() );

    TabControl *pTabControl = getTabControl();
    TabPage *pTabPage = pTabControl->GetTabPage( sal::static_int_cast< sal_uInt16 >(  getActiveTabID() ) );
    if ( pTabPage )
    {
        ::Point aPos( nX, nY );
        ::Size  aSize = pTabPage->GetSizePixel();

		OutputDevice* pDev = VCLUnoHelper::GetOutputDevice( getGraphics() );
        aPos  = pDev->PixelToLogic( aPos );
        aSize = pDev->PixelToLogic( aSize );

        pTabPage->Draw( pDev, aPos, aSize, 0 );
    }

    VCLXWindow::draw( nX, nY );
}

void VCLXTabControl::AddChild (uno::Reference< awt::XLayoutConstrains > const& xChild)

{
#ifndef __SUNPRO_CC
    OSL_TRACE ("%s: children: %d", __PRETTY_FUNCTION__, maChildren.size ());
#endif
    mIdMap[ xChild ] = mTabId++;
    Box_Base::AddChild( xChild );
#ifndef __SUNPRO_CC
    OSL_TRACE ("%s: children: %d", __PRETTY_FUNCTION__, maChildren.size ());
#endif
}

void SAL_CALL VCLXTabControl::addChild(
    const uno::Reference< awt::XLayoutConstrains > &xChild )
    throw (uno::RuntimeException, awt::MaxChildrenException)
{
    mIdMap[ xChild ] = insertTab();
    Box_Base::addChild( xChild );
}

void SAL_CALL VCLXTabControl::removeChild( const uno::Reference< awt::XLayoutConstrains > &xChild )
    throw (uno::RuntimeException)
{
    removeTab( mIdMap[xChild] );
    mIdMap[ xChild ] = -1;
    Box_Base::removeChild( xChild );
}

static void setChildrenVisible( uno::Reference < awt::XLayoutConstrains > xChild, bool visible )
{
    uno::Reference< awt::XWindow > xWin( xChild, uno::UNO_QUERY);
    if ( xWin.is() )
    {
        xWin->setVisible( visible );
    }

    uno::Reference < awt::XLayoutContainer > xCont( xChild, uno::UNO_QUERY );
    if ( xCont.is())
    {
        uno::Sequence< uno::Reference < awt::XLayoutConstrains > > children = xCont->getChildren();
        for ( int i = 0; i < children.getLength(); i++ )
        {
            setChildrenVisible( children[i], visible );
        }
    }
}

void SAL_CALL VCLXTabControl::allocateArea (awt::Rectangle const &area)
    throw (uno::RuntimeException)
{
#ifndef __SUNPRO_CC
    OSL_TRACE ("\n%s", __PRETTY_FUNCTION__);
#endif
    maAllocation = area;

    TabControl *pTabControl = getTabControl();

// FIXME: this is wrong. We just want to set tab controls pos/size for
// the tabs menu, otherwise, it gets events that should go to children
// (I guess we could solve this by making the tabcontrol as the actual
// XWindow parent of its children, when importing...)  Not sure about
// TabPage drawing... That doesn't work on gtk+; just ignoring that.
// LATER: Nah, the proper fix is to get the XWindow hierarchy
// straight.

#if 0
    setPosSize( area.X, area.Y, area.Width, area.Height, awt::PosSize::POSSIZE );
#else
    awt::Size currentSize = getSize();
    awt::Size requestedSize (area.Width, area.Height);
//    requestedSize.Height = getHeightForWidth( area.Width );

    awt::Size minimumSize = getMinimumSize();
    if (requestedSize.Width < minimumSize.Width)
        requestedSize.Width = minimumSize.Width;
    if (requestedSize.Height < minimumSize.Height)
        requestedSize.Height = minimumSize.Height;

    Size pageSize = static_cast<TabControl*> (GetWindow ())->GetTabPageSizePixel ();
    awt::Size pageBasedSize (0, 0);
    pageBasedSize.Width = pageSize.Width ();
    pageBasedSize.Height = pageSize.Height ();

    const int wc = 0;
    const int hc = 20;
    static int pwc = 0;
    static int phc = 40;

    if (requestedSize.Width < pageBasedSize.Width)
        requestedSize.Width = pageBasedSize.Width + wc;
    if (requestedSize.Height < pageBasedSize.Height)
        requestedSize.Height = pageBasedSize.Height + hc;

    Size windowSize = GetWindow()->GetSizePixel();
    Window *parent = GetWindow()->GetParent();
    Size parentSize = parent->GetSizePixel();

#ifndef __SUNPRO_CC
#ifdef GCC_MAJOR
    OSL_TRACE ("\n%s", __PRETTY_FUNCTION__);
#endif /* GCC_MAJOR */
    OSL_TRACE ("%s: cursize: %d ,%d", __FUNCTION__, currentSize.Width, currentSize.Height );
    OSL_TRACE ("%s: area: %d, %d", __FUNCTION__, area.Width, area.Height );
    OSL_TRACE ("%s: minimum: %d, %d", __FUNCTION__, minimumSize.Width, minimumSize.Height );
    OSL_TRACE ("%s: requestedSize: %d, %d", __FUNCTION__, requestedSize.Width, requestedSize.Height );
    OSL_TRACE ("%s: pageBasedSize: %d, %d", __FUNCTION__, pageBasedSize.Width, pageBasedSize.Height );

    //OSL_TRACE ("%s: parent: %d, %d", __FUNCTION__, parentSize.Width(), parentSize.Height() );
    //OSL_TRACE ("%s: window: %d, %d", __FUNCTION__, windowSize.Width(), windowSize.Height() );
#endif

	//bRealized = false;
    if (!bRealized)
    {
        setPosSize( area.X, area.Y, requestedSize.Width, requestedSize.Height, awt::PosSize::POSSIZE );
        bRealized = true;
    }
    else
    {
        if ( requestedSize.Width > currentSize.Width + 10)
            setPosSize( 0, 0, requestedSize.Width, 0, awt::PosSize::WIDTH );
        if ( requestedSize.Height > currentSize.Height + 10)
            setPosSize( 0, 0, 0, requestedSize.Height, awt::PosSize::HEIGHT );
    }
#endif

    if (pageBasedSize.Width > parentSize.Width ()
        || pageBasedSize.Height > parentSize.Height ())
        //parent->SetSizePixel ( Size (pageBasedSize.Width, pageBasedSize.Height));
        //parent->SetSizePixel ( Size (pageBasedSize.Width + pwc, pageBasedSize.Height + phc));
        parent->SetSizePixel ( Size (requestedSize.Width + pwc, requestedSize.Height + phc));

    // FIXME: we can save cycles by setting visibility more sensibly. Having
    // it here does makes it easier when changing tabs (just needs a recalc())
    unsigned i = 0;
    for ( std::list<Box_Base::ChildData *>::const_iterator it
              = maChildren.begin(); it != maChildren.end(); it++, i++ )
    {
        ChildData *child = static_cast<VCLXTabControl::ChildData*> ( *it );
        uno::Reference
              < awt::XLayoutConstrains > xChild( child->mxChild );
        if ( xChild.is() )
        {
            uno::Reference< awt::XWindow > xWin( xChild, uno::UNO_QUERY );
            bool active = (i+1 == (unsigned) getActiveTabID());

            // HACK: since our layout:: container don't implement XWindow, we have no easy
            // way to set them invisible; lets just set all their children as such :P
#if 0
            if ( xWin.is() )
                xWin->setVisible( active );
#else
            setChildrenVisible( xChild, active );
#endif

            if ( active )
            {
                ::Rectangle label_rect = pTabControl->GetTabBounds( sal::static_int_cast< sal_uInt16 >( i+1 ) );
                ::Rectangle page_rect = pTabControl->GetTabPageBounds( sal::static_int_cast< sal_uInt16 >( i+1 ) );

                awt::Rectangle childRect;
                childRect.X = page_rect.Left();
                childRect.Y = SAL_MAX( label_rect.Bottom(), page_rect.Top() );
                childRect.Width = page_rect.Right() - page_rect.Left();
                childRect.Height = page_rect.Bottom() - childRect.Y;

                allocateChildAt( xChild, childRect );
            }
        }
    }
}

awt::Size SAL_CALL VCLXTabControl::getMinimumSize()
    throw(uno::RuntimeException)
{
    awt::Size requestedSize = VCLXWindow::getMinimumSize();
    awt::Size childrenSize( 0, 0 );

    TabControl* pTabControl = static_cast< TabControl* >( GetWindow() );
    if ( !pTabControl )
        return requestedSize;

    // calculate size to accomodate all children
    unsigned i = 0;
    for ( std::list<Box_Base::ChildData *>::const_iterator it
              = maChildren.begin(); it != maChildren.end(); it++, i++ )
    {
        ChildData *child = static_cast<VCLXTabControl::ChildData*> ( *it );
        if ( child->mxChild.is() )
        {
            // set the title prop here...
            pTabControl->SetPageText( sal::static_int_cast< sal_uInt16 >( i+1 ), child->maTitle.getStr() );

            awt::Size childSize( child->mxChild->getMinimumSize() );
            childrenSize.Width = SAL_MAX( childSize.Width, childrenSize.Width );
            childrenSize.Height = SAL_MAX( childSize.Height, childrenSize.Height );
        }
    }

#ifndef __SUNPRO_CC
#ifdef GCC_MAJOR
    OSL_TRACE ("\n%s", __PRETTY_FUNCTION__);
#endif /* GCC_MAJOR */
    OSL_TRACE ("%s: children: %d", __FUNCTION__, i);
    OSL_TRACE ("%s: childrenSize: %d, %d", __FUNCTION__, childrenSize.Width, childrenSize.Height );
#endif

    requestedSize.Width += childrenSize.Width;
    requestedSize.Height += childrenSize.Height + 20;

    maRequisition = requestedSize;
    return requestedSize;
}

void VCLXTabControl::ProcessWindowEvent( const VclWindowEvent& _rVclWindowEvent )
{
    ::vos::OClearableGuard aGuard( GetMutex() );
    TabControl* pTabControl = static_cast< TabControl* >( GetWindow() );
    if ( !pTabControl )
        return;

    switch ( _rVclWindowEvent.GetId() )
    {
        case VCLEVENT_TABPAGE_ACTIVATE:
            forceRecalc();
        case VCLEVENT_TABPAGE_DEACTIVATE:
        case VCLEVENT_TABPAGE_INSERTED:
        case VCLEVENT_TABPAGE_REMOVED:
        case VCLEVENT_TABPAGE_REMOVEDALL:
        case VCLEVENT_TABPAGE_PAGETEXTCHANGED:
        {
            sal_uLong page = (sal_uLong) _rVclWindowEvent.GetData();
            for ( std::list< uno::Reference
                      < awt::XTabListener > >::iterator it
                      = mxTabListeners.begin(); it != mxTabListeners.end(); it++)
            {
                uno::Reference
                    < awt::XTabListener > listener = *it;

                switch ( _rVclWindowEvent.GetId() )
                {

                    case VCLEVENT_TABPAGE_ACTIVATE:
                        listener->activated( page );
                        break;
                    case VCLEVENT_TABPAGE_DEACTIVATE:
                        listener->deactivated( page );
                        break;
                    case VCLEVENT_TABPAGE_INSERTED:
                        listener->inserted( page );
                        break;
                    case VCLEVENT_TABPAGE_REMOVED:
                        listener->removed( page );
                        break;
                    case VCLEVENT_TABPAGE_REMOVEDALL:
                        for ( int i = 1; i < mTabId; i++)
                        {
                            if ( pTabControl->GetTabPage( sal::static_int_cast< sal_uInt16 >( i ) ) )
                                listener->removed( i );
                        }
                        break;
                    case VCLEVENT_TABPAGE_PAGETEXTCHANGED:
                        listener->changed( page, getTabProps( page ) );
                        break;
                }
            }
            break;
        }
        default:
            aGuard.clear();
            VCLXWindow::ProcessWindowEvent( _rVclWindowEvent );
            break;
    }
}

void SAL_CALL VCLXTabControl::setProperty( const ::rtl::OUString& PropertyName, const uno::Any &Value ) throw(uno::RuntimeException)
{
    VCLXWindow::setProperty( PropertyName, Value );
}

uno::Any SAL_CALL VCLXTabControl::getProperty( const ::rtl::OUString& PropertyName ) throw(uno::RuntimeException)
{
    return VCLXWindow::getProperty( PropertyName );
}

} // namespace layoutimpl
