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



//***************************************************************************
// comment: Step 1: get the remote component context from the office
//          Step 2: open an empty calc document
//          Step 3: create cell styles
//          Step 4: get the sheet an insert some data
//          Step 5: apply the created cell syles
//          Step 6: insert a 3D Chart
//***************************************************************************

import com.sun.star.awt.Rectangle;

import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertySet;

import com.sun.star.chart.XDiagram;
import com.sun.star.chart.XChartDocument;

import com.sun.star.container.XIndexAccess;
import com.sun.star.container.XNameAccess;
import com.sun.star.container.XNameContainer;

import com.sun.star.document.XEmbeddedObjectSupplier;

import com.sun.star.frame.XDesktop;
import com.sun.star.frame.XComponentLoader;

import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.lang.XMultiComponentFactory;

import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;
import com.sun.star.uno.XComponentContext;

import com.sun.star.sheet.XCellRangeAddressable;
import com.sun.star.sheet.XSpreadsheet;
import com.sun.star.sheet.XSpreadsheets;
import com.sun.star.sheet.XSpreadsheetDocument;

import com.sun.star.style.XStyleFamiliesSupplier;

import com.sun.star.table.CellRangeAddress;
import com.sun.star.table.XCell;
import com.sun.star.table.XCellRange;
import com.sun.star.table.XTableChart;
import com.sun.star.table.XTableCharts;
import com.sun.star.table.XTableChartsSupplier;


public class SCalc  {

    public static void main(String args[]) {

        //oooooooooooooooooooooooooooStep 1oooooooooooooooooooooooooooooooooooooooooo
        // call UNO bootstrap method and get the remote component context form
        // the a running office (office will be started if necessary)
        //***************************************************************************
        XComponentContext xContext = null;

        // get the remote office component context
        try {
            xContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
            System.out.println("Connected to a running office ...");
        } catch( Exception e) {
            e.printStackTrace(System.err);
            System.exit(1);
        }

        //oooooooooooooooooooooooooooStep 2oooooooooooooooooooooooooooooooooooooooooo
        // open an empty document. In this case it's a calc document.
        // For this purpose an instance of com.sun.star.frame.Desktop
        // is created. The desktop provides the XComponentLoader interface,
        // which is used to open the document via loadComponentFromURL
        //***************************************************************************

        //Open document

        //Calc
        XSpreadsheetDocument myDoc = null;
//        XCell oCell = null;

        System.out.println("Opening an empty Calc document");
        myDoc = openCalc(xContext);

        //***************************************************************************


        //oooooooooooooooooooooooooooStep 3oooooooooooooooooooooooooooooooooooooooooo
        // create cell styles.
        // For this purpose get the StyleFamiliesSupplier and the family
        // CellStyle. Create an instance of com.sun.star.style.CellStyle and
        // add it to the family. Now change some properties
        //***************************************************************************

        try {
            XStyleFamiliesSupplier xSFS = (XStyleFamiliesSupplier)
                UnoRuntime.queryInterface(XStyleFamiliesSupplier.class, myDoc);
            XNameAccess xSF = (XNameAccess) xSFS.getStyleFamilies();
            XNameAccess xCS = (XNameAccess) UnoRuntime.queryInterface(
                XNameAccess.class, xSF.getByName("CellStyles"));
            XMultiServiceFactory oDocMSF = (XMultiServiceFactory)
                UnoRuntime.queryInterface(XMultiServiceFactory.class, myDoc );
            XNameContainer oStyleFamilyNameContainer = (XNameContainer)
                UnoRuntime.queryInterface(
                XNameContainer.class, xCS);
            XInterface oInt1 = (XInterface) oDocMSF.createInstance(
                "com.sun.star.style.CellStyle");
            oStyleFamilyNameContainer.insertByName("My Style", oInt1);
            XPropertySet oCPS1 = (XPropertySet)UnoRuntime.queryInterface(
                XPropertySet.class, oInt1 );
            oCPS1.setPropertyValue("IsCellBackgroundTransparent", new Boolean(false));
            oCPS1.setPropertyValue("CellBackColor",new Integer(6710932));
            oCPS1.setPropertyValue("CharColor",new Integer(16777215));
            XInterface oInt2 = (XInterface) oDocMSF.createInstance(
                "com.sun.star.style.CellStyle");
            oStyleFamilyNameContainer.insertByName("My Style2", oInt2);
            XPropertySet oCPS2 = (XPropertySet)UnoRuntime.queryInterface(
                XPropertySet.class, oInt2 );
            oCPS2.setPropertyValue("IsCellBackgroundTransparent", new Boolean(false));
            oCPS2.setPropertyValue("CellBackColor",new Integer(13421823));
        } catch (Exception e) {
            e.printStackTrace(System.err);
        }

        //***************************************************************************

        //oooooooooooooooooooooooooooStep 4oooooooooooooooooooooooooooooooooooooooooo
        // get the sheet an insert some data.
        // Get the sheets from the document and then the first from this container.
        // Now some data can be inserted. For this purpose get a Cell via
        // getCellByPosition and insert into this cell via setValue() (for floats)
        // or setFormula() for formulas and Strings
        //***************************************************************************


        XSpreadsheet xSheet=null;

        try {
            System.out.println("Getting spreadsheet") ;
            XSpreadsheets xSheets = myDoc.getSheets() ;
            XIndexAccess oIndexSheets = (XIndexAccess) UnoRuntime.queryInterface(
                XIndexAccess.class, xSheets);
            xSheet = (XSpreadsheet) UnoRuntime.queryInterface(
                XSpreadsheet.class, oIndexSheets.getByIndex(0));

        } catch (Exception e) {
            System.out.println("Couldn't get Sheet " +e);
            e.printStackTrace(System.err);
        }



        System.out.println("Creating the Header") ;

        insertIntoCell(1,0,"JAN",xSheet,"");
        insertIntoCell(2,0,"FEB",xSheet,"");
        insertIntoCell(3,0,"MAR",xSheet,"");
        insertIntoCell(4,0,"APR",xSheet,"");
        insertIntoCell(5,0,"MAI",xSheet,"");
        insertIntoCell(6,0,"JUN",xSheet,"");
        insertIntoCell(7,0,"JUL",xSheet,"");
        insertIntoCell(8,0,"AUG",xSheet,"");
        insertIntoCell(9,0,"SEP",xSheet,"");
        insertIntoCell(10,0,"OCT",xSheet,"");
        insertIntoCell(11,0,"NOV",xSheet,"");
        insertIntoCell(12,0,"DEC",xSheet,"");
        insertIntoCell(13,0,"SUM",xSheet,"");


        System.out.println("Fill the lines");

        insertIntoCell(0,1,"Smith",xSheet,"");
        insertIntoCell(1,1,"42",xSheet,"V");
        insertIntoCell(2,1,"58.9",xSheet,"V");
        insertIntoCell(3,1,"-66.5",xSheet,"V");
        insertIntoCell(4,1,"43.4",xSheet,"V");
        insertIntoCell(5,1,"44.5",xSheet,"V");
        insertIntoCell(6,1,"45.3",xSheet,"V");
        insertIntoCell(7,1,"-67.3",xSheet,"V");
        insertIntoCell(8,1,"30.5",xSheet,"V");
        insertIntoCell(9,1,"23.2",xSheet,"V");
        insertIntoCell(10,1,"-97.3",xSheet,"V");
        insertIntoCell(11,1,"22.4",xSheet,"V");
        insertIntoCell(12,1,"23.5",xSheet,"V");
        insertIntoCell(13,1,"=SUM(B2:M2)",xSheet,"");


        insertIntoCell(0,2,"Jones",xSheet,"");
        insertIntoCell(1,2,"21",xSheet,"V");
        insertIntoCell(2,2,"40.9",xSheet,"V");
        insertIntoCell(3,2,"-57.5",xSheet,"V");
        insertIntoCell(4,2,"-23.4",xSheet,"V");
        insertIntoCell(5,2,"34.5",xSheet,"V");
        insertIntoCell(6,2,"59.3",xSheet,"V");
        insertIntoCell(7,2,"27.3",xSheet,"V");
        insertIntoCell(8,2,"-38.5",xSheet,"V");
        insertIntoCell(9,2,"43.2",xSheet,"V");
        insertIntoCell(10,2,"57.3",xSheet,"V");
        insertIntoCell(11,2,"25.4",xSheet,"V");
        insertIntoCell(12,2,"28.5",xSheet,"V");
        insertIntoCell(13,2,"=SUM(B3:M3)",xSheet,"");

        insertIntoCell(0,3,"Brown",xSheet,"");
        insertIntoCell(1,3,"31.45",xSheet,"V");
        insertIntoCell(2,3,"-20.9",xSheet,"V");
        insertIntoCell(3,3,"-117.5",xSheet,"V");
        insertIntoCell(4,3,"23.4",xSheet,"V");
        insertIntoCell(5,3,"-114.5",xSheet,"V");
        insertIntoCell(6,3,"115.3",xSheet,"V");
        insertIntoCell(7,3,"-171.3",xSheet,"V");
        insertIntoCell(8,3,"89.5",xSheet,"V");
        insertIntoCell(9,3,"41.2",xSheet,"V");
        insertIntoCell(10,3,"71.3",xSheet,"V");
        insertIntoCell(11,3,"25.4",xSheet,"V");
        insertIntoCell(12,3,"38.5",xSheet,"V");
        insertIntoCell(13,3,"=SUM(A4:L4)",xSheet,"");

        //***************************************************************************

        //oooooooooooooooooooooooooooStep 5oooooooooooooooooooooooooooooooooooooooooo
        // apply the created cell style.
        // For this purpose get the PropertySet of the Cell and change the
        // property CellStyle to the appropriate value.
        //***************************************************************************

        // change backcolor
        chgbColor( 1 , 0, 13, 0, "My Style", xSheet );
        chgbColor( 0 , 1, 0, 3, "My Style", xSheet );
        chgbColor( 1 , 1, 13, 3, "My Style2", xSheet );

        //***************************************************************************

        //oooooooooooooooooooooooooooStep 6oooooooooooooooooooooooooooooooooooooooooo
        // insert a 3D chart.
        // get the CellRange which holds the data for the chart and its RangeAddress
        // get the TableChartSupplier from the sheet and then the TableCharts from it.
        // add a new chart based on the data to the TableCharts.
        // get the ChartDocument, which provide the Diagram. Change the properties
        // Dim3D (3 dimension) and String (the title) of the diagram.
        //***************************************************************************

        // insert a chart

        Rectangle oRect = new Rectangle();
        oRect.X = 500;
        oRect.Y = 3000;
        oRect.Width = 25000;
        oRect.Height = 11000;

        XCellRange oRange = (XCellRange)UnoRuntime.queryInterface(
            XCellRange.class, xSheet);
        XCellRange myRange = oRange.getCellRangeByName("A1:N4");
        XCellRangeAddressable oRangeAddr = (XCellRangeAddressable)
            UnoRuntime.queryInterface(XCellRangeAddressable.class, myRange);
        CellRangeAddress myAddr = oRangeAddr.getRangeAddress();

        CellRangeAddress[] oAddr = new CellRangeAddress[1];
        oAddr[0] = myAddr;
        XTableChartsSupplier oSupp = (XTableChartsSupplier)UnoRuntime.queryInterface(
            XTableChartsSupplier.class, xSheet);

        XTableChart oChart = null;

        System.out.println("Insert Chart");

        XTableCharts oCharts = oSupp.getCharts();
        oCharts.addNewByName("Example", oRect, oAddr, true, true);

        // get the diagram and Change some of the properties

        try {
            oChart = (XTableChart) (UnoRuntime.queryInterface(
                XTableChart.class, ((XNameAccess)UnoRuntime.queryInterface(
                            XNameAccess.class, oCharts)).getByName("Example")));
            XEmbeddedObjectSupplier oEOS = (XEmbeddedObjectSupplier)
                UnoRuntime.queryInterface(XEmbeddedObjectSupplier.class, oChart);
            XInterface oInt = oEOS.getEmbeddedObject();
            XChartDocument xChart = (XChartDocument) UnoRuntime.queryInterface(
                XChartDocument.class,oInt);
            XDiagram oDiag = (XDiagram) xChart.getDiagram();
            System.out.println("Change Diagramm to 3D");
            XPropertySet oCPS = (XPropertySet)UnoRuntime.queryInterface(
                XPropertySet.class, oDiag );
            oCPS.setPropertyValue("Dim3D", new Boolean(true));
            System.out.println("Change the title");
            Thread.sleep(200);
            XPropertySet oTPS = (XPropertySet)UnoRuntime.queryInterface(
                XPropertySet.class, xChart.getTitle() );
            oTPS.setPropertyValue("String","The new title");
            //oDiag.Dim3D();
        } catch (Exception e){
            System.err.println("Changin Properties failed "+e);
            e.printStackTrace(System.err);
        }

        System.out.println("done");
        System.exit(0);
    }

    public static XSpreadsheetDocument openCalc(XComponentContext xContext)
    {
        //define variables
        XMultiComponentFactory xMCF = null;
        XComponentLoader xCLoader;
        XSpreadsheetDocument xSpreadSheetDoc = null;
        XComponent xComp = null;

        try {
            // get the servie manager rom the office
            xMCF = xContext.getServiceManager();

            // create a new instance of the desktop
            Object oDesktop = xMCF.createInstanceWithContext(
                "com.sun.star.frame.Desktop", xContext );

            // query the desktop object for the XComponentLoader
            xCLoader = ( XComponentLoader ) UnoRuntime.queryInterface(
                XComponentLoader.class, oDesktop );

            PropertyValue [] szEmptyArgs = new PropertyValue [0];
            String strDoc = "private:factory/scalc";

            xComp = xCLoader.loadComponentFromURL(strDoc, "_blank", 0, szEmptyArgs );
            xSpreadSheetDoc = (XSpreadsheetDocument) UnoRuntime.queryInterface(
                XSpreadsheetDocument.class, xComp);

        } catch(Exception e){
            System.err.println(" Exception " + e);
            e.printStackTrace(System.err);
        }

        return xSpreadSheetDoc;
    }


    public static void insertIntoCell(int CellX, int CellY, String theValue,
                                      XSpreadsheet TT1, String flag)
    {
        XCell xCell = null;

        try {
            xCell = TT1.getCellByPosition(CellX, CellY);
        } catch (com.sun.star.lang.IndexOutOfBoundsException ex) {
            System.err.println("Could not get Cell");
            ex.printStackTrace(System.err);
        }

        if (flag.equals("V")) {
            xCell.setValue((new Float(theValue)).floatValue());
        } else {
            xCell.setFormula(theValue);
        }

    }

    public static void chgbColor( int x1, int y1, int x2, int y2,
                                  String template, XSpreadsheet TT )
    {
        XCellRange xCR = null;
        try {
            xCR = TT.getCellRangeByPosition(x1,y1,x2,y2);
        } catch (com.sun.star.lang.IndexOutOfBoundsException ex) {
            System.err.println("Could not get CellRange");
            ex.printStackTrace(System.err);
        }

        XPropertySet xCPS = (XPropertySet)UnoRuntime.queryInterface(
            XPropertySet.class, xCR );

        try {
            xCPS.setPropertyValue("CellStyle", template);
        } catch (Exception e) {
            System.err.println("Can't change colors chgbColor" + e);
            e.printStackTrace(System.err);
        }
    }

}
