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

#ifndef _TOOLKIT_TREE_CONTROL_HXX
#include <treecontrol.hxx>
#endif

#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/view/SelectionType.hpp>
#include <com/sun/star/awt/tree/XTreeDataModel.hpp>
#include <toolkit/helper/unopropertyarrayhelper.hxx>
#include <toolkit/helper/property.hxx>
#include <com/sun/star/awt/XVclWindowPeer.hpp>
#include <comphelper/processfactory.hxx>
#include <osl/diagnose.h>

using ::rtl::OUString;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::awt::tree;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::view;

namespace toolkit
{
//	----------------------------------------------------
//	class UnoTreeModel
//	----------------------------------------------------
UnoTreeModel::UnoTreeModel( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& i_factory )
    :UnoControlModel( i_factory )
{
	ImplRegisterProperty( BASEPROPERTY_BACKGROUNDCOLOR );
    ImplRegisterProperty( BASEPROPERTY_BORDER );
	ImplRegisterProperty( BASEPROPERTY_BORDERCOLOR );
    ImplRegisterProperty( BASEPROPERTY_DEFAULTCONTROL );
	ImplRegisterProperty( BASEPROPERTY_ENABLED );
	ImplRegisterProperty( BASEPROPERTY_ENABLEVISIBLE );
	ImplRegisterProperty( BASEPROPERTY_FILLCOLOR );
    ImplRegisterProperty( BASEPROPERTY_HELPTEXT );
	ImplRegisterProperty( BASEPROPERTY_HELPURL );
    ImplRegisterProperty( BASEPROPERTY_PRINTABLE );
    ImplRegisterProperty( BASEPROPERTY_TABSTOP );
    ImplRegisterProperty( BASEPROPERTY_TREE_SELECTIONTYPE );
    ImplRegisterProperty( BASEPROPERTY_TREE_EDITABLE );
    ImplRegisterProperty( BASEPROPERTY_TREE_DATAMODEL );
    ImplRegisterProperty( BASEPROPERTY_TREE_ROOTDISPLAYED );
	ImplRegisterProperty( BASEPROPERTY_TREE_SHOWSHANDLES );
	ImplRegisterProperty( BASEPROPERTY_TREE_SHOWSROOTHANDLES );
    ImplRegisterProperty( BASEPROPERTY_ROW_HEIGHT );
    ImplRegisterProperty( BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING );
    ImplRegisterProperty( BASEPROPERTY_HIDEINACTIVESELECTION );
}

UnoTreeModel::UnoTreeModel( const UnoTreeModel& rModel )
: UnoControlModel( rModel )
{
}

UnoControlModel* UnoTreeModel::Clone() const
{
	return new UnoTreeModel( *this );
}

OUString UnoTreeModel::getServiceName() throw(RuntimeException)
{
	return OUString::createFromAscii( szServiceName_TreeControlModel );
}

Any UnoTreeModel::ImplGetDefaultValue( sal_uInt16 nPropId ) const
{
	switch( nPropId )
	{
	case BASEPROPERTY_TREE_SELECTIONTYPE:
		return Any( SelectionType_NONE );
	case BASEPROPERTY_ROW_HEIGHT:
		return Any( sal_Int32( 0 ) );
	case BASEPROPERTY_TREE_DATAMODEL:
		return Any( Reference< XTreeDataModel >( 0 ) );
	case BASEPROPERTY_TREE_EDITABLE:
	case BASEPROPERTY_TREE_INVOKESSTOPNODEEDITING:
		return Any( sal_False );
	case BASEPROPERTY_TREE_ROOTDISPLAYED:
	case BASEPROPERTY_TREE_SHOWSROOTHANDLES:
	case BASEPROPERTY_TREE_SHOWSHANDLES:
		return Any( sal_True );
	case BASEPROPERTY_DEFAULTCONTROL:
		return uno::makeAny( ::rtl::OUString::createFromAscii( szServiceName_TreeControl ) );
	default:
		return UnoControlModel::ImplGetDefaultValue( nPropId );
	}
}

::cppu::IPropertyArrayHelper& UnoTreeModel::getInfoHelper()
{
	static UnoPropertyArrayHelper* pHelper = NULL;
	if ( !pHelper )
	{
		Sequence<sal_Int32>	aIDs = ImplGetPropertyIds();
		pHelper = new UnoPropertyArrayHelper( aIDs );
	}
	return *pHelper;
}

// XMultiPropertySet
Reference< XPropertySetInfo > UnoTreeModel::getPropertySetInfo(  ) throw(RuntimeException)
{
	static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
	return xInfo;
}


//	----------------------------------------------------
//	class UnoTreeControl
//	----------------------------------------------------
UnoTreeControl::UnoTreeControl( const Reference< XMultiServiceFactory >& i_factory )
: UnoTreeControl_Base( i_factory )
, maSelectionListeners( *this )
, maTreeExpansionListeners( *this )
, maTreeEditListeners( *this )
{
}

OUString UnoTreeControl::GetComponentServiceName()
{
	return OUString::createFromAscii( "Tree" );
}

// -------------------------------------------------------------------
// ::com::sun::star::view::XSelectionSupplier
// -------------------------------------------------------------------

sal_Bool SAL_CALL UnoTreeControl::select( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->select( rSelection );
}

// -------------------------------------------------------------------

Any SAL_CALL UnoTreeControl::getSelection() throw (RuntimeException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getSelection();
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::addSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException)
{
	maSelectionListeners.addInterface( xListener );
	if( getPeer().is() && (maSelectionListeners.getLength() == 1) )
	{
		// maSelectionListeners acts as a proxy,
		// add it to the peer if this is the first listener added to that proxy
        Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
		Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->addSelectionChangeListener(&maSelectionListeners);
	}
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& xListener ) throw (RuntimeException)
{
	if( getPeer().is() && (maSelectionListeners.getLength() == 1) )
	{
		// maSelectionListeners acts as a proxy,
		// remove it from the peer if this is the last listener removed from that proxy
        Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
		Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->removeSelectionChangeListener(&maSelectionListeners);
	}
	maSelectionListeners.removeInterface( xListener );
}

// -------------------------------------------------------------------
// ::com::sun::star::view::XMultiSelectionSupplier
// -------------------------------------------------------------------

sal_Bool SAL_CALL UnoTreeControl::addSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->addSelection(rSelection);
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::removeSelection( const Any& rSelection ) throw (IllegalArgumentException, RuntimeException)
{
    Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
	Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->removeSelection(rSelection);
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::clearSelection() throw (RuntimeException)
{
    Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
	Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->clearSelection();
}

// -------------------------------------------------------------------

sal_Int32 SAL_CALL UnoTreeControl::getSelectionCount() throw (RuntimeException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getSelectionCount();
}

// -------------------------------------------------------------------

Reference< XEnumeration > SAL_CALL UnoTreeControl::createSelectionEnumeration() throw (RuntimeException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->createSelectionEnumeration();
}

// -------------------------------------------------------------------

Reference< XEnumeration > SAL_CALL UnoTreeControl::createReverseSelectionEnumeration() throw (RuntimeException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->createReverseSelectionEnumeration();
}

// --------------------------------------------------------------------
// XTreeControl
// --------------------------------------------------------------------

OUString SAL_CALL UnoTreeControl::getDefaultExpandedGraphicURL() throw (RuntimeException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getDefaultExpandedGraphicURL();
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::setDefaultExpandedGraphicURL( const OUString& _defaultexpansiongraphicurl ) throw (RuntimeException)
{
    Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
	Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->setDefaultExpandedGraphicURL(_defaultexpansiongraphicurl);
}

// -------------------------------------------------------------------

OUString SAL_CALL UnoTreeControl::getDefaultCollapsedGraphicURL() throw (RuntimeException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getDefaultCollapsedGraphicURL();
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::setDefaultCollapsedGraphicURL( const OUString& _defaultcollapsedgraphicurl ) throw (RuntimeException)
{
    Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
	Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->setDefaultCollapsedGraphicURL(_defaultcollapsedgraphicurl);
}

// -------------------------------------------------------------------

sal_Bool SAL_CALL UnoTreeControl::isNodeExpanded( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->isNodeExpanded(xNode);
}

// -------------------------------------------------------------------

sal_Bool SAL_CALL UnoTreeControl::isNodeCollapsed( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->isNodeCollapsed(xNode);
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::makeNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException)
{
    Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
	Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->makeNodeVisible(xNode);
}

// -------------------------------------------------------------------

sal_Bool SAL_CALL UnoTreeControl::isNodeVisible( const Reference< XTreeNode >& xNode ) throw (RuntimeException, IllegalArgumentException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->isNodeVisible(xNode);
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::expandNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException)
{
    Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
	Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->expandNode(xNode);
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::collapseNode( const Reference< XTreeNode >& xNode ) throw (RuntimeException, ExpandVetoException, IllegalArgumentException)
{
    Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
	Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->collapseNode(xNode);
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::addTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException)
{
	maTreeExpansionListeners.addInterface( xListener );
	if( getPeer().is() && (maTreeExpansionListeners.getLength() == 1) )
	{
		// maSelectionListeners acts as a proxy,
		// add it to the peer if this is the first listener added to that proxy
        Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
		Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->addTreeExpansionListener(&maTreeExpansionListeners);
	}
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::removeTreeExpansionListener( const Reference< XTreeExpansionListener >& xListener ) throw (RuntimeException)
{
	if( getPeer().is() && (maTreeExpansionListeners.getLength() == 1) )
	{
		// maSelectionListeners acts as a proxy,
		// remove it from the peer if this is the last listener removed from that proxy
        Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
		Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->removeTreeExpansionListener(&maTreeExpansionListeners);
	}
	maTreeExpansionListeners.removeInterface( xListener );
}

// -------------------------------------------------------------------

Reference< XTreeNode > SAL_CALL UnoTreeControl::getNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getNodeForLocation(x,y);
}

// -------------------------------------------------------------------

Reference< XTreeNode > SAL_CALL UnoTreeControl::getClosestNodeForLocation( sal_Int32 x, sal_Int32 y ) throw (RuntimeException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getClosestNodeForLocation(x,y);
}

// -------------------------------------------------------------------

awt::Rectangle SAL_CALL UnoTreeControl::getNodeRect( const Reference< XTreeNode >& Node ) throw (IllegalArgumentException, RuntimeException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->getNodeRect( Node );
}

// -------------------------------------------------------------------

sal_Bool SAL_CALL UnoTreeControl::isEditing(  ) throw (RuntimeException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->isEditing();
}

// -------------------------------------------------------------------

sal_Bool SAL_CALL UnoTreeControl::stopEditing() throw (RuntimeException)
{
	return Reference< XTreeControl >( getPeer(), UNO_QUERY_THROW )->stopEditing();
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::cancelEditing() throw (RuntimeException)
{
    Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
	Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->cancelEditing();
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::startEditingAtNode( const Reference< XTreeNode >& xNode ) throw (IllegalArgumentException, RuntimeException)
{
    Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
	Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->startEditingAtNode(xNode);
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::addTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException)
{
	maTreeEditListeners.addInterface( xListener );
	if( getPeer().is() && (maTreeEditListeners.getLength() == 1) )
	{
		// maSelectionListeners acts as a proxy,
		// add it to the peer if this is the first listener added to that proxy
        Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
		Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->addTreeEditListener(&maTreeEditListeners);
	}
}

// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::removeTreeEditListener( const Reference< XTreeEditListener >& xListener ) throw (RuntimeException)
{
	if( getPeer().is() && (maTreeEditListeners.getLength() == 1) )
	{
		// maSelectionListeners acts as a proxy,
		// remove it from the peer if this is the last listener removed from that proxy
        Reference< XWindowPeer > xGcc3WorkaroundTemporary( getPeer());
		Reference< XTreeControl >( xGcc3WorkaroundTemporary, UNO_QUERY_THROW )->removeTreeEditListener(&maTreeEditListeners);
	}
	maTreeEditListeners.removeInterface( xListener );
}

// -------------------------------------------------------------------
// XComponent
// -------------------------------------------------------------------

void SAL_CALL UnoTreeControl::dispose(  ) throw(RuntimeException)
{
	lang::EventObject aEvt;
	aEvt.Source = static_cast< ::cppu::OWeakObject* >(this);
	maSelectionListeners.disposeAndClear( aEvt );
	maTreeExpansionListeners.disposeAndClear( aEvt );
	UnoControl::dispose();
}

void UnoTreeControl::createPeer( const uno::Reference< awt::XToolkit > & rxToolkit, const uno::Reference< awt::XWindowPeer >  & rParentPeer ) throw(uno::RuntimeException)
{
	UnoControlBase::createPeer( rxToolkit, rParentPeer );

	Reference< XTreeControl >  xTree( getPeer(), UNO_QUERY_THROW );
	if( maSelectionListeners.getLength() )
		xTree->addSelectionChangeListener( &maSelectionListeners );
	if( maTreeExpansionListeners.getLength() )
		xTree->addTreeExpansionListener( &maTreeExpansionListeners );
}

}

Reference< XInterface > SAL_CALL TreeControl_CreateInstance( const Reference< XMultiServiceFactory >& i_factory )
{
	return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::UnoTreeControl( i_factory ) );
}

Reference< XInterface > SAL_CALL TreeControlModel_CreateInstance( const Reference< XMultiServiceFactory >& i_factory )
{
	return Reference < XInterface >( ( ::cppu::OWeakObject* ) new ::toolkit::UnoTreeModel( i_factory ) );
}

void SAL_CALL TreeEditListenerMultiplexer::nodeEditing( const Reference< XTreeNode >& Node ) throw (RuntimeException, ::com::sun::star::util::VetoException)
{
	::cppu::OInterfaceIteratorHelper aIt( *this );
	while( aIt.hasMoreElements() )
    {
        Reference< XTreeEditListener > xListener(static_cast< XTreeEditListener* >( aIt.next() ) );
        try
        {
			xListener->nodeEditing( Node );
        }
        catch( DisposedException& e )
        {
            OSL_ENSURE( e.Context.is(), "caught DisposedException with empty Context field" );
            if ( e.Context == xListener || !e.Context.is() )
                aIt.remove();
        }
        catch( RuntimeException& e )
        {
			(void)e;
            DISPLAY_EXCEPTION( TreeEditListenerMultiplexer, nodeEditing, e )
        }
    }
}

void SAL_CALL TreeEditListenerMultiplexer::nodeEdited( const Reference< XTreeNode >& Node, const OUString& NewText ) throw (RuntimeException)
{
	::cppu::OInterfaceIteratorHelper aIt( *this );
	while( aIt.hasMoreElements() )
    {
        Reference< XTreeEditListener > xListener( static_cast< XTreeEditListener* >( aIt.next() ) );
        try
        {
			xListener->nodeEdited( Node, NewText );
        }
        catch( DisposedException& e )
        {
            OSL_ENSURE( e.Context.is(), "caught DisposedException with empty Context field" );
            if ( e.Context == xListener || !e.Context.is() )
                aIt.remove();
        }
        catch( RuntimeException& e )
        {
			(void)e;
            DISPLAY_EXCEPTION( TreeEditListenerMultiplexer, nodeEdited, e )
        }
    }
}
