/**************************************************************
 * 
 * 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 Desktop object from the office
//          Step 2: open an empty text document
//          Step 3: enter a example text
//          Step 4: use the paragraph collection
//          Step 5: apply a different paragraph style on the paragraphs
//***************************************************************************

import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.AnyConverter;

public class StyleInitialization {
    
    public static void main(String args[]) {
        // You need the desktop to create a document
        // The getDesktop method does the UNO bootstrapping, gets the
        // remote servie manager and the desktop object.
        com.sun.star.frame.XDesktop xDesktop = null;
        xDesktop = getDesktop();
        
        try {
            // BEGIN: 'Style basics' Section from the Tutorial
            
            // create text document
            com.sun.star.text.XTextDocument xTextDocument = null;
            xTextDocument = createTextdocument( xDesktop );
            
            // the text interface contains all methods and properties to
            // manipulate the content from a text document
            com.sun.star.text.XText xText = null;
            xText = xTextDocument.getText();
            
            String sMyText = "A very short paragraph for illustration only";
            
            // you can travel with the cursor throught the text document.
            // you travel only at the model, not at the view. The cursor that you can
            // see on the document doesn't change the position
            com.sun.star.text.XTextCursor xTextCursor = null;
            xTextCursor = (com.sun.star.text.XTextCursor)
                xTextDocument.getText().createTextCursor();
            
            com.sun.star.beans.XPropertySet oCPS = (com.sun.star.beans.XPropertySet)
                UnoRuntime.queryInterface(
                    com.sun.star.beans.XPropertySet.class, xTextCursor);
            try {
                oCPS.setPropertyValue("CharFontName","Helvetica");
            }
            catch (Exception ex) {
                
            }
            
            xText.insertString( xTextCursor, "Headline", false );
            
            try {
                oCPS.setPropertyValue("CharFontName","Times");
            }
            catch (Exception ex) {
                
            }
            xText.insertControlCharacter(xTextCursor,
                      com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, false);
            
            xText.insertString( xTextCursor, sMyText, false );
            
            com.sun.star.text.XTextRange xTextRange = null;
            com.sun.star.beans.XPropertySet xPropertySet = null;
            
            // the text range not the cursor contains the 'parastyle' property
            xTextRange = xText.getEnd();
            xPropertySet = (com.sun.star.beans.XPropertySet)
                UnoRuntime.queryInterface(
                    com.sun.star.beans.XPropertySet.class, xTextRange );
            
            // To run the sample with StarOffice 5.2 you'll have to change
            // 'ParaStyleName' to 'ParaStyle' in the next line
            System.out.println( "Current Parastyle : "
                                + xPropertySet.getPropertyValue("ParaStyleName") );
            
            // END: 'Style basics' Section from the Tutorial
            
            // There are two way to travel throught the paragraphs, with a
            // paragraph cursor, or a enumeration.
            // You find both ways in this example
            
            // The first way, with the paragraph cursor
            com.sun.star.text.XParagraphCursor xParagraphCursor = null;
            xParagraphCursor = (com.sun.star.text.XParagraphCursor)
                UnoRuntime.queryInterface(
                    com.sun.star.text.XParagraphCursor.class, xTextRange );
            
            xParagraphCursor.gotoStart( false );
            xParagraphCursor.gotoEndOfParagraph( true );
            
            // The second way, with the paragraph enumeration
            com.sun.star.container.XEnumerationAccess xEnumerationAccess = null;
            xEnumerationAccess = (com.sun.star.container.XEnumerationAccess)
                UnoRuntime.queryInterface(
                    com.sun.star.container.XEnumerationAccess.class, xText );
            
            // the enumeration contains all paragraph form the document
            com.sun.star.container.XEnumeration xParagraphEnumeration = null;
            xParagraphEnumeration = xEnumerationAccess.createEnumeration();
            
            com.sun.star.text.XTextContent xParagraph = null;
            com.sun.star.text.XTextRange xWord = null;
            
            com.sun.star.container.XEnumerationAccess xParaEnumerationAccess = null;
            com.sun.star.container.XEnumeration xPortionEnumeration = null;

            // check if a paragraph is available
            while ( xParagraphEnumeration.hasMoreElements() ) {
                // get the next paragraph
                xParagraph = (com.sun.star.text.XTextContent)
                    UnoRuntime.queryInterface(
                        com.sun.star.text.XTextContent.class,
                        xParagraphEnumeration.nextElement());
                
                // you need the method getAnchor to a TextRange -> to manipulate
                // the paragraph
                String sText = xParagraph.getAnchor().getString();
                
                // create a cursor from this paragraph
                com.sun.star.text.XTextCursor xParaCursor = null;
                xParaCursor = xParagraph.getAnchor().getText().createTextCursor();
                
                // goto the start and end of the paragraph
                xParaCursor.gotoStart( false );
                xParaCursor.gotoEnd( true );
                
                // The enumeration from the paragraphs contain parts from the
                // paragraph with a different attributes.
                xParaEnumerationAccess = (com.sun.star.container.XEnumerationAccess)
                    UnoRuntime.queryInterface(
                        com.sun.star.container.XEnumerationAccess.class, xParagraph);
                xPortionEnumeration = xParaEnumerationAccess.createEnumeration();
                
                while ( xPortionEnumeration.hasMoreElements() ) {
                    // output of all parts from the paragraph with different attributes
                    xWord = (com.sun.star.text.XTextRange) UnoRuntime.queryInterface(
                        com.sun.star.text.XTextRange.class,
                        xPortionEnumeration.nextElement());
                    String sWordString = xWord.getString();
                    System.out.println( "Content of the paragraph : " + sWordString );
                }
            }
            
            // BEGIN: 'Finding a suitable style' Section from the Tutorial
            
            // craete a supplier to get the styles-collection
            com.sun.star.style.XStyleFamiliesSupplier xSupplier = null;
            xSupplier = ( com.sun.star.style.XStyleFamiliesSupplier ) UnoRuntime.queryInterface(
                com.sun.star.style.XStyleFamiliesSupplier.class, xTextDocument );
            
            // use the name access from the collection
            com.sun.star.container.XNameAccess xNameAccess = null;
            xNameAccess = xSupplier.getStyleFamilies();
            
            com.sun.star.container.XNameContainer xParaStyleCollection = null;
            xParaStyleCollection = (com.sun.star.container.XNameContainer) UnoRuntime.queryInterface(
                com.sun.star.container.XNameContainer.class, xNameAccess.getByName( "ParagraphStyles" ));
            
            // create a array from strings with the name of all paragraph styles from the text document
            String[] sElementNames = xParaStyleCollection.getElementNames();
            int iElementCount = sElementNames.length;

            for( int iCounter = 0;  iCounter < iElementCount; iCounter++ ) {
                // specify one paragraph style
                com.sun.star.style.XStyle xStyle = null;
                xStyle = (com.sun.star.style.XStyle) UnoRuntime.queryInterface(
                    com.sun.star.style.XStyle.class,
                    xParaStyleCollection.getByName( sElementNames[iCounter] ));
                
                // create a property set of all properties from the style
                xPropertySet = (com.sun.star.beans.XPropertySet) UnoRuntime.queryInterface(
                    com.sun.star.beans.XPropertySet.class, xStyle );
                
                AnyConverter aAnyConv = new AnyConverter();
                String sFontname = aAnyConv.toString(xPropertySet.getPropertyValue("CharFontName"));
                sFontname = sFontname.toLowerCase();
                
                // if the style use the font 'Albany', apply it to the current paragraph
                if( sFontname.compareTo("albany") == 0 ) {
                    // create a property set from the current paragraph, to change the paragraph style
                    xPropertySet = (com.sun.star.beans.XPropertySet) UnoRuntime.queryInterface(
                        com.sun.star.beans.XPropertySet.class, xTextRange );
                    
                    // To run the sample with StarOffice 5.2 you'll have to change 'ParaStyleName'
                    // to 'ParaStyle' in the next line
                    xPropertySet.setPropertyValue("ParaStyleName", new String( sElementNames[iCounter] ) );
                    System.out.println( "Apply the paragraph style : " + sElementNames[iCounter] );
                    break;
                }
            }
            // END: 'Finding a suitable style' Section from the Tutorial
        }
        catch( Exception e) {
            e.printStackTrace(System.err);
        }
        
        
        System.out.println("Done");
        
        System.exit(0);
        
    }
    
    public static com.sun.star.frame.XDesktop getDesktop() {
        com.sun.star.frame.XDesktop xDesktop = null;
        com.sun.star.lang.XMultiComponentFactory xMCF = null;
        
        try {
            com.sun.star.uno.XComponentContext xContext = null;
            
            // get the remote office component context
            xContext = com.sun.star.comp.helper.Bootstrap.bootstrap();
            
            // get the remote office service manager
            xMCF = xContext.getServiceManager();
            if( xMCF != null ) {
                System.out.println("Connected to a running office ...");

                Object oDesktop = xMCF.createInstanceWithContext(
                    "com.sun.star.frame.Desktop", xContext);
                xDesktop = (com.sun.star.frame.XDesktop) UnoRuntime.queryInterface(
                    com.sun.star.frame.XDesktop.class, oDesktop);
            }
            else
                System.out.println( "Can't create a desktop. No connection, no remote office servicemanager available!" );
        }
        catch( Exception e) {
            e.printStackTrace(System.err);
            System.exit(1);
        }
        
        
        return xDesktop;
    }
    
    public static com.sun.star.text.XTextDocument createTextdocument(
        com.sun.star.frame.XDesktop xDesktop )
    {
        com.sun.star.text.XTextDocument aTextDocument = null;
        
        try {
            com.sun.star.lang.XComponent xComponent = CreateNewDocument(xDesktop,
                                                                        "swriter");
            aTextDocument = (com.sun.star.text.XTextDocument)
                UnoRuntime.queryInterface(
                    com.sun.star.text.XTextDocument.class, xComponent);
        }
        catch( Exception e) {
            e.printStackTrace(System.err);
        }
        
        return aTextDocument;
    }
    
    
    protected static com.sun.star.lang.XComponent CreateNewDocument(
        com.sun.star.frame.XDesktop xDesktop,
        String sDocumentType )
    {
        String sURL = "private:factory/" + sDocumentType;
        
        com.sun.star.lang.XComponent xComponent = null;
        com.sun.star.frame.XComponentLoader xComponentLoader = null;
        com.sun.star.beans.PropertyValue xValues[] =
            new com.sun.star.beans.PropertyValue[1];
        com.sun.star.beans.PropertyValue xEmptyArgs[] =
            new com.sun.star.beans.PropertyValue[0];
        
        try {
            xComponentLoader = (com.sun.star.frame.XComponentLoader)
                UnoRuntime.queryInterface(
                    com.sun.star.frame.XComponentLoader.class, xDesktop);
        
            xComponent  = xComponentLoader.loadComponentFromURL(
                sURL, "_blank", 0, xEmptyArgs);
        }
        catch( Exception e) {
            e.printStackTrace(System.err);
        }
        
        return xComponent ;
    }
}
