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

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

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

// application specific classes
import com.sun.star.chart.*;
import com.sun.star.drawing.*;

import com.sun.star.table.CellRangeAddress;
import com.sun.star.table.XCellRange;
import com.sun.star.sheet.XCellRangeAddressable;

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

import com.sun.star.util.XNumberFormatsSupplier;
import com.sun.star.util.XNumberFormats;

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

// Exceptions
import com.sun.star.uno.Exception;
import com.sun.star.uno.RuntimeException;
import com.sun.star.beans.UnknownPropertyException;
import com.sun.star.lang.IndexOutOfBoundsException;
import com.sun.star.util.MalformedNumberFormatException;


// __________ Implementation __________

/** Create a spreadsheet add some data and add a chart
    @author Bj&ouml;rn Milcke
 */
public class ChartInCalc
{
    // ____________________

    public static void main( String args[] )
    {
        Helper aHelper = new Helper( args );

        CalcHelper aCalcHelper = new CalcHelper( aHelper.createSpreadsheetDocument() );

        // insert a cell range with 4 columns and 24 rows filled with random numbers
        XCellRange aRange = aCalcHelper.insertRandomRange( 4, 24 );
        CellRangeAddress aRangeAddress = ((XCellRangeAddressable) UnoRuntime.queryInterface(
            XCellRangeAddressable.class, aRange)).getRangeAddress();

        // change view to sheet containing the chart
        aCalcHelper.raiseChartSheet();

        // the unit for measures is 1/100th of a millimeter
        // position at (1cm, 1cm)
        Point aPos    = new Point( 1000, 1000 );

        // size of the chart is 15cm x 9.271cm
        Size  aExtent = new Size( 15000, 9271 );

        // insert a new chart into the "Chart" sheet of the
        // spreadsheet document
        XChartDocument aChartDoc = aCalcHelper.insertChart(
            "ScatterChart",
            aRangeAddress,
            aPos,
            aExtent,
            "com.sun.star.chart.XYDiagram" );

        // instantiate test class with newly created chart
        ChartInCalc aTest   = new ChartInCalc( aChartDoc );

        try
        {
            aTest.lockControllers();

            aTest.testDiagram();
            aTest.testArea();
            aTest.testWall();
            aTest.testTitle();
            aTest.testAxis();
            aTest.testGrid();

            // show an intermediate state, ...
            aTest.unlockControllers();
            aTest.lockControllers();

            // ..., because the following takes a while:
            // an internet URL has to be resolved
            aTest.testDataRowProperties();
            aTest.testDataPointProperties();

            aTest.unlockControllers();
        }
        catch( Exception ex )
        {
            System.out.println( "UNO Exception caught: " + ex );
            System.out.println( "Message: " + ex.getMessage() );
        }

        System.exit( 0 );
    }


    // ________________________________________

    public ChartInCalc( XChartDocument aChartDoc )
    {
        maChartDocument = aChartDoc;
        maDiagram       = maChartDocument.getDiagram();
    }

    // ____________________

    public void lockControllers()
        throws RuntimeException
    {
        ((XModel) UnoRuntime.queryInterface( XModel.class, maChartDocument )).lockControllers();
    }

    // ____________________

    public void unlockControllers()
        throws RuntimeException
    {
        ((XModel) UnoRuntime.queryInterface( XModel.class, maChartDocument )).unlockControllers();
    }

    // ____________________

    public void testDiagram()
        throws RuntimeException, UnknownPropertyException, PropertyVetoException,
               com.sun.star.lang.IllegalArgumentException, WrappedTargetException
    {
        XPropertySet aDiaProp = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, maDiagram );

        if( aDiaProp != null )
        {
            // change chart type
            aDiaProp.setPropertyValue( "Lines", new Boolean( true ));

            // change attributes for all series
            // set line width to 0.5mm
            aDiaProp.setPropertyValue( "LineWidth",  new Integer( 50 ));
        }
    }

    // ____________________

    public void testDataRowProperties()
        throws RuntimeException, UnknownPropertyException, PropertyVetoException,
               com.sun.star.lang.IllegalArgumentException, WrappedTargetException
    {
        // change properties of the data series
        try
        {
            XPropertySet aSeriesProp;
            for( int i = 1; i <= 3; i++ )
            {
                aSeriesProp = maDiagram.getDataRowProperties( i );
                aSeriesProp.setPropertyValue( "LineColor", new Integer(
                                                  0x400000 * i +
                                                  0x005000 * i +
                                                  0x0000ff - 0x40 * i ));
                if( 1 == i )
                {
                    StringBuffer sUrl = new StringBuffer("file:///");
                    try {
                        /* for use without net it's easier to load a local graphic */
                        java.io.File sourceFile = new java.io.File("bullet.gif");
                        sUrl.append(sourceFile.getCanonicalPath().replace('\\', '/'));
                    } catch (java.io.IOException e) {
                        sUrl = new StringBuffer("http://graphics.openoffice.org/chart/bullet1.gif");
                    }

                    // set a bitmap via URL as symbol for the first series
                    aSeriesProp.setPropertyValue( "SymbolType", new Integer( ChartSymbolType.BITMAPURL ));
                    aSeriesProp.setPropertyValue( "SymbolBitmapURL", sUrl.toString() );
                }
                else
                {
                    aSeriesProp.setPropertyValue( "SymbolType", new Integer( ChartSymbolType.SYMBOL1 ));
                    aSeriesProp.setPropertyValue( "SymbolSize", new Size( 250, 250 ));
                }
            }
        }
        catch( IndexOutOfBoundsException ex )
        {
            System.out.println( "Oops, there not enough series for setting properties: " + ex );
        }
    }

    // ____________________

    public void testDataPointProperties()
        throws RuntimeException, UnknownPropertyException, PropertyVetoException,
               com.sun.star.lang.IllegalArgumentException, WrappedTargetException
    {
        // set properties for a single data point
        try
        {
            // determine the maximum value of the first series
            int nMaxIndex = 0;

            XChartDataArray aDataArray = (XChartDataArray) UnoRuntime.queryInterface(
                XChartDataArray.class, maChartDocument.getData());
            double aData[][] = aDataArray.getData();

            int i;
            double fMax = aData[ 0 ][ 1 ];
            for( i = 1; i < aData.length; i++ )
            {
                if( aData[ i ][ 1 ] > fMax )
                {
                    fMax = aData[ i ][ 1 ];
                    nMaxIndex = i;
                }
            }

            // first parameter is the index of the point, the second one is the series
            XPropertySet aPointProp = maDiagram.getDataPointProperties( 0, 1 );

            // set a different, larger symbol
            aPointProp.setPropertyValue( "SymbolType", new Integer( ChartSymbolType.SYMBOL6 ));
            aPointProp.setPropertyValue( "SymbolSize", new Size( 600, 600 ));

            // add a label text with bold font, bordeaux red 14pt
            aPointProp.setPropertyValue( "DataCaption", new Integer( ChartDataCaption.VALUE ));
            aPointProp.setPropertyValue( "CharHeight",  new Float( 14.0 ));
            aPointProp.setPropertyValue( "CharColor",   new Integer( 0x993366 ));
            aPointProp.setPropertyValue( "CharWeight",  new Float( FontWeight.BOLD ));
        }
        catch( IndexOutOfBoundsException ex )
        {
            System.out.println( "Oops, there not enough data points or series for setting properties: " + ex );
        }
    }

    // ____________________

    public void testArea()
        throws RuntimeException, UnknownPropertyException, PropertyVetoException,
               com.sun.star.lang.IllegalArgumentException, WrappedTargetException
    {
        XPropertySet   aArea = maChartDocument.getArea();

        if( aArea != null )
        {
            // change background color of entire chart
            aArea.setPropertyValue( "FillStyle", FillStyle.SOLID );
            aArea.setPropertyValue( "FillColor", new Integer( 0xeeeeee ));
        }
    }

    // ____________________

    public void testWall()
        throws RuntimeException, UnknownPropertyException, PropertyVetoException,
               com.sun.star.lang.IllegalArgumentException, WrappedTargetException
    {
        XPropertySet aWall = ((X3DDisplay) UnoRuntime.queryInterface(
                                  X3DDisplay.class, maDiagram )).getWall();

        // change background color of area
        aWall.setPropertyValue( "FillStyle", FillStyle.SOLID );
        aWall.setPropertyValue( "FillColor", new Integer( 0xcccccc ));
    }

    // ____________________

    public void testTitle()
        throws RuntimeException, UnknownPropertyException, PropertyVetoException,
               com.sun.star.lang.IllegalArgumentException, WrappedTargetException
    {
        // change main title
        XPropertySet aDocProp = (XPropertySet) UnoRuntime.queryInterface(
            XPropertySet.class, maChartDocument );
        aDocProp.setPropertyValue( "HasMainTitle", new Boolean( true ));

        XShape aTitle = maChartDocument.getTitle();
        XPropertySet aTitleProp = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, aTitle );

        // set new text
        if( aTitleProp != null )
        {
            aTitleProp.setPropertyValue( "String", "Random Scatter Chart" );
            aTitleProp.setPropertyValue( "CharHeight", new Float(14.0) );
        }

        // align title with y axis
        XShape aAxis = (XShape) UnoRuntime.queryInterface(
            XShape.class, ((XAxisYSupplier) UnoRuntime.queryInterface(
                XAxisYSupplier.class, maDiagram )).getYAxis() );

        if( aAxis != null &&
            aTitle != null )
        {
            Point aPos = aTitle.getPosition();
            aPos.X = ( aAxis.getPosition() ).X;
            aTitle.setPosition( aPos );
        }
    }

    // ____________________

    public void testAxis()
        throws RuntimeException, UnknownPropertyException, PropertyVetoException,
               com.sun.star.lang.IllegalArgumentException, WrappedTargetException,
               MalformedNumberFormatException
    {
        // x axis
        XPropertySet aAxisProp = ((XAxisXSupplier) UnoRuntime.queryInterface(
                                      XAxisXSupplier.class, maDiagram )).getXAxis();
        if( aAxisProp != null )
        {
            aAxisProp.setPropertyValue( "Max",      new Integer( 24 ));
            aAxisProp.setPropertyValue( "StepMain", new Integer( 3 ));
        }

        // change number format for y axis
        aAxisProp = ((XAxisYSupplier) UnoRuntime.queryInterface(
                         XAxisYSupplier.class, maDiagram )).getYAxis();

        // add a new custom number format and get the new key
        int nNewNumberFormat = 0;
        XNumberFormatsSupplier aNumFmtSupp = (XNumberFormatsSupplier) UnoRuntime.queryInterface(
            XNumberFormatsSupplier.class, maChartDocument );

        if( aNumFmtSupp != null )
        {
            XNumberFormats aFormats = aNumFmtSupp.getNumberFormats();
            Locale aLocale = new Locale( "de", "DE", "de" );

            String aFormatStr = aFormats.generateFormat( nNewNumberFormat, aLocale, true, true, (short)3, (short)1 );
            nNewNumberFormat = aFormats.addNew( aFormatStr, aLocale );
        }

        if( aAxisProp != null )
        {
            aAxisProp.setPropertyValue( "NumberFormat", new Integer( nNewNumberFormat ));
        }
    }

    // ____________________

    public void testGrid()
        throws RuntimeException, UnknownPropertyException, PropertyVetoException,
               com.sun.star.lang.IllegalArgumentException, WrappedTargetException
    {
        // y major grid
        XPropertySet aGridProp = (XPropertySet) UnoRuntime.queryInterface(
            XPropertySet.class,
            ( (XAxisYSupplier) UnoRuntime.queryInterface(
                XAxisYSupplier.class, maDiagram )).getYMainGrid());

        if( aGridProp != null )
        {
            LineDash aDash = new LineDash();
            aDash.Style    = DashStyle.ROUND;
            aDash.Dots     = 2;
            aDash.DotLen   = 10;
            aDash.Dashes   = 1;
            aDash.DashLen  = 200;
            aDash.Distance = 100;

            aGridProp.setPropertyValue( "LineColor", new Integer( 0x999999 ));
            aGridProp.setPropertyValue( "LineStyle", LineStyle.DASH );
            aGridProp.setPropertyValue( "LineDash", aDash );
            aGridProp.setPropertyValue( "LineWidth", new Integer( 30 ));
        }
    }


    // ______________________________
    //
    // private members
    // ______________________________

    private XChartDocument maChartDocument;
    private XDiagram       maDiagram;
}
