/**************************************************************
 *
 * 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: bootstrap UNO and get the remote component context
//          Step 2: open an empty text document
//          Step 3: get the drawpage an insert some shapes
//***************************************************************************


import java.lang.Math;

import com.sun.star.uno.UnoRuntime;

public class SDraw  {


    public static void main(String args[]) {

        //oooooooooooooooooooooooooooStep 1oooooooooooooooooooooooooooooooooooooooo
        // bootstrap UNO and get the remote component context. The context can
        // be used to get the service manager
        //*************************************************************************
        com.sun.star.uno.XComponentContext xContext = null;

        try {
            // get the remote office component context
            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);
        }

        com.sun.star.lang.XComponent xDrawDoc = null;
        com.sun.star.drawing.XDrawPage xDrawPage = null;

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

        //Open document
        //Draw
        System.out.println("Opening an empty Draw document ...");
        xDrawDoc = openDraw(xContext);

        //oooooooooooooooooooooooooooStep 3oooooooooooooooooooooooooooooooooooooooo
        // get the drawpage an insert some shapes.
        // the documents DrawPageSupplier supplies the DrawPage vi IndexAccess
        // To add a shape get the MultiServiceFaktory of the document, create an
        // instance of the ShapeType and add it to the Shapes-container
        // provided by the drawpage
        //*************************************************************************


        // get the drawpage of drawing here
        try {
            System.out.println( "getting Drawpage" );
            com.sun.star.drawing.XDrawPagesSupplier xDPS =
                (com.sun.star.drawing.XDrawPagesSupplier)UnoRuntime.queryInterface(
                    com.sun.star.drawing.XDrawPagesSupplier.class, xDrawDoc);
            com.sun.star.drawing.XDrawPages xDPn = xDPS.getDrawPages();
            com.sun.star.container.XIndexAccess xDPi =
                (com.sun.star.container.XIndexAccess)UnoRuntime.queryInterface(
                    com.sun.star.container.XIndexAccess.class, xDPn);
            xDrawPage = (com.sun.star.drawing.XDrawPage)UnoRuntime.queryInterface(
                com.sun.star.drawing.XDrawPage.class, xDPi.getByIndex(0));
        } catch ( Exception e ) {
            System.err.println( "Couldn't create document"+ e );
            e.printStackTrace(System.err);
        }

        createSequence(xDrawDoc, xDrawPage);

        //put something on the drawpage
        System.out.println( "inserting some Shapes" );
        com.sun.star.drawing.XShapes xShapes = (com.sun.star.drawing.XShapes)
            UnoRuntime.queryInterface(
                com.sun.star.drawing.XShapes.class, xDrawPage);
        xShapes.add(createShape(xDrawDoc,2000,1500,1000,1000,"Line",0));
        xShapes.add(createShape(xDrawDoc,3000,4500,15000,1000,"Ellipse",16711680));
        xShapes.add(createShape(xDrawDoc,5000,3500,7500,5000,"Rectangle",6710932));

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

    public static com.sun.star.lang.XComponent openDraw(
        com.sun.star.uno.XComponentContext xContext)
    {
        com.sun.star.frame.XComponentLoader xCLoader;
        com.sun.star.text.XTextDocument xDoc = null;
        com.sun.star.lang.XComponent xComp = null;

        try {
            // get the remote office service manager
            com.sun.star.lang.XMultiComponentFactory xMCF =
                xContext.getServiceManager();

            Object oDesktop = xMCF.createInstanceWithContext(
                                        "com.sun.star.frame.Desktop", xContext);

            xCLoader = (com.sun.star.frame.XComponentLoader)
                UnoRuntime.queryInterface(com.sun.star.frame.XComponentLoader.class,
                                          oDesktop);
            com.sun.star.beans.PropertyValue szEmptyArgs[] =
                new com.sun.star.beans.PropertyValue[0];
            String strDoc = "private:factory/sdraw";
            xComp = xCLoader.loadComponentFromURL(strDoc, "_blank", 0, szEmptyArgs);

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

        return xComp;
    }

    public static com.sun.star.drawing.XShape createShape(
        com.sun.star.lang.XComponent xDocComp, int height, int width, int x,
        int y, String kind, int col)
    {
        //possible values for kind are 'Ellipse', 'Line' and 'Rectangle'
        com.sun.star.awt.Size size = new com.sun.star.awt.Size();
        com.sun.star.awt.Point position = new com.sun.star.awt.Point();
        com.sun.star.drawing.XShape xShape = null;

        //get MSF
        com.sun.star.lang.XMultiServiceFactory xDocMSF =
            (com.sun.star.lang.XMultiServiceFactory) UnoRuntime.queryInterface(
                com.sun.star.lang.XMultiServiceFactory.class, xDocComp );

        try {
            Object oInt = xDocMSF.createInstance("com.sun.star.drawing."
                                                 +kind + "Shape");
            xShape = (com.sun.star.drawing.XShape)UnoRuntime.queryInterface(
                com.sun.star.drawing.XShape.class, oInt);
            size.Height = height;
            size.Width = width;
            position.X = x;
            position.Y = y;
            xShape.setSize(size);
            xShape.setPosition(position);

        } catch ( Exception e ) {
            System.err.println( "Couldn't create instance "+ e );
            e.printStackTrace(System.err);
        }

        com.sun.star.beans.XPropertySet xSPS = (com.sun.star.beans.XPropertySet)
            UnoRuntime.queryInterface(
                com.sun.star.beans.XPropertySet.class, xShape);

        try {
            xSPS.setPropertyValue("FillColor", new Integer(col));
        } catch (Exception e) {
            System.err.println("Can't change colors " + e);
            e.printStackTrace(System.err);
        }

        return xShape;
    }

    public static com.sun.star.drawing.XShape createSequence(
        com.sun.star.lang.XComponent xDocComp, com.sun.star.drawing.XDrawPage xDP)
    {
        com.sun.star.awt.Size size = new com.sun.star.awt.Size();
        com.sun.star.awt.Point position = new com.sun.star.awt.Point();
        com.sun.star.drawing.XShape xShape = null;
        com.sun.star.drawing.XShapes xShapes = (com.sun.star.drawing.XShapes)
            UnoRuntime.queryInterface(com.sun.star.drawing.XShapes.class, xDP);
        int height = 3000;
        int width = 3500;
        int x = 1900;
        int y = 20000;
        Object oInt = null;
        int r = 40;
        int g = 0;
        int b = 80;

        //get MSF
        com.sun.star.lang.XMultiServiceFactory xDocMSF =
            (com.sun.star.lang.XMultiServiceFactory)UnoRuntime.queryInterface(
                com.sun.star.lang.XMultiServiceFactory.class, xDocComp );

        for (int i=0; i<370; i=i+25) {
            try{
                oInt = xDocMSF.createInstance("com.sun.star.drawing.EllipseShape");
                xShape = (com.sun.star.drawing.XShape)UnoRuntime.queryInterface(
                    com.sun.star.drawing.XShape.class, oInt);
                size.Height = height;
                size.Width = width;
                position.X = (x+(i*40));
                position.Y =
                    (new Float(y+(Math.sin((i*Math.PI)/180))*5000)).intValue();
                xShape.setSize(size);
                xShape.setPosition(position);

            } catch ( Exception e ) {
                // Some exception occures.FAILED
                System.err.println( "Couldn't get Shape "+ e );
                e.printStackTrace(System.err);
            }

            b=b+8;

            com.sun.star.beans.XPropertySet xSPS = (com.sun.star.beans.XPropertySet)
                UnoRuntime.queryInterface(com.sun.star.beans.XPropertySet.class,
                                          xShape);

            try {
                xSPS.setPropertyValue("FillColor", new Integer(getCol(r,g,b)));
                xSPS.setPropertyValue("Shadow", new Boolean(true));
            } catch (Exception e) {
                System.err.println("Can't change colors " + e);
                e.printStackTrace(System.err);
            }
            xShapes.add(xShape);
        }

        com.sun.star.drawing.XShapeGrouper xSGrouper =
            (com.sun.star.drawing.XShapeGrouper)UnoRuntime.queryInterface(
                com.sun.star.drawing.XShapeGrouper.class, xDP);

        xShape = xSGrouper.group(xShapes);

        return xShape;
    }

    public static int getCol(int r, int g, int b) {
        return r*65536+g*256+b;
    }
}
