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



// __________ Imports __________

import java.util.Random;

// base classes
import com.sun.star.uno.XInterface;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.lang.*;

// factory for creating components
import com.sun.star.comp.servicemanager.ServiceManager;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.bridge.XUnoUrlResolver;
import com.sun.star.uno.XNamingService;
import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XComponentLoader;

// property access
import com.sun.star.beans.*;

// container access
import com.sun.star.container.*;

// application specific classes
import com.sun.star.sheet.*;
import com.sun.star.table.*;
import com.sun.star.chart.*;
import com.sun.star.text.XText;

import com.sun.star.document.XEmbeddedObjectSupplier;
import com.sun.star.frame.XModel;
import com.sun.star.frame.XController;

// base graphics things
import com.sun.star.awt.Point;
import com.sun.star.awt.Size;
import com.sun.star.awt.Rectangle;

// Exceptions
import com.sun.star.uno.RuntimeException;
import com.sun.star.container.NoSuchElementException;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.lang.IndexOutOfBoundsException;

// __________ Implementation __________

/** Helper for accessing a calc document
    @author Bj&ouml;rn Milcke
 */
public class CalcHelper
{
    public CalcHelper( XSpreadsheetDocument aDoc )
    {
        maSpreadSheetDoc = aDoc;
        initSpreadSheet();
    }

    // ____________________

    public XSpreadsheet getChartSheet() throws RuntimeException
    {
        XNameAccess aSheetsNA = (XNameAccess) UnoRuntime.queryInterface(
            XNameAccess.class, maSpreadSheetDoc.getSheets() );

        XSpreadsheet aSheet = null;
        try
        {
            aSheet = (XSpreadsheet) UnoRuntime.queryInterface(
                XSpreadsheet.class, aSheetsNA.getByName( msChartSheetName ) );
        }
        catch( NoSuchElementException ex )
        {
            System.out.println( "Couldn't find sheet with name " + msChartSheetName + ": " + ex );
        }
        catch( Exception ex )
        {}
        
        return aSheet;
    }

    // ____________________

    public XSpreadsheet getDataSheet() throws RuntimeException
    {
        XNameAccess aSheetsNA = (XNameAccess) UnoRuntime.queryInterface(
            XNameAccess.class, maSpreadSheetDoc.getSheets() );

        XSpreadsheet aSheet = null;
        if( aSheetsNA != null )
        {
            try
            {
                aSheet = (XSpreadsheet) UnoRuntime.queryInterface(
                    XSpreadsheet.class, aSheetsNA.getByName( msDataSheetName ) );
            }
            catch( NoSuchElementException ex )
            {
                System.out.println( "Couldn't find sheet with name " + msDataSheetName + ": " + ex );
            }
            catch( Exception ex )
            {}
        }

        return aSheet;
    }

    // ____________________

    /** Insert a chart using the given name as name of the OLE object and the range as correspoding
        range of data to be used for rendering.  The chart is placed in the sheet for charts at
        position aUpperLeft extending as large as given in aExtent.

        The service name must be the name of a diagram service that can be instantiated via the
        factory of the chart document
     */
    public XChartDocument insertChart(
        String               sChartName,
        CellRangeAddress     aRange,
        Point                aUpperLeft,
        Size                 aExtent,
        String               sChartServiceName )
    {
        XChartDocument aResult = null;
        XTableChartsSupplier aSheet;

        // get the sheet to insert the chart
        try
        {
            aSheet = (XTableChartsSupplier) UnoRuntime.queryInterface(
                XTableChartsSupplier.class, getChartSheet() );
        }
        catch( Exception ex )
        {
            System.out.println( "Sheet not found" + ex );
            return aResult;
        }

        XTableCharts aChartCollection = aSheet.getCharts();
        XNameAccess  aChartCollectionNA = (XNameAccess) UnoRuntime.queryInterface(
            XNameAccess.class, aChartCollection );

        if( aChartCollectionNA != null &&
            ! aChartCollectionNA.hasByName( sChartName ) )
        {
            Rectangle aRect = new Rectangle( aUpperLeft.X, aUpperLeft.Y, aExtent.Width, aExtent.Height );

            CellRangeAddress[] aAddresses = new CellRangeAddress[ 1 ];
            aAddresses[ 0 ] = aRange;

            // first bool: ColumnHeaders
            // second bool: RowHeaders
            aChartCollection.addNewByName( sChartName, aRect, aAddresses, true, false );

            try
            {
                XTableChart aTableChart = (XTableChart) UnoRuntime.queryInterface(
                    XTableChart.class, aChartCollectionNA.getByName( sChartName ));

                // the table chart is an embedded object which contains the chart document
                aResult = (XChartDocument) UnoRuntime.queryInterface(
                    XChartDocument.class,
                    ((XEmbeddedObjectSupplier) UnoRuntime.queryInterface(
                        XEmbeddedObjectSupplier.class,
                        aTableChart )).getEmbeddedObject());

                // create a diagram via the factory and set this as new diagram
                aResult.setDiagram(
                    (XDiagram) UnoRuntime.queryInterface(
                        XDiagram.class,
                        ((XMultiServiceFactory) UnoRuntime.queryInterface(
                            XMultiServiceFactory.class,
                            aResult )).createInstance( sChartServiceName )));
            }
            catch( NoSuchElementException ex )
            {
                System.out.println( "Couldn't find chart with name " + sChartName + ": " + ex );                
            }
            catch( Exception ex )
            {}
        }

        return aResult;
    }

    // ____________________

    /** Fill a rectangular range with random numbers.
        The first column has increasing values
     */
    public XCellRange insertRandomRange( int nColumnCount, int nRowCount )
    {
        XCellRange aRange = null;

        // get the sheet to insert the chart
        try
        {
            XSpreadsheet aSheet = getDataSheet();
            XCellRange aSheetRange = (XCellRange) UnoRuntime.queryInterface( XCellRange.class, aSheet );

            aRange = aSheetRange.getCellRangeByPosition(
                0, 0,
                nColumnCount - 1, nRowCount - 1 );

            int nCol, nRow;
            double fBase  = 0.0;
            double fRange = 10.0;
            double fValue;
            Random aGenerator = new Random();


            for( nCol = 0; nCol < nColumnCount; nCol++ )
            {
                if( 0 == nCol )
                {
                    (aSheet.getCellByPosition( nCol, 0 )).setFormula( "X" );
                }
                else
                {
                    (aSheet.getCellByPosition( nCol, 0 )).setFormula( "Random " + nCol );
                }

                for( nRow = 1; nRow < nRowCount; nRow++ )
                {
                    if( 0 == nCol )
                    {
                        // x values: ascending numbers
                        fValue = (double)nRow + aGenerator.nextDouble();
                    }
                    else
                    {
                        fValue = fBase + ( aGenerator.nextGaussian() * fRange );
                    }

                    // put value into cell

                    // note: getCellByPosition is a method at ...table.XCellRange which
                    //       the XSpreadsheet inherits via ...sheet.XSheetCellRange
                    (aSheet.getCellByPosition( nCol, nRow )).setValue( fValue );
                }
            }

        }
        catch( Exception ex )
        {
            System.out.println( "Sheet not found" + ex );
        }
        
        return aRange;
    }

    // ____________________

    public XCellRange insertFormulaRange( int nColumnCount, int nRowCount )
    {
        XCellRange aRange = null;

        // get the sheet to insert the chart
        try
        {
            XSpreadsheet aSheet = getDataSheet();
            XCellRange aSheetRange = (XCellRange) UnoRuntime.queryInterface( XCellRange.class, aSheet );

            aRange = aSheetRange.getCellRangeByPosition(
                0, 0,
                nColumnCount - 1, nRowCount - 1 );

            int nCol, nRow;
            double fValue;
            double fFactor = 2.0 * java.lang.Math.PI / (double)(nRowCount - 1);
            String aFormula;

            // set variable factor for cos formula 
            int nFactorCol = nColumnCount + 2;
            (aSheet.getCellByPosition( nFactorCol - 1, 0 )).setValue( 0.2 );

            XText xCellText = (XText) UnoRuntime.queryInterface( XText.class, aSheet.getCellByPosition( nFactorCol - 1, 1 ) );
            xCellText.setString( "Change the factor above and\nwatch the changes in the chart" );
            
            for( nCol = 0; nCol < nColumnCount; nCol++ )
            {
                for( nRow = 0; nRow < nRowCount; nRow++ )
                {
                    if( 0 == nCol )
                    {
                        // x values: ascending numbers
                        fValue = (double)nRow * fFactor;
                        (aSheet.getCellByPosition( nCol, nRow )).setValue( fValue );
                    }
                    else
                    {
                        aFormula = new String( "=" );
                        if( nCol % 2 == 0 )
                            aFormula += "SIN";
                        else
                            aFormula += "COS";
                        aFormula += "(INDIRECT(ADDRESS(" + (nRow + 1) + ";1)))+RAND()*INDIRECT(ADDRESS(1;" + nFactorCol + "))";
                        (aSheet.getCellByPosition( nCol, nRow )).setFormula( aFormula );
                    }
                }
            }

        }
        catch( Exception ex )
        {
            System.out.println( "Sheet not found" + ex );
        }
        
        return aRange;
    }

    // ____________________

    /** Bring the sheet containing charts visually to the foreground
     */
    public void raiseChartSheet()
    {
        ((XSpreadsheetView) UnoRuntime.queryInterface(
            XSpreadsheetView.class,
            ((XModel) UnoRuntime.queryInterface(
                XModel.class,
                maSpreadSheetDoc )).getCurrentController()) ).setActiveSheet( getChartSheet() );
    }


    // __________ private members and methods __________

    private final String  msDataSheetName  = "Data";
    private final String  msChartSheetName = "Chart";

    private XSpreadsheetDocument   maSpreadSheetDoc;


    // ____________________

    /** create two sheets, one for data and one for charts in the document
     */
    private void initSpreadSheet()
    {
        if( maSpreadSheetDoc != null )
        {
            XSpreadsheets  aSheets    = maSpreadSheetDoc.getSheets();
            XNameContainer aSheetsNC  = (XNameContainer)  UnoRuntime.queryInterface(
                XNameContainer.class, aSheets );
            XIndexAccess   aSheetsIA  = (XIndexAccess)    UnoRuntime.queryInterface(
                XIndexAccess.class, aSheets );

            if( aSheets   != null &&
                aSheetsNC != null &&
                aSheetsIA != null )
            {
                try
                {
                    // remove all sheets except one
                    for( int i = aSheetsIA.getCount() - 1; i > 0; i-- )
                    {
                        aSheetsNC.removeByName(
                            ( (XNamed) UnoRuntime.queryInterface(
                                XNamed.class, aSheetsIA.getByIndex( i ) )).getName() );
                    }

                    XNamed aFirstSheet = (XNamed) UnoRuntime.queryInterface(
                        XNamed.class,
                        aSheetsIA.getByIndex( 0 ));

                    // first sheet becomes data sheet
                    aFirstSheet.setName( msDataSheetName );

                    // second sheet becomes chart sheet
                    aSheets.insertNewByName( msChartSheetName, (short)1 );
                }
                catch( Exception ex )
                {
                    System.out.println( "Couldn't initialize Spreadsheet Document: " + ex );
                }
            }
        }
    }
}
