/*************************************************************************
 *
 *  $RCSfile: DocumentHelper.java,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2003/06/30 15:27:13 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  the BSD license.
 *  
 *  Copyright (c) 2003 by Sun Microsystems, Inc.
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. Neither the name of Sun Microsystems, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 *  OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 *  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 *  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *     
 *************************************************************************/

import com.sun.star.uno.*;
import com.sun.star.lang.*;
import com.sun.star.util.*;
import com.sun.star.container.*;
import com.sun.star.awt.*;
import com.sun.star.drawing.*;
import com.sun.star.frame.*;
import com.sun.star.form.*;
import com.sun.star.beans.*;

/**************************************************************************/
/** provides a small wrapper around a document
*/
public class DocumentHelper
{
	protected XMultiServiceFactory	m_xMSF;
	protected XComponent			m_xDocument;

	/* ------------------------------------------------------------------ */
	public XComponent	getDocument( )
	{
		return m_xDocument;
	}

	/* ------------------------------------------------------------------ */
	public DocumentHelper( XMultiServiceFactory xMSF, XComponent xDocument )
	{
		m_xMSF = xMSF;
		m_xDocument = xDocument;
	}

	/* ------------------------------------------------------------------ */
	/** retrieves the current view of the document
		@return
			the view component, queried for the interface described by aInterfaceClass
	*/
	public DocumentViewHelper getCurrentView( )
	{
		// get the model interface for the document
		XModel xDocModel = (XModel)UnoRuntime.queryInterface(XModel.class, m_xDocument );
		// get the current controller for the document - as a controller is tied to a view,
		// this gives us the currently active view for the document.
		XController xController = xDocModel.getCurrentController();
		return new DocumentViewHelper( m_xMSF, this, xController );
	}

	/* ------------------------------------------------------------------ */
	/** classifies a document
	*/
	public DocumentType classify( )
	{
		XServiceInfo xSI = UNO.queryServiceInfo( m_xDocument );
		if ( xSI.supportsService( "com.sun.star.text.TextDocument" ) )
			return DocumentType.WRITER;
		else if ( xSI.supportsService( "com.sun.star.sheet.SpreadsheetDocument" ) )
			return DocumentType.CALC;
		else if ( xSI.supportsService( "com.sun.star.drawing.DrawingDocument" ) )
			return DocumentType.DRAWING;

		return DocumentType.UNKNOWN;
	}

	/* ------------------------------------------------------------------ */
	/** creates a new form which is a child of the given form components container

		@param xParentContainer
			The parent container for the new form
		@param sInitialName
			The initial name of the form. May be null, in this case the default (which
			is an implementation detail) applies.
	*/
	protected XIndexContainer createSubForm( XIndexContainer xParentContainer, String sInitialName )
		throws com.sun.star.uno.Exception
	{
		// create a new form
		Object xNewForm = m_xMSF.createInstance( "com.sun.star.form.component.DataForm" );

		// insert
		xParentContainer.insertByIndex( xParentContainer.getCount(), xNewForm );

		// set the name if necessary
		if ( null != sInitialName )
		{
			XPropertySet xFormProps = UNO.queryPropertySet( xNewForm );
			xFormProps.setPropertyValue( "Name", sInitialName );
		}

		// outta here
		return UNO.queryIndexContainer( xNewForm );
	}

	/* ------------------------------------------------------------------ */
	/** creates a new form which is a child of the given form components container

		@param aParentContainer
			The parent container for the new form
		@param sInitialName
			The initial name of the form. May be null, in this case the default (which
			is an implementation detail) applies.
	*/
	public XIndexContainer createSubForm( Object aParentContainer, String sInitialName )
		throws com.sun.star.uno.Exception
	{
		XIndexContainer xParentContainer = UNO.queryIndexContainer( aParentContainer );
		return createSubForm( xParentContainer, sInitialName );
	}

	/* ------------------------------------------------------------------ */
	/** creates a form which is a sibling of the given form

		@param aForm
			A sinbling of the to be created form.

		@param sInitialName
			The initial name of the form. May be null, in this case the default (which
			is an implementation detail) applies.
	*/
	public XIndexContainer createSiblingForm( Object aForm, String sInitialName ) throws com.sun.star.uno.Exception
	{
		// get the parent
		XIndexContainer xContainer = (XIndexContainer)FLTools.getParent(
			aForm, XIndexContainer.class );
		// append a new form to this parent container
		return createSubForm( xContainer, sInitialName );
	}

	/* ------------------------------------------------------------------ */
	/** retrieves the document model which a given form component belongs to
	*/
	static public DocumentHelper getDocumentForComponent( Object aFormComponent, XMultiServiceFactory xMSF )
	{
		XChild xChild = (XChild)UnoRuntime.queryInterface( XChild.class, aFormComponent );
		XModel xModel = null;
		while ( ( null != xChild ) && ( null == xModel ) )
		{
			XInterface xParent = (XInterface)xChild.getParent();
			xModel = (XModel)UnoRuntime.queryInterface( XModel.class, xParent );
			xChild = (XChild)UnoRuntime.queryInterface( XChild.class, xParent );
		}

		return new DocumentHelper( xMSF, xModel );
	}

	/* ------------------------------------------------------------------ */
	/** gets the <type scope="com.sun.star.drawing">DrawPage</type> of the document
	*/
	protected XDrawPage getMainDrawPage( ) throws com.sun.star.uno.Exception
	{
		XDrawPage xReturn;

		// in case of a Writer document, this is rather easy: simply ask the XDrawPageSupplier
		XDrawPageSupplier xSuppPage = (XDrawPageSupplier)UnoRuntime.queryInterface(
			XDrawPageSupplier.class, getDocument() );
		if ( null != xSuppPage )
			xReturn = xSuppPage.getDrawPage();
		else
		{	// the model itself is no draw page supplier - okay, it may be a Writer or Calc document
			// (or any other multi-page document)
			XDrawPagesSupplier xSuppPages = (XDrawPagesSupplier)UnoRuntime.queryInterface(
				XDrawPagesSupplier.class, getDocument() );
			XDrawPages xPages = xSuppPages.getDrawPages();

			xReturn = (XDrawPage)UnoRuntime.queryInterface( XDrawPage.class,
				xPages.getByIndex( 0 ) );

			// Note that this is no really error-proof code: If the document model does not support the
			// XDrawPagesSupplier interface, or if the pages collection returned is empty, this will break.
		}

		return xReturn;
	}

	/* ------------------------------------------------------------------ */
	/** retrieves the root of the hierarchy of form components
	*/
	protected XNameContainer getFormComponentTreeRoot( ) throws com.sun.star.uno.Exception
	{
		XFormsSupplier xSuppForms = (XFormsSupplier)UnoRuntime.queryInterface(
			XFormsSupplier.class, getMainDrawPage( ) );

		XNameContainer xFormsCollection = null;
		if ( null != xSuppForms )
		{
			xFormsCollection = xSuppForms.getForms();
		}
		return xFormsCollection;
	}
};

