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



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_chart2.hxx"

#include "AccessibleChartView.hxx"
#include "chartview/ExplicitValueProvider.hxx"
#include "servicenames.hxx"
#include "macros.hxx"
#include "ObjectHierarchy.hxx"
#include "ObjectIdentifier.hxx"
#include "ResId.hxx"
#include "Strings.hrc"
#include "AccessibleViewForwarder.hxx"

#include <com/sun/star/accessibility/AccessibleEventId.hpp>
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#include <com/sun/star/accessibility/AccessibleRole.hpp>

#include <tools/string.hxx>
#include <vcl/window.hxx>
#include <toolkit/helper/vclunohelper.hxx>
// for SolarMutex
#include <vcl/svapp.hxx>

// header for typedef MutexGuard
#include <osl/mutex.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::accessibility;

using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::WeakReference;
using ::com::sun::star::uno::Any;
using ::rtl::OUString;
using osl::MutexGuard;

//.............................................................................
namespace chart
{
//.............................................................................

AccessibleChartView::AccessibleChartView(
    const Reference< uno::XComponentContext >& xContext, SdrView* pView ) :
        impl::AccessibleChartView_Base(
            AccessibleElementInfo(), // empty for now
            true, // has children
            true  // always transparent
            ),
        m_xContext( xContext ),
        m_pSdrView( pView ),
        m_pViewForwarder( NULL )
{
    AddState( AccessibleStateType::OPAQUE );
}

AccessibleChartView::~AccessibleChartView()
{
    delete m_pViewForwarder;
}


awt::Rectangle AccessibleChartView::GetWindowPosSize() const
{
    Reference< awt::XWindow > xWindow( GetInfo().m_xWindow );
    if( ! xWindow.is())
        return awt::Rectangle();

    // this should do, but it doesn't => HACK
//     return xWindow->getPosSize();

    awt::Rectangle aBBox( xWindow->getPosSize() );

    Window* pWindow( VCLUnoHelper::GetWindow( GetInfo().m_xWindow ));
    if( pWindow )
    {
        // /-- solar
        ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
        Point aVCLPoint( pWindow->OutputToAbsoluteScreenPixel( Point( 0, 0 ) ));
        aBBox.X = aVCLPoint.getX();
        aBBox.Y = aVCLPoint.getY();
        // \-- solar
    }

    return aBBox;
}

awt::Point AccessibleChartView::GetUpperLeftOnScreen() const
{
    awt::Point aParentPosition;

    awt::Rectangle aBBox( GetWindowPosSize() );
    aParentPosition.X = aBBox.X;
    aParentPosition.Y = aBBox.Y;

    return aParentPosition;
}

// ________ XAccessibleContext ________
OUString SAL_CALL AccessibleChartView::getAccessibleName()
    throw (uno::RuntimeException)
{
    return OUString( String( SchResId( STR_OBJECT_DIAGRAM )));
}

OUString SAL_CALL AccessibleChartView::getAccessibleDescription()
    throw (uno::RuntimeException)
{
    return getAccessibleName();
}

Reference< XAccessible > SAL_CALL AccessibleChartView::getAccessibleParent()
    throw (uno::RuntimeException)
{
    return Reference< XAccessible >( m_xParent );
}

sal_Int32 SAL_CALL AccessibleChartView::getAccessibleIndexInParent()
    throw (uno::RuntimeException)
{
    // the document is always the only child of the window
    return 0;
}

sal_Int16 SAL_CALL AccessibleChartView::getAccessibleRole()
    throw (uno::RuntimeException)
{
    return AccessibleRole::DOCUMENT;
}

// ________ XAccessibleComponent ________
awt::Rectangle SAL_CALL AccessibleChartView::getBounds()
    throw (uno::RuntimeException)
{
    awt::Rectangle aResult( GetWindowPosSize());
    Reference< XAccessible > xParent( m_xParent );
    if( xParent.is())
    {
        Reference< XAccessibleComponent > xContext( xParent->getAccessibleContext(), uno::UNO_QUERY );
        if( xContext.is())
        {
            awt::Point aParentPosition = xContext->getLocationOnScreen();
            aResult.X -= aParentPosition.X;
            aResult.Y -= aParentPosition.Y;
        }
    }
    return aResult;
}

awt::Point SAL_CALL AccessibleChartView::getLocationOnScreen()
    throw (uno::RuntimeException)
{
    awt::Rectangle aBounds( getBounds());
    awt::Point aResult;
    Reference< XAccessible > xParent( m_xParent );
    if( xParent.is())
    {
        Reference< XAccessibleComponent > xAccComp(
            xParent->getAccessibleContext(), uno::UNO_QUERY );
        aResult = xAccComp->getLocationOnScreen();
        aResult.X += aBounds.X;
        aResult.Y += aBounds.Y;
    }
    return aResult;
}

//-----------------------------------------------------------------
// lang::XInitialization
//-----------------------------------------------------------------

void SAL_CALL AccessibleChartView::initialize( const Sequence< Any >& rArguments )
                throw (uno::Exception, uno::RuntimeException)
{
    //0: view::XSelectionSupplier offers notifications for selection changes and access to the selection itself
    //1: frame::XModel representing the chart model - offers access to object data
    //2: lang::XInterface representing the normal chart view - offers access to some extra object data

    //all arguments are only valid until next initialization
    bool bChanged = false;
    bool bOldInvalid = false;
    bool bNewInvalid = false;

    Reference< view::XSelectionSupplier > xSelectionSupplier;
    Reference< frame::XModel > xChartModel;
    Reference< uno::XInterface > xChartView;
    Reference< XAccessible > xParent;
    Reference< awt::XWindow > xWindow;
    {
        MutexGuard aGuard( GetMutex());
        xSelectionSupplier.set( m_xSelectionSupplier );
        xChartModel.set( m_xChartModel );
        xChartView.set( m_xChartView );
        xParent.set( m_xParent );
        xWindow.set( m_xWindow );
    }

    if( !xSelectionSupplier.is() || !xChartModel.is() || !xChartView.is() )
    {
        bOldInvalid = true;
    }

    if( rArguments.getLength() > 1 )
    {
        Reference< frame::XModel > xNewChartModel;
        rArguments[1] >>= xNewChartModel;
        if( xNewChartModel != xChartModel )
        {
            xChartModel = xNewChartModel;
            bChanged = true;
        }
    }
    else if( xChartModel.is() )
    {
        bChanged = true;
        xChartModel = 0;
    }

    if( rArguments.getLength() > 2 )
    {
        Reference< uno::XInterface > xNewChartView;
        rArguments[2] >>= xNewChartView;
        if( xNewChartView != xChartView )
        {
            xChartView = xNewChartView;
            bChanged = true;
        }
    }
    else if( xChartView.is() )
    {
        bChanged = true;
        xChartView = 0;
    }

    if( rArguments.getLength() > 3 )
    {
        Reference< XAccessible > xNewParent;
        rArguments[3] >>= xNewParent;
        if( xNewParent != xParent )
        {
            xParent = xNewParent;
            bChanged = true;
        }
    }

    if( rArguments.getLength() > 4 )
    {
        Reference< awt::XWindow > xNewWindow;
        rArguments[4] >>= xNewWindow;
        if( xNewWindow != xWindow )
        {
            xWindow.set( xNewWindow );
            bChanged = true;
        }
    }

    if( rArguments.getLength() > 0 && xChartModel.is() && xChartView.is() )
    {
        Reference< view::XSelectionSupplier > xNewSelectionSupplier;
        rArguments[0] >>= xNewSelectionSupplier;
        if(xSelectionSupplier!=xNewSelectionSupplier)
        {
            bChanged = true;
            if(xSelectionSupplier.is())
                xSelectionSupplier->removeSelectionChangeListener(this);
            if(xNewSelectionSupplier.is())
                xNewSelectionSupplier->addSelectionChangeListener(this);
            xSelectionSupplier = xNewSelectionSupplier;
        }
    }
    else if( xSelectionSupplier.is() )
    {
        bChanged = true;
        xSelectionSupplier->removeSelectionChangeListener(this);
        xSelectionSupplier = 0;
    }

    if( !xSelectionSupplier.is() || !xChartModel.is() || !xChartView.is() )
    {
        if(xSelectionSupplier.is())
            xSelectionSupplier->removeSelectionChangeListener(this);
        xSelectionSupplier = 0;
        xChartModel.clear();
        xChartView.clear();
        xParent.clear();
        xWindow.clear();

        bNewInvalid = true;
    }

    {
        MutexGuard aGuard( GetMutex());
        m_xSelectionSupplier = WeakReference< view::XSelectionSupplier >(xSelectionSupplier);
        m_xChartModel = WeakReference< frame::XModel >(xChartModel);
        m_xChartView = WeakReference< uno::XInterface >(xChartView);
        m_xParent = WeakReference< XAccessible >(xParent);
        m_xWindow = WeakReference< awt::XWindow >(xWindow);
    }

    if( bOldInvalid && bNewInvalid )
        bChanged = false;

    if( bChanged )
    {
        {
            //before notification we prepare for creation of new context
            //the old context will be deleted after notification than
            MutexGuard aGuard( GetMutex());
            Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY );
            if( xChartDoc.is())
                m_spObjectHierarchy.reset( new ObjectHierarchy( xChartDoc, getExplicitValueProvider() ));
            else
                m_spObjectHierarchy.reset();
        }

        {
            AccessibleElementInfo aAccInfo;
            aAccInfo.m_aOID = ObjectIdentifier( C2U( "ROOT" ) );
            aAccInfo.m_xChartDocument = uno::WeakReference< chart2::XChartDocument >(
                uno::Reference< chart2::XChartDocument >( m_xChartModel.get(), uno::UNO_QUERY ));
            aAccInfo.m_xSelectionSupplier = m_xSelectionSupplier;
            aAccInfo.m_xView = m_xChartView;
            aAccInfo.m_xWindow = m_xWindow;
            aAccInfo.m_pParent = 0;
            aAccInfo.m_spObjectHierarchy = m_spObjectHierarchy;
            aAccInfo.m_pSdrView = m_pSdrView;
            Window* pWindow = VCLUnoHelper::GetWindow( m_xWindow );
            if ( m_pViewForwarder )
            {
                delete m_pViewForwarder;
            }
            m_pViewForwarder = new AccessibleViewForwarder( this, pWindow );
            aAccInfo.m_pViewForwarder = m_pViewForwarder;
            // broadcasts an INVALIDATE_ALL_CHILDREN event globally
            SetInfo( aAccInfo );
        }
    }
}

ExplicitValueProvider* AccessibleChartView::getExplicitValueProvider()
{
    return ExplicitValueProvider::getExplicitValueProvider(m_xChartView);
}

//-------------------------------------------------------------------------
// view::XSelectionChangeListener
//-------------------------------------------------------------------------

void SAL_CALL AccessibleChartView::selectionChanged( const lang::EventObject& /*rEvent*/ )
                throw (uno::RuntimeException)
{
    Reference< view::XSelectionSupplier > xSelectionSupplier;
    {
        MutexGuard aGuard( GetMutex());
        xSelectionSupplier = Reference< view::XSelectionSupplier >(m_xSelectionSupplier);
    }

    if( xSelectionSupplier.is() )
    {
        ObjectIdentifier aSelectedOID( xSelectionSupplier->getSelection() );
        if ( m_aCurrentSelectionOID.isValid() )
        {
            NotifyEvent( LOST_SELECTION, m_aCurrentSelectionOID );
        }
        if( aSelectedOID.isValid() )
        {
            NotifyEvent( GOT_SELECTION, aSelectedOID );
        }
        m_aCurrentSelectionOID = aSelectedOID;
    }
}

//-------------------------------------------------------------------------
// lang::XComponent::dispose()
//-------------------------------------------------------------------------
void SAL_CALL AccessibleChartView::disposing()
{
    AccessibleBase::disposing();
}

//-------------------------------------------------------------------------
// XEventListener
//-------------------------------------------------------------------------
void SAL_CALL AccessibleChartView::disposing( const lang::EventObject& /*Source*/ )
    throw (uno::RuntimeException)
{
}

//.............................................................................
} //namespace chart
//.............................................................................
