/**************************************************************
 *
 * 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: enter some text
//          Step 4: insert a text table
//          Step 5: insert colored text
//          Step 6: insert a text frame
//***************************************************************************

import com.sun.star.uno.UnoRuntime;

public class SWriter  {

    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();
            if( xContext != null )
                System.out.println("Connected to a running office ...");
        }
        catch( Exception e) {
            e.printStackTrace(System.err);
            System.exit(1);
        }

        //oooooooooooooooooooooooooooStep 2oooooooooooooooooooooooooooooooooooooooo
        // open an empty document. In this case it's a writer 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 Writer document

        System.out.println("Opening an empty Writer document");
        com.sun.star.text.XTextDocument myDoc = openWriter(xContext);

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


        //oooooooooooooooooooooooooooStep 3oooooooooooooooooooooooooooooooooooooooo
        // insert some text.
        // For this purpose get the Text-Object of the document an create the
        // cursor. Now it is possible to insert a text at the cursor-position
        // via insertString
        //*************************************************************************


        //getting the text object
        com.sun.star.text.XText xText = myDoc.getText();

        //create a cursor object
        com.sun.star.text.XTextCursor xTCursor = xText.createTextCursor();

        //inserting some Text
        xText.insertString( xTCursor, "The first line in the newly created text document.\n", false );

        //inserting a second line
        xText.insertString( xTCursor, "Now we're in the second line\n", false );

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


        //oooooooooooooooooooooooooooStep 4oooooooooooooooooooooooooooooooooooooooo
        // insert a text table.
        // For this purpose get MultiServiceFactory of the document, create an
        // instance of com.sun.star.text.TextTable and initialize it. Now it can
        // be inserted at the cursor position via insertTextContent.
        // After that some properties are changed and some data is inserted.
        //*************************************************************************

        //inserting a text table
        System.out.println("Inserting a text table");

        //getting MSF of the document
        com.sun.star.lang.XMultiServiceFactory xDocMSF =
            (com.sun.star.lang.XMultiServiceFactory) UnoRuntime.queryInterface(
                com.sun.star.lang.XMultiServiceFactory.class, myDoc);

        //create instance of a text table
        com.sun.star.text.XTextTable xTT = null;

        try {
            Object oInt = xDocMSF.createInstance("com.sun.star.text.TextTable");
            xTT = (com.sun.star.text.XTextTable)
                UnoRuntime.queryInterface(com.sun.star.text.XTextTable.class,oInt);
        } catch (Exception e) {
            System.err.println("Couldn't create instance "+ e);
            e.printStackTrace(System.err);
        }

        //initialize the text table with 4 columns an 4 rows
        xTT.initialize(4,4);

        com.sun.star.beans.XPropertySet xTTRowPS = null;

        //insert the table
        try {
            xText.insertTextContent(xTCursor, xTT, false);
            // get first Row
            com.sun.star.container.XIndexAccess xTTRows = xTT.getRows();
            xTTRowPS = (com.sun.star.beans.XPropertySet)UnoRuntime.queryInterface(
                com.sun.star.beans.XPropertySet.class, xTTRows.getByIndex(0));

        } catch (Exception e) {
            System.err.println("Couldn't insert the table " + e);
            e.printStackTrace(System.err);
        }


        // get the property set of the text table

        com.sun.star.beans.XPropertySet xTTPS = (com.sun.star.beans.XPropertySet)
            UnoRuntime.queryInterface(com.sun.star.beans.XPropertySet.class, xTT);

        // Change the BackColor
        try {
            xTTPS.setPropertyValue("BackTransparent", new Boolean(false));
            xTTPS.setPropertyValue("BackColor",new Integer(13421823));
            xTTRowPS.setPropertyValue("BackTransparent", new Boolean(false));
            xTTRowPS.setPropertyValue("BackColor",new Integer(6710932));

        } catch (Exception e) {
            System.err.println("Couldn't change the color " + e);
            e.printStackTrace(System.err);
        }

        // write Text in the Table headers
        System.out.println("Write text in the table headers");

        insertIntoCell("A1","FirstColumn", xTT);
        insertIntoCell("B1","SecondColumn", xTT) ;
        insertIntoCell("C1","ThirdColumn", xTT) ;
        insertIntoCell("D1","SUM", xTT) ;


        //Insert Something in the text table
        System.out.println("Insert something in the text table");

        (xTT.getCellByName("A2")).setValue(22.5);
        (xTT.getCellByName("B2")).setValue(5615.3);
        (xTT.getCellByName("C2")).setValue(-2315.7);
        (xTT.getCellByName("D2")).setFormula("sum <A2:C2>");

        (xTT.getCellByName("A3")).setValue(21.5);
        (xTT.getCellByName("B3")).setValue(615.3);
        (xTT.getCellByName("C3")).setValue(-315.7);
        (xTT.getCellByName("D3")).setFormula("sum <A3:C3>");

        (xTT.getCellByName("A4")).setValue(121.5);
        (xTT.getCellByName("B4")).setValue(-615.3);
        (xTT.getCellByName("C4")).setValue(415.7);
        (xTT.getCellByName("D4")).setFormula("sum <A4:C4>");


        //oooooooooooooooooooooooooooStep 5oooooooooooooooooooooooooooooooooooooooo
        // insert a colored text.
        // Get the propertySet of the cursor, change the CharColor and add a
        // shadow. Then insert the Text via InsertString at the cursor position.
        //*************************************************************************

        // get the property set of the cursor
        com.sun.star.beans.XPropertySet xTCPS = (com.sun.star.beans.XPropertySet)
            UnoRuntime.queryInterface(com.sun.star.beans.XPropertySet.class,
                                      xTCursor);

        Object oldValue = null;

        // Change the CharColor and add a Shadow
        try {
            xTCPS.setPropertyValue("CharColor",new Integer(255));
            xTCPS.setPropertyValue("CharShadowed", new Boolean(true));
        } catch (Exception e) {
            System.err.println("Couldn't change the color " + e);
            e.printStackTrace(System.err);
        }

        //create a paragraph break
        try {
            xText.insertControlCharacter(xTCursor,
                      com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, false);

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

        //inserting colored Text
        System.out.println("Inserting colored Text");

        xText.insertString(xTCursor, " This is a colored Text - blue with shadow\n",
                           false );

        //create a paragraph break
        try {
            xText.insertControlCharacter(xTCursor,
                      com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, false);

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

        //oooooooooooooooooooooooooooStep 6oooooooooooooooooooooooooooooooooooooooo
        // insert a text frame.
        // create an instance of com.sun.star.text.TextFrame using the MSF of the
        // document. Change some properties an insert it.
        // Now get the text-Object of the frame an the corresponding cursor.
        // Insert some text via insertString.
        //*************************************************************************

        // Create a TextFrame
        com.sun.star.text.XTextFrame xTF = null;
        com.sun.star.drawing.XShape xTFS = null;

        try {
            Object oInt = xDocMSF.createInstance("com.sun.star.text.TextFrame");
            xTF = (com.sun.star.text.XTextFrame) UnoRuntime.queryInterface(
                com.sun.star.text.XTextFrame.class,oInt);
            xTFS = (com.sun.star.drawing.XShape) UnoRuntime.queryInterface(
                com.sun.star.drawing.XShape.class,oInt);

            com.sun.star.awt.Size aSize = new com.sun.star.awt.Size();
            aSize.Height = 400;
            aSize.Width = 15000;

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

        // get the property set of the text frame
        com.sun.star.beans.XPropertySet xTFPS = (com.sun.star.beans.XPropertySet)
            UnoRuntime.queryInterface(com.sun.star.beans.XPropertySet.class, xTF);

        // Change the AnchorType
        try {
            xTFPS.setPropertyValue("AnchorType",
                      com.sun.star.text.TextContentAnchorType.AS_CHARACTER);
        } catch (Exception e) {
            System.err.println("Couldn't change the color " + e);
            e.printStackTrace(System.err);
        }

        //insert the frame
        System.out.println("Insert the text frame");

        try {
            xText.insertTextContent(xTCursor, xTF, false);
        } catch (Exception e) {
            System.err.println("Couldn't insert the frame " + e);
            e.printStackTrace(System.err);
        }

        //getting the text object of Frame
        com.sun.star.text.XText xTextF = xTF.getText();

        //create a cursor object
        com.sun.star.text.XTextCursor xTCF = xTextF.createTextCursor();

        //inserting some Text
        xTextF.insertString(xTCF,
                 "The first line in the newly created text frame.", false);


        xTextF.insertString(xTCF,
                 "\nWith this second line the height of the frame raises.", false);

        //insert a paragraph break
        try {
            xText.insertControlCharacter(xTCursor,
                      com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, false );

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

        // Change the CharColor and add a Shadow
        try {
            xTCPS.setPropertyValue("CharColor",new Integer(65536));
            xTCPS.setPropertyValue("CharShadowed", new Boolean(false));
        } catch (Exception e) {
            System.err.println("Couldn't change the color " + e);
            e.printStackTrace(System.err);
        }

        xText.insertString(xTCursor, " That's all for now !!", false );

        System.out.println("done");

        System.exit(0);
    }


    public static com.sun.star.text.XTextDocument openWriter(
        com.sun.star.uno.XComponentContext xContext)
    {
        //define variables
        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/swriter";
            xComp = xCLoader.loadComponentFromURL(strDoc, "_blank", 0, szEmptyArgs);
            xDoc = (com.sun.star.text.XTextDocument)
                UnoRuntime.queryInterface(com.sun.star.text.XTextDocument.class,
                                          xComp);

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

    public static void insertIntoCell(String CellName, String theText,
                                      com.sun.star.text.XTextTable xTTbl) {

        com.sun.star.text.XText xTableText = (com.sun.star.text.XText)
            UnoRuntime.queryInterface(com.sun.star.text.XText.class,
                                      xTTbl.getCellByName(CellName));

        //create a cursor object
        com.sun.star.text.XTextCursor xTC = xTableText.createTextCursor();

        com.sun.star.beans.XPropertySet xTPS = (com.sun.star.beans.XPropertySet)
            UnoRuntime.queryInterface(com.sun.star.beans.XPropertySet.class, xTC);

        try {
            xTPS.setPropertyValue("CharColor",new Integer(16777215));
        } catch (Exception e) {
            System.err.println(" Exception " + e);
            e.printStackTrace(System.err);
        }

        //inserting some Text
        xTableText.setString( theText );

    }
}
