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


import com.sun.star.beans.PropertyChangeEvent;
import com.sun.star.beans.XPropertyChangeListener;
import com.sun.star.beans.XPropertySet;


// __________ Imports __________
import com.sun.star.beans.XPropertySetInfo;

// base classes
import com.sun.star.container.XIndexContainer;
import com.sun.star.container.XNameAccess;
import com.sun.star.container.XNamed;
import com.sun.star.form.FormComponentType;
import com.sun.star.form.ListSourceType;
import com.sun.star.form.XGridColumnFactory;
import com.sun.star.form.XReset;
import com.sun.star.form.XResetListener;
import com.sun.star.form.runtime.FormFeature;
import com.sun.star.lang.EventObject;
import com.sun.star.lang.XComponent;
import com.sun.star.sdb.CommandType;
import com.sun.star.sdb.XColumnUpdate;
import com.sun.star.sdbc.ResultSetConcurrency;
import com.sun.star.sdbc.XConnection;
import com.sun.star.sdbc.XDataSource;
import com.sun.star.sdbc.XStatement;
import com.sun.star.sdbcx.XColumnsSupplier;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;

/**************************************************************************/
/** a class for enumerating a form component tree
*/
class PrintComponentTree extends ComponentTreeTraversal
{
	private String m_sPrefix;

	public PrintComponentTree()
	{
		m_sPrefix = new String();
	}

	public void handle( Object aFormComponent ) throws com.sun.star.uno.Exception
	{
		// the name of the child
		XNamed xName = (XNamed)UnoRuntime.queryInterface( XNamed.class, aFormComponent );

		// if it's a form control model, check it's type
		XPropertySet xProps = UNO.queryPropertySet( aFormComponent );
		String sTypeName = FLTools.classifyFormComponentType( xProps );

		String sName;
		if ( null == xName )
			sName = "<unnamed>";
		else
			sName = xName.getName();

		// print the component's name
		if ( 0 != sTypeName.length() )
		{
			System.out.println( m_sPrefix + sName + " (" + sTypeName + ")" );
		}
		else
		{
			System.out.println( m_sPrefix + sName );
		}

		// let the super class step down the tree
		m_sPrefix = m_sPrefix + " ";
		super.handle( aFormComponent );
		m_sPrefix = m_sPrefix.substring( 0, m_sPrefix.length() - 1 );
	}
};

/**************************************************************************/
/** a class revoking button models from a ButtonOperator instance
*/
class RevokeButtons extends ComponentTreeTraversal
{
	private ButtonOperator m_aOperator;

	public RevokeButtons( ButtonOperator aOperator )
	{
		m_aOperator = aOperator;
	}

	public void handle( Object aFormComponent ) throws com.sun.star.uno.Exception
	{
		// check if it's a button
		XPropertySet xProps = UNO.queryPropertySet( aFormComponent );
		XPropertySetInfo xPI = null;
		if ( null != xProps )
			xPI = xProps.getPropertySetInfo();
		if ( ( null != xPI ) && xPI.hasPropertyByName( "ClassId" ) )
		{
			Short nClassId = (Short)xProps.getPropertyValue( "ClassId" );
			if ( FormComponentType.COMMANDBUTTON == nClassId.shortValue() )
			{
				// yes, it is
				m_aOperator.revokeButton( xProps );
			}
		}

		// let the super class step down the tree (if possible)
		super.handle( aFormComponent );
	}
}

/**************************************************************************/
public class DataAwareness extends DocumentBasedExample implements XPropertyChangeListener, XResetListener
{
	/* ================================================================== */
    private HsqlDatabase            m_database;

    private static final String     s_tableNameSalesmen = "SALESMEN";
    private static final String     s_tableNameCustomers = "CUSTOMERS";
    private static final String     s_tableNameSales = "SALES";

	private XPropertySet			m_xMasterForm;
	private ButtonOperator			m_aOperator;
	private SalesFilter				m_aSalesFilter;

	private KeyGenerator			m_aSalesmanKeyGenerator;
	private KeyGenerator			m_aSalesKeyGenerator;
	private ControlLock				m_aSalesmenLocker;
	private	ControlLock				m_aSalesLocker;
	private	GridFieldValidator		m_aSalesNameValidator;

	private boolean					m_bDefaultSalesDate;
	private boolean					m_bProtectKeyFields;
	private boolean					m_bAllowEmptySales;

	/* ------------------------------------------------------------------ */
    public DataAwareness()
	{
        super( DocumentType.WRITER );
		m_bDefaultSalesDate = false;
		m_bProtectKeyFields = false;
		m_bAllowEmptySales = false;
	}

	/* ==================================================================
	   = form components
	   ================================================================== */

	/* ------------------------------------------------------------------ */
	/** enumerates and prints all the elements in the given container, together with the container itself
	*/
	protected void enumFormComponents( XNameAccess xContainer ) throws java.lang.Exception
	{
		String sObjectName;

		XNamed xNameAcc = (XNamed)UnoRuntime.queryInterface( XNamed.class, xContainer );
		if ( null == xNameAcc )
			sObjectName = new String( "<unnamed>" );
		else
			sObjectName = xNameAcc.getName();
		System.out.println( new String( "enumerating the container named \"" ) + sObjectName +
			new String( "\"\n" ) );

		PrintComponentTree aPrinter = new PrintComponentTree();
		aPrinter.handle( xContainer );
	}

	/* ------------------------------------------------------------------ */
	/** enumerates and prints all form elements in the document
	*/
	protected void enumFormComponents( ) throws java.lang.Exception
	{
		enumFormComponents( m_document.getFormComponentTreeRoot() );
	}

	/* ==================================================================
	   = UNO callbacks
	   ================================================================== */

	/* ------------------------------------------------------------------ */
	// XResetListener overridables
	/* ------------------------------------------------------------------ */
    public boolean approveReset( EventObject aEvent ) throws com.sun.star.uno.RuntimeException
	{
		// not interested in vetoing this
		return true;
	}

	/* ------------------------------------------------------------------ */
    public void resetted( EventObject aEvent ) throws com.sun.star.uno.RuntimeException
	{
		// check if this reset occured becase we're on a new record
		XPropertySet xFormProps = UNO.queryPropertySet(  aEvent.Source );
		try
		{
			Boolean aIsNew = (Boolean)xFormProps.getPropertyValue( "IsNew" );
			if ( aIsNew.booleanValue() )
			{	// yepp

				if ( !m_bDefaultSalesDate )
				{	// we're interested to do all this only if the user told us to default the sales date
					// to "today"
					// As date fields do this defaulting automatically, the semantics is inverted here:
					// If we're told to default, we must do nothing, if we should not default, we must
					// reset the value which the date field set automatically.

					Integer aConcurrency = (Integer)xFormProps.getPropertyValue( "ResultSetConcurrency" );
					if ( ResultSetConcurrency.READ_ONLY != aConcurrency.intValue() )
					{
						// we're going to modify the record, though after that, to the user, it should look
						// like it has not been modified
						// So we need to ensure that we do not change the IsModified property with whatever we do
						Object aModifiedFlag = xFormProps.getPropertyValue( "IsModified" );


						// get the columns of our master form
						XColumnsSupplier xSuppCols = (XColumnsSupplier)UnoRuntime.queryInterface(
							XColumnsSupplier.class, xFormProps );
						XNameAccess xCols = xSuppCols.getColumns();

						// and update the date column with a NULL value
						XColumnUpdate xDateColumn = (XColumnUpdate)UnoRuntime.queryInterface(
							XColumnUpdate.class, xCols.getByName( "SALEDATE" ) );
						xDateColumn.updateNull();


						// then restore the flag
						xFormProps.setPropertyValue( "IsModified", aModifiedFlag );
					}
				}
			}
		}
		catch( com.sun.star.uno.Exception e )
		{
			System.out.println(e);
			e.printStackTrace();
		}
	}

	/* ------------------------------------------------------------------ */
	// XPropertyChangeListener overridables
	/* ------------------------------------------------------------------ */
    public void propertyChange( PropertyChangeEvent aEvent ) throws com.sun.star.uno.RuntimeException
	{
		try
		{
			// did it come from a radio button or checkbox?
			if ( aEvent.PropertyName.equals( "State" ) )
			{	// yep
				Short aNewState = (Short)aEvent.NewValue;

				XPropertySet xModel = UNO.queryPropertySet( aEvent.Source );
				String sName = (String)xModel.getPropertyValue( "Name" );

				Short aClassId = (Short)xModel.getPropertyValue( "ClassId" );
				if ( FormComponentType.RADIOBUTTON == aClassId.shortValue() )
				{
					String sRefValue = (String)xModel.getPropertyValue( "RefValue" );

					short nNewValue = ((Short)aEvent.NewValue).shortValue();
					if ( sName.equals( "KeyGen" ) )
					{
						// it's one of the options for key generation
						if ( sRefValue.equals( "none" ) )
						{	// no automatic generation at all
							m_aSalesmanKeyGenerator.stopGenerator( );
							m_aSalesKeyGenerator.stopGenerator( );
						}
						else
						{
							boolean bGenerateOnReset = true;
							if ( sRefValue.equals( "update" ) )
							{	// generate on update
								bGenerateOnReset = ( 0 == nNewValue );
							}
							else if ( sRefValue.equals( "reset" ) )
							{	// generat on reset
								bGenerateOnReset = ( 0 != nNewValue );
							}
							m_aSalesmanKeyGenerator.activateKeyGenerator( bGenerateOnReset );
							m_aSalesKeyGenerator.activateKeyGenerator( bGenerateOnReset );
						}
					}
				}
				else if ( FormComponentType.CHECKBOX == aClassId.shortValue() )
				{
					boolean bEnabled = ( 0 != aNewState.shortValue() );
					if ( sName.equals( "defaultdate" ) )
					{
						m_bDefaultSalesDate = bEnabled;
					}
					else if ( sName.equals( "protectkeys" ) )
					{
						m_bProtectKeyFields = bEnabled;
						m_aSalesmenLocker.enableLock( m_bProtectKeyFields );
						m_aSalesLocker.enableLock( m_bProtectKeyFields );
					}
					else if ( sName.equals( "emptysales" ) )
					{
						m_bAllowEmptySales = bEnabled;
						m_aSalesNameValidator.enableColumnWatch( m_bAllowEmptySales );
					}
				}
			}
		}
		catch(com.sun.star.uno.Exception e)
		{
			System.out.println(e);
			e.printStackTrace();
		}
	}

	/* ------------------------------------------------------------------ */
	// XEventListener overridables
	/* ------------------------------------------------------------------ */
	public void disposing( EventObject aEvent )
	{
        // simply disambiguate
        super.disposing( aEvent );
	}

	/* ==================================================================
	   = miscellaneous
	   ================================================================== */

	/* ------------------------------------------------------------------ */
	/** skips line feeds in the input stream

		@returns
			the first character which does not belong to a line feed
	*/
	protected int skipLineFeeds( java.io.InputStream aInput ) throws java.io.IOException
	{
		// read characters, until we encounter something which is not a line feed character
		int nChar = aInput.read( );
		while ( ( 13 == nChar ) || ( 10 == nChar ) )
			nChar = aInput.read( );

		// now read everything which is behind this single character we are interested in
		while ( 0 < aInput.available() )
			aInput.read( );

		return nChar;
	}

	/* ==================================================================
	   = table handling
	   ================================================================== */
	/* ------------------------------------------------------------------ */
	/** checks if a given table exists.

		<p>The check is made using a SELECT statement, so even if the connection
		is a n SDB-level connection, which may filter tables in it's table
		supplier, the result may be reliable ....</p>
	*/
	protected boolean existsInvisibleTable( XConnection xConn, String sTableName ) throws java.lang.Exception
	{
		String sStatement = "SELECT * FROM ";
		sStatement += sTableName;
		sStatement += " WHERE 0=1";

		boolean bSuccess = false;
		try
		{
			XStatement xStatement = xConn.createStatement();
			xStatement.execute( sStatement );
			// if we reached this point, the table probably exists
			bSuccess = true;
		}
		catch(com.sun.star.sdbc.SQLException e)
		{
		}
		return bSuccess;
	}

	/* ------------------------------------------------------------------ */
	/** add a specified table name to the table filter of the given data source.
	*/
	protected void makeTableVisible( XDataSource xDS, XConnection xConn, String sTableName ) throws java.lang.Exception
	{
		// get the table filter
		XPropertySet xDSP = UNO.queryPropertySet( xDS );
		String[] aCurrentFilter = (String[])xDSP.getPropertyValue( "TableFilter" );

		// check if the table name is already part of it
		String sAllTables = "*";												// all tables

		for ( int i=0; i<aCurrentFilter.length; ++i )
		{
			String sCurrentTableFilter = aCurrentFilter[i];

			if ( sCurrentTableFilter.equals( sTableName ) )
				return;
			if ( sCurrentTableFilter.equals( sAllTables ) )
				return;
		}

		// if we are here, we have to add our table to the filter sequence
		String[] aNewFilter = new String[ aCurrentFilter.length + 1 ];
		// copy the existent filter entries
		for ( int i=0; i<aCurrentFilter.length; ++i )
			aNewFilter[i] = aCurrentFilter[i];
		// add our table
		aNewFilter[ aCurrentFilter.length ] = sTableName;

		xDSP.setPropertyValue( "TableFilter", aNewFilter );
	}

	/* ------------------------------------------------------------------ */
	/** executes the given statement on the given connection
	*/
	protected boolean implExecuteStatement( XConnection xConn, String sStatement ) throws java.lang.Exception
	{
		try
		{
			XStatement xStatement = xConn.createStatement( );
			xStatement.execute( sStatement );
		}
		catch(com.sun.star.sdbc.SQLException e)
		{
			System.err.println( e );
			return false;
		}

		return true;
	}

	/* ------------------------------------------------------------------ */
	/** creates the table witht the given name, using the given statement
	*/
	protected boolean implCreateTable( XConnection xConn, String sCreateStatement, String sTableName ) throws java.lang.Exception
	{
		if ( !implExecuteStatement( xConn, sCreateStatement ) )
		{
			System.out.println( "  could not create the table " + sTableName + "." );
			System.out.println( );
			return false;
		}

		return true;
	}

	/* ------------------------------------------------------------------ */
	/** creates the table SALESMEN

		@return
			<TRUE/> if and only if the creation succeeded
	*/
	protected boolean createTableSalesman( XConnection xConn ) throws java.lang.Exception
	{
		String sCreateStatement = "CREATE TABLE " + s_tableNameSalesmen + " ";
		sCreateStatement += "(SNR INTEGER NOT NULL, ";
		sCreateStatement += "FIRSTNAME VARCHAR(50), ";
		sCreateStatement += "LASTNAME VARCHAR(100), ";
		sCreateStatement += "STREET VARCHAR(50), ";
		sCreateStatement += "STATE VARCHAR(50), ";
		sCreateStatement += "ZIP INTEGER, ";
		sCreateStatement += "BIRTHDATE DATE, ";
		sCreateStatement += "PRIMARY KEY(SNR))";

		if ( implCreateTable( xConn, sCreateStatement, s_tableNameSalesmen) )
		{
			String sInsertionPrefix = "INSERT INTO " + s_tableNameSalesmen + " VALUES ";

			implExecuteStatement( xConn, sInsertionPrefix + "(1, 'Joseph', 'Smith', 'Bond Street', 'CA', 95460, '1946-07-02')" );
			implExecuteStatement( xConn, sInsertionPrefix + "(2, 'Frank', 'Jones', 'Lake silver', 'CA', 95460, '1963-12-24')" );
			implExecuteStatement( xConn, sInsertionPrefix + "(3, 'Jane', 'Esperansa', '23 Hollywood driver', 'CA', 95460, '1972-04-01')" );

			return true;
		}
		return false;
	}

	/* ------------------------------------------------------------------ */
	/** creates the table CUSTOMERS

		@return
			<TRUE/> if and only if the creation succeeded
	*/
	protected boolean createTableCustomer( XConnection xConn ) throws java.lang.Exception
	{
		String sCreateStatement = "CREATE TABLE " + s_tableNameCustomers + " ";
		sCreateStatement += "(COS_NR INTEGER NOT NULL, ";
		sCreateStatement += "LASTNAME VARCHAR(100), ";
		sCreateStatement += "STREET VARCHAR(50), ";
		sCreateStatement += "CITY VARCHAR(50), ";
		sCreateStatement += "STATE VARCHAR(50), ";
		sCreateStatement += "ZIP INTEGER, ";
		sCreateStatement += "PRIMARY KEY(COS_NR))";

		if ( implCreateTable( xConn, sCreateStatement, s_tableNameCustomers ) )
		{
			String sInsertionPrefix = "INSERT INTO " + s_tableNameCustomers + " VALUES ";

			implExecuteStatement( xConn, sInsertionPrefix + "(100, 'Acme, Inc.', '99 Market Street', 'Groundsville', 'CA', 95199)" );
			implExecuteStatement( xConn, sInsertionPrefix + "(101, 'Superior BugSoft', '1 Party Place', 'Mendocino', 'CA', 95460)");
			implExecuteStatement( xConn, sInsertionPrefix + "(102, 'WeKnowAll, Inc.', '100 Coffee Lane', 'Meadows', 'CA', 93699)");

			return true;
		}
		return false;
	}

	/* ------------------------------------------------------------------ */
	/** creates the table SALES

		@return
			<TRUE/> if and only if the creation succeeded
	*/
	protected boolean createTableSales( XConnection xConn ) throws java.lang.Exception
	{
		String sCreateStatement = "CREATE TABLE " + s_tableNameSales + " ";
		sCreateStatement += "(SALENR INTEGER NOT NULL, ";
		sCreateStatement += "COS_NR INTEGER NOT NULL, ";
		sCreateStatement += "SNR INTEGER NOT NULL, ";
		sCreateStatement += "NAME VARCHAR(50), ";
		sCreateStatement += "SALEDATE DATE, ";
		sCreateStatement += "PRICE DECIMAL(8,2), ";
		sCreateStatement += "PRIMARY KEY(SALENR))";

		if ( implCreateTable( xConn, sCreateStatement, s_tableNameSales ) )
		{
			String sInsertionPrefix = "INSERT INTO " + s_tableNameSales + " VALUES ";

			implExecuteStatement( xConn, sInsertionPrefix + "(1, 100, 1, 'Fruits', '2005-02-12', 39.99)" );
			implExecuteStatement( xConn, sInsertionPrefix + "(2, 101, 3, 'Beef', '2005-10-18', 15.78)" );
			implExecuteStatement( xConn, sInsertionPrefix + "(3, 102, 3, 'Orange Juice', '2005-09-08', 25.63)" );
			implExecuteStatement( xConn, sInsertionPrefix + "(4, 101, 2, 'Oil', '2005-03-01', 12.30)" );

			return true;
		}

		return false;
	}

	/* ------------------------------------------------------------------ */
	/** ensures that the tables we need for our example exist
	*/
	protected void ensureTables() throws java.lang.Exception
	{
		// get the data source
		XDataSource xDS = m_database.getDataSource();
		XPropertySet xDSProps = UNO.queryPropertySet( xDS );

		// connect to this data source
		XConnection xConn = xDS.getConnection( "", "" );
		XComponent xConnComp = UNO.queryComponent( xConn );

        createTableSalesman( xConn );
        createTableCustomer( xConn );
        createTableSales( xConn );

        // free the resources acquired by the connection
		xConnComp.dispose();
	}

	/* ==================================================================
	   = sample document handling
	   ================================================================== */

	/* ------------------------------------------------------------------ */
	/** creates the button used for demonstrating (amonst others) event handling
		@param nXPos
			x-position of the to be inserted shape
		@param nYPos
			y-position of the to be inserted shape
		@param nXSize
			width of the to be inserted shape
		@param sName
			the name of the model in the form component hierarchy
		@param sLabel
			the label of the button control
		@param sActionURL
			the URL of the action which should be triggered by the button
		@return
			the model of the newly created button
	*/
	protected XPropertySet createButton( int nXPos, int nYPos, int nXSize, String sName, String sLabel, short _formFeature ) throws java.lang.Exception
	{
		XPropertySet xButton = m_formLayer.createControlAndShape( "CommandButton", nXPos, nYPos, nXSize, 6 );
		// the name for referring to it later:
		xButton.setPropertyValue( "Name", sName );
		// the label
		xButton.setPropertyValue( "Label", sLabel );
		// use the name as help text
		xButton.setPropertyValue( "HelpText", sName );
		// don't want buttons to be accessible by the "tab" key - this would be uncomfortable when traveling
		// with records with "tab"
		xButton.setPropertyValue( "Tabstop", new Boolean( false ) );
        // similar, they should not steal the focus when clicked
		xButton.setPropertyValue( "FocusOnClick", new Boolean( false ) );

		m_aOperator.addButton( xButton, _formFeature );

		return xButton;
	}

	/* ------------------------------------------------------------------ */
	/** creates a column in a grid
		@param xGridModel
			specifies the model of the grid where the new column should be inserted
		@param sColumnService
			specifies the service name of the column to create (e.g. "NumericField")
		@param sDataField
			specifies the database field to which the column should be bound
		@param nWidth
			specifies the column width (in mm). If 0, no width is set.
		@return
			the newly created column
	*/
	XPropertySet createGridColumn( Object aGridModel, String sColumnService, String sDataField, int nWidth )
		throws com.sun.star.uno.Exception
	{
		// the container to insert columns into
		XIndexContainer xColumnContainer = UNO.queryIndexContainer( aGridModel );
		// the factory for creating column models
		XGridColumnFactory xColumnFactory = (XGridColumnFactory)UnoRuntime.queryInterface(
			XGridColumnFactory.class, aGridModel );

		// (let) create the new col
		XInterface xNewCol = (XInterface)xColumnFactory.createColumn( sColumnService );
		XPropertySet xColProps = UNO.queryPropertySet( xNewCol );

		// some props
		// the field the column is bound to
		xColProps.setPropertyValue( "DataField", sDataField );
		// the "display name" of the column
		xColProps.setPropertyValue( "Label", sDataField );
		// the name of the column within it's parent
		xColProps.setPropertyValue( "Name", sDataField );

		if ( nWidth > 0 )
			xColProps.setPropertyValue( "Width", new Integer( nWidth * 10 ) );

		// insert
		xColumnContainer.insertByIndex( xColumnContainer.getCount(), xNewCol );

		// outta here
		return xColProps;
	}

	/* ------------------------------------------------------------------ */
	/** creates a column in a grid
	*/
	XPropertySet createGridColumn( Object aGridModel, String sColumnService, String sDataField )
		throws com.sun.star.uno.Exception
	{
		return createGridColumn( aGridModel, sColumnService, sDataField );
	}

	/* ------------------------------------------------------------------ */
	/** creates our sample document
	*/
    protected void prepareDocument() throws com.sun.star.uno.Exception, java.lang.Exception
	{
        super.prepareDocument();

        m_database = new HsqlDatabase( m_xCtx );

        // ensure that we have the tables needed for our example
        ensureTables();

        // --------------------------------------------------------------
		/* create some shapes */
		XPropertySet xSNRField =	m_formLayer.insertControlLine( "NumericField", "SNR", "", 3 );
                                    m_formLayer.insertControlLine( "TextField", "FIRSTNAME", "", 11);
                                    m_formLayer.insertControlLine( "TextField", "LASTNAME", "", 19 );
                                    m_formLayer.insertControlLine( "TextField", "STREET", "", 27 );
                                    m_formLayer.insertControlLine( "TextField", "STATE", "", 35 );
        XPropertySet xZipField =    m_formLayer.insertControlLine( "NumericField", "ZIP", "", 43 );
                                    m_formLayer.insertControlLine( "FormattedField", "BIRTHDATE", "", 51 );

		// for the salesman number / zip code, we don't want to have decimal places:
		xSNRField.setPropertyValue( "DecimalAccuracy", new Short( (short)0 ) );
		xZipField.setPropertyValue( "DecimalAccuracy", new Short( (short)0 ) );

        // --------------------------------------------------------------
		/** need the form the control models belong to
			for this, we simply obtain the parent for any of the control models we have

			Note that this involves knowledge about the implementation: If a control shape is
			inserted into a document, where the control model does not belong to the form component
			hierarchy, yet, it is automatically inserted into the first form, which is created
			if necessary.
		*/
		m_xMasterForm = FLTools.getParent( xZipField );

		// set the data source signature at the form
		m_xMasterForm.setPropertyValue( "DataSourceName", m_database.getDocumentURL() );
		m_xMasterForm.setPropertyValue( "CommandType", new Integer( CommandType.TABLE ) );
		m_xMasterForm.setPropertyValue( "Command", "SALESMEN" );

        // --------------------------------------------------------------
		// insert the buttons
		// create our button operator, if necessary
        m_aOperator = new ButtonOperator( m_xCtx, m_document, m_xMasterForm );

		createButton( 2, 63, 8, "first", "<<", FormFeature.MoveToFirst );
		createButton( 12, 63, 8, "prev", "<", FormFeature.MoveToPrevious );
		createButton( 22, 63, 8, "next", ">", FormFeature.MoveToNext );
		createButton( 32, 63, 8, "last", ">>", FormFeature.MoveToLast );
		createButton( 42, 63, 8, "new", ">*", FormFeature.MoveToInsertRow );
		createButton( 58, 63, 13, "reload", "reload", FormFeature.ReloadForm );

        // --------------------------------------------------------------
		// create a sub for for the sales

		// for this, first create a sub form and bind it to the SALES table
		XIndexContainer xSalesForm = m_document.createSubForm( m_xMasterForm, "Sales" );
		XPropertySet xSalesFormProps = UNO.queryPropertySet( xSalesForm );

		xSalesFormProps.setPropertyValue( "DataSourceName", m_database.getDocumentURL() );
		xSalesFormProps.setPropertyValue( "CommandType", new Integer( CommandType.COMMAND ) );

		String sCommand = new String( "SELECT * FROM " );
		sCommand += s_tableNameSales;
		sCommand += " WHERE " + s_tableNameSales + ".SNR = :salesmen";
		xSalesFormProps.setPropertyValue( "Command", sCommand );

		// the master-details connection
		String[] aMasterFields = new String[] { "SNR" };		// the field in the master form
		String[] aDetailFields = new String[] { "salesmen" };	// the name in the detail form
		xSalesFormProps.setPropertyValue( "MasterFields", aMasterFields );
		xSalesFormProps.setPropertyValue( "DetailFields", aDetailFields );

		// the create thr grid model
        XPropertySet xSalesGridModel = m_formLayer.createControlAndShape( "GridControl", 2, 80, 162, 40, xSalesForm );
		xSalesGridModel.setPropertyValue( "Name", "SalesTable" );
		XPropertySet xKeyColumn		 =	createGridColumn( xSalesGridModel, "NumericField", "SALENR", 12 );
		XPropertySet xCustomerColumn =	createGridColumn( xSalesGridModel, "ListBox", "COS_NR", 40 );
		XPropertySet xSalesNameColumn =	createGridColumn( xSalesGridModel, "TextField", "NAME", 25 );
										createGridColumn( xSalesGridModel, "DateField", "SALEDATE", 24 );
										createGridColumn( xSalesGridModel, "CurrencyField", "PRICE", 16 );

			// please note that a better solution for the SALEDATE field would have been to use
			// a FormattedField. But we want to demonstrate some effects with DateFields here ...

		m_aSalesNameValidator = new GridFieldValidator( m_xCtx, xSalesNameColumn );
		m_aSalesNameValidator.enableColumnWatch( m_bAllowEmptySales );

		xKeyColumn.setPropertyValue( "DecimalAccuracy", new Short( (short)0 ) );

		// init the list box which is for choosing the customer a sale belongs to
		xCustomerColumn.setPropertyValue( "BoundColumn", new Short( (short)1 ) );
		xCustomerColumn.setPropertyValue( "Label", "Customer" );
		xCustomerColumn.setPropertyValue( "ListSourceType", ListSourceType.SQL );

		String sListSource = "SELECT LASTNAME, COS_NR FROM ";
		sListSource += s_tableNameCustomers;
		String[] aListSource = new String[] { sListSource };
		xCustomerColumn.setPropertyValue( "ListSource", aListSource );

		// We want to demonstrate how to reset fields to NULL, we do this with the SALEDATE field
		// above. For this, we add as reset listener to the form
		XReset xFormReset = UNO.queryReset( xSalesForm );
		xFormReset.addResetListener( this );


        // --------------------------------------------------------------
		// the option for filtering the sales form
		XIndexContainer xSalesFilterForm = m_document.createSiblingForm( xSalesForm, "SalesFilter" );
		XPropertySet xSFFProps = UNO.queryPropertySet( xSalesFilterForm );
        XPropertySet xLabel = m_formLayer.createControlAndShape( "FixedText", 2, 125, 35, 6, xSalesFilterForm );
		xLabel.setPropertyValue( "Label", "show only sales since" );
		xLabel.setPropertyValue( "Name", "FilterLabel" );

        XPropertySet xFilterSelection = m_formLayer.createControlAndShape( "ListBox", 40, 125, 59, 6, xSalesFilterForm );
		xFilterSelection.setPropertyValue( "Name", "FilterList" );
		xFilterSelection.setPropertyValue( "LabelControl", xLabel );
        XPropertySet xManualFilter = m_formLayer.createControlAndShape( "DateField", 104, 125, 30, 6, xSalesFilterForm );
		xManualFilter.setPropertyValue( "Name", "ManualFilter" );
        XPropertySet xApplyFilter = m_formLayer.createControlAndShape( "CommandButton", 139, 125, 25, 6, xSalesFilterForm );
		xApplyFilter.setPropertyValue( "Name", "ApplyFilter" );
		xApplyFilter.setPropertyValue( "DefaultButton", new Boolean( true ) );
		m_aSalesFilter = new SalesFilter( m_document, xSalesFormProps, xFilterSelection,
			xManualFilter, xApplyFilter );


        // --------------------------------------------------------------
		// the options section
		// for this, we need a form which is a sibling of our master form (don't want to interfere
		// the controls which represent options only with the controls which are used for data access)

		XIndexContainer xOptionsForm = m_document.createSiblingForm( m_xMasterForm, "Options" );

        xLabel = m_formLayer.createControlAndShape( "GroupBox", 98, 0, 66, 62, xOptionsForm );
		xLabel.setPropertyValue( "Name", "Options" );
		xLabel.setPropertyValue( "Label", "Options" );

		// radio buttons which controls how we generate unique keys
        xLabel = m_formLayer.createControlAndShape( "GroupBox", 103, 5, 56, 25, xOptionsForm );
		xLabel.setPropertyValue( "Label", "key generation" );
		xLabel.setPropertyValue( "Name", "KeyGeneration" );
        XPropertySet xKeyGen = m_formLayer.createControlAndShape( "RadioButton", 106, 11, 50, 6, xOptionsForm );
		xKeyGen.setPropertyValue( "Name", "KeyGen" );
		xKeyGen.setPropertyValue( "Label", "no automatic generation" );
		xKeyGen.setPropertyValue( "RefValue", "none" );
		xKeyGen.addPropertyChangeListener( "State", this );

        xKeyGen = m_formLayer.createControlAndShape( "RadioButton", 106, 17, 50, 6, xOptionsForm );
		xKeyGen.setPropertyValue( "Name", "KeyGen" );
		xKeyGen.setPropertyValue( "Label", "before inserting a record" );
		xKeyGen.setPropertyValue( "RefValue", "update" );
		xKeyGen.addPropertyChangeListener( "State", this );

        xKeyGen = m_formLayer.createControlAndShape( "RadioButton", 106, 23, 50, 6, xOptionsForm );
		xKeyGen.setPropertyValue( "Name", "KeyGen" );
		xKeyGen.setPropertyValue( "Label", "when moving to a new record" );
		xKeyGen.setPropertyValue( "RefValue", "reset" );
		xKeyGen.addPropertyChangeListener( "State", this );

		// initialize listeners
		// master form - key generation
		m_aSalesmanKeyGenerator = new KeyGenerator( m_xMasterForm, "SNR", m_xCtx );
		m_aSalesmanKeyGenerator.activateKeyGenerator( true );
		// master form - control locking
		m_aSalesmenLocker = new ControlLock( m_xMasterForm, "SNR" );
		m_aSalesmenLocker.enableLock( m_bProtectKeyFields );

		// details form - key generation
		m_aSalesKeyGenerator = new KeyGenerator( xSalesFormProps, "SALENR", m_xCtx );
		m_aSalesKeyGenerator.activateKeyGenerator( true );

		// details form - control locking
		m_aSalesLocker = new ControlLock( xSalesFormProps, "SALENR" );
		m_aSalesLocker.enableLock( m_bProtectKeyFields );

		// initally, we want to generate keys when moving to a new record
		xKeyGen.setPropertyValue( "DefaultState", new Short( (short)1 ) );

        // --------------------------------------------------------------
		// second options block
        xLabel = m_formLayer.createControlAndShape( "GroupBox", 103, 33, 56, 25, xOptionsForm  );
		xLabel.setPropertyValue( "Name", "Misc" );
		xLabel.setPropertyValue( "Label", "Miscellaneous" );

        XPropertySet xCheck = m_formLayer.createControlAndShape( "CheckBox", 106, 39, 60, 6, xOptionsForm  );
		xCheck.setPropertyValue( "Name", "defaultdate" );
		xCheck.setPropertyValue( "Label", "default sales date to \"today\"" );
        xCheck.setPropertyValue( "HelpText", "When checked, newly entered sales records are pre-filled with today's date, else left empty." );
		xCheck.addPropertyChangeListener( "State", this );

        xCheck = m_formLayer.createControlAndShape( "CheckBox", 106, 45, 60, 6, xOptionsForm  );
		xCheck.setPropertyValue( "Name", "protectkeys" );
		xCheck.setPropertyValue( "Label", "protect key fields from editing" );
        xCheck.setPropertyValue( "HelpText", "When checked, you cannot modify the values in the table's key fields (SNR and SALENR)" );
		xCheck.addPropertyChangeListener( "State", this );

        xCheck = m_formLayer.createControlAndShape( "CheckBox", 106, 51, 60, 6, xOptionsForm  );
		xCheck.setPropertyValue( "Name", "emptysales" );
		xCheck.setPropertyValue( "Label", "check for empty sales names" );
        xCheck.setPropertyValue( "HelpText", "When checked, you cannot enter empty values into the NAME column of the 'Sales' table." );
		xCheck.addPropertyChangeListener( "State", this );

        // dump the form component tree
        enumFormComponents( );
	}

	/* ------------------------------------------------------------------ */
    protected void onFormsAlive()
    {
        m_aOperator.onFormsAlive();
    }

	/* ------------------------------------------------------------------ */
	/** performs any cleanup before exiting the program
	*/
	protected void cleanUp( ) throws java.lang.Exception
	{
		// remove the listeners at the buttons
		RevokeButtons aRevoke = new RevokeButtons( m_aOperator );
		aRevoke.handle( m_document.getFormComponentTreeRoot( ) );

		// remove the key generator listeners from the form
		m_aSalesmanKeyGenerator.stopGenerator( );
		m_aSalesKeyGenerator.stopGenerator( );

		// and the control lockers
		m_aSalesmenLocker.enableLock( false );
		m_aSalesLocker.enableLock( false );

		// the validator for the grid column
		m_aSalesNameValidator.enableColumnWatch( false );

		// remove our own reset listener from the form
		XNameAccess xMasterAsNames = (XNameAccess)UnoRuntime.queryInterface(
			XNameAccess.class, m_xMasterForm );
		XReset xFormReset = UNO.queryReset( xMasterAsNames.getByName( "Sales" ) );
		xFormReset.removeResetListener( this );

        super.cleanUp();
	}

	/* ------------------------------------------------------------------ */
	/** class entry point
	*/
	public static void main(String argv[]) throws java.lang.Exception
	{
        DataAwareness aSample = new DataAwareness();
		aSample.run( argv );
	}
}
