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


// java base stuff
import com.sun.star.awt.ActionEvent;
import com.sun.star.awt.XActionListener;
import com.sun.star.awt.XButton;
import com.sun.star.beans.XPropertySet;
import com.sun.star.form.runtime.FormOperations;
import com.sun.star.form.runtime.XFeatureInvalidation;
import com.sun.star.form.runtime.XFormOperations;
import com.sun.star.lang.EventObject;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import java.util.Vector;


/**************************************************************************/
/** a helper class for operating the buttons
*/
public class ButtonOperator implements XActionListener, XFeatureInvalidation
{
	private XComponentContext	m_componentContext;
	private DocumentHelper		m_aDocument;
    private XPropertySet        m_form;
    private XFormOperations     m_formOperations;

	private Vector				m_aButtons;

	/* ------------------------------------------------------------------ */
	/** ctor
	*/
	public ButtonOperator( XComponentContext xCtx, DocumentHelper aDocument, XPropertySet _form )
	{
		m_componentContext = xCtx;
		m_aDocument = aDocument;
        m_form = _form;
		m_aButtons = new Vector();
	}

	/* ------------------------------------------------------------------ */
    private short getAssociatedFormFeature( XPropertySet _buttonModel )
	{
		short formFeature = -1;
		try
		{
            formFeature = Short.valueOf( (String)_buttonModel.getPropertyValue( "Tag" ) );
		}
		catch( com.sun.star.uno.Exception e )
		{
		}
		return formFeature;
	}

	/* ------------------------------------------------------------------ */
	/** get's the button which we operate and which is responsible for a given URL
	*/
	private XPropertySet getButton( short _formFeature )
	{
		for ( int i=0; i < m_aButtons.size(); ++i )
		{
            XPropertySet button = (XPropertySet)m_aButtons.elementAt( i );
			if ( _formFeature == getAssociatedFormFeature( button ) )
				return button;
		}
		return null;
	}

	/* ------------------------------------------------------------------ */
	/** announces a button which the operator should be responsible for
	*/
	private int getButtonIndex( XPropertySet xButton )
	{
		int nPos = -1;
		for ( int i=0; ( i < m_aButtons.size() ) && ( -1 == nPos ); ++i )
		{
			if ( xButton.equals( m_aButtons.elementAt( i ) ) )
				nPos = i;
		}
		return nPos;
	}

	/* ------------------------------------------------------------------ */
	/** announces a button which the operator should be responsible for
	*/
	public void addButton( XPropertySet _buttonModel, short _formFeature  ) throws java.lang.Exception
	{
		// the current view to the document
		DocumentViewHelper aCurrentView = m_aDocument.getCurrentView();

		// add a listener so we get noticed if the user presses the button
		XButton xButtonControl = (XButton)UnoRuntime.queryInterface( XButton.class,
			aCurrentView.getFormControl( _buttonModel ) );
		xButtonControl.addActionListener( this );

        _buttonModel.setPropertyValue( "Tag", String.valueOf( _formFeature ) );

		// remember the button
		m_aButtons.add( _buttonModel );
	}

	/* ------------------------------------------------------------------ */
	public void revokeButton( XPropertySet xButtonModel )
	{
		int nPos = getButtonIndex( xButtonModel );
		if ( -1 < nPos )
		{
			m_aButtons.remove( nPos );
		}
	}

	/* ==================================================================
	   = XActionListener
	   ================================================================== */
	/* ------------------------------------------------------------------ */
	/* called when a button has been pressed
	*/
    public void actionPerformed( ActionEvent aEvent ) throws com.sun.star.uno.RuntimeException
	{
		// get the model's name
        XPropertySet buttonModel = (XPropertySet)FLTools.getModel( aEvent.Source, XPropertySet.class );
        try
        {
            short formFeature = getAssociatedFormFeature( buttonModel );
            if ( formFeature != -1 )
                m_formOperations.execute( formFeature );
        }
        catch( final com.sun.star.uno.Exception e )
        {
        }
	}

	/* ------------------------------------------------------------------ */
	/* (to be) called when the form layer has been switched to alive mode
     * @todo
     *  register as listener somewhere ...
	*/
    public void onFormsAlive()
    {
        try
        {
            m_formOperations = FormOperations.createWithFormController(
                m_componentContext, m_aDocument.getCurrentView().getFormController( m_form ) );
            m_formOperations.setFeatureInvalidation( this );
            invalidateAllFeatures();
        }
        catch( final com.sun.star.uno.Exception e )
        {
        }
    }

	/* ==================================================================
	   = XEventListener
	   ================================================================== */
	public void disposing( EventObject aEvent )
	{
		// not interested in
	}

	/* ==================================================================
	   = XFeatureInvalidation
	   ================================================================== */
    private void updateButtonState( XPropertySet _buttonModel, short _formFeature )
    {
        try
        {
            _buttonModel.setPropertyValue( "Enabled", m_formOperations.isEnabled( _formFeature ) );
        }
        catch( com.sun.star.uno.Exception e )
        {
        }
    }

    public void invalidateFeatures( short[] _features ) throws com.sun.star.uno.RuntimeException
    {
        for ( int i=0; i<_features.length; ++i )
        {
            XPropertySet buttonModel = getButton( _features[i] );
            if ( buttonModel != null )
                updateButtonState( buttonModel, _features[i] );
        }
    }

    public void invalidateAllFeatures() throws com.sun.star.uno.RuntimeException
    {
		for ( int i=0; i < m_aButtons.size(); ++i )
		{
            XPropertySet buttonModel = (XPropertySet)m_aButtons.elementAt( i );
            updateButtonState( buttonModel, getAssociatedFormFeature( buttonModel ) );
		}
    }
};

