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



// Lotus Notes Domino API
import lotus.domino.NotesThread;
import lotus.domino.Session;
import lotus.domino.Database;
import lotus.domino.DocumentCollection;
import lotus.domino.Document;
import lotus.domino.NotesFactory;

// OpenOffice.org API
import com.sun.star.bridge.XUnoUrlResolver;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.uno.XComponentContext;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.frame.XComponentLoader;
import com.sun.star.beans.PropertyValue;
import com.sun.star.beans.XPropertySet;
import com.sun.star.sheet.XSpreadsheetDocument;
import com.sun.star.sheet.XSpreadsheets;
import com.sun.star.sheet.XSpreadsheet;
import com.sun.star.container.XIndexAccess;
import com.sun.star.table.XCell;

/** This class creates an OpenOffice.org Calc spreadsheet document and fills it
 * with existing values of documents from a Lotus Notes database.
 */
public class NotesAccess implements Runnable {

    /** Host server of the Domino Directory.
     */
    static String stringHost = "";

    /** User in the host's Domino Directory.
     */
    static String stringUser = "";

    /** Password for the user in the host's Domino Directory.
     */
    static String stringPassword = "";

    /** Database with documents to get data from.
     */
    static String stringDatabase = "";

    /** Reading the arguments and constructing the thread.
     * @param argv Holding values for the host, user, and the password of the user.
     */
    public static void main( String args[] ) {
        Thread thread;

        if ( args.length < 4 ) {
            System.out.println(
                "usage: java -jar NotesAccess.jar \"<Domino Host>\" \"<User>\" " +
                "\"<Password>\" \"<Database>\"" );
            System.out.println( "\ne.g.:" );
            System.out.println(
                "java -jar NotesAccess.jar \"\" \"\" \"\" \"Stocks.nsf\"" );
            System.exit( 1 );
        }

        if ( !args[ 0 ].trim().equals( "" ) ) {
            stringHost = args[ 0 ].trim();
        }
        if ( !args[ 1 ].trim().equals( "" ) ) {
            stringUser = args[ 1 ].trim();
        }
        stringPassword = args[ 2 ].trim();

        try {
            java.io.File sourceFile = new java.io.File(args[ 3 ].trim());
            stringDatabase = sourceFile.getCanonicalPath();
        } catch (java.io.IOException e) {
            System.out.println("Error: Please check the name or path to your database file.");
            e.printStackTrace();
            System.exit( 1 );
        }

        if ( stringHost.equals( "" ) ) {
            // Initializing.
            NotesAccess notesaccess = new NotesAccess();

            // Allowing only local calls to the Domino classes.
            thread = new NotesThread( ( Runnable ) notesaccess );
        }
        else {
            // Extracting the host, user, and password.
            NotesAccess notesaccess = new NotesAccess();

            // Allowing remote calls to the Domino classes.
            thread = new Thread( ( Runnable ) notesaccess );
        }

        // Starting the thread.
        thread.start();
    }

    /** This is the default constructor without arguments.
     */
    public NotesAccess() {
    }

    /** Reading all documents from the given database and writing the data to
     * an OpenOffice.org Calc spreadsheet document.
     */
    public void run() {
        try {
            // get the remote office component context
            XComponentContext xContext =
                com.sun.star.comp.helper.Bootstrap.bootstrap();

            System.out.println("Connected to a running office ...");

            XMultiComponentFactory xMCF = xContext.getServiceManager();

            /* A desktop environment contains tasks with one or more
               frames in which components can be loaded. Desktop is the
               environment for components which can instantiate within
               frames. */
            XComponentLoader xLoader = ( XComponentLoader )
                UnoRuntime.queryInterface(XComponentLoader.class,
                    xMCF.createInstanceWithContext(
                        "com.sun.star.frame.Desktop", xContext));

            // Load a Writer document, which will be automatically displayed
            XComponent xComponent = xLoader.loadComponentFromURL(
                "private:factory/scalc", "_blank", 0,
                new PropertyValue[0] );

            // Querying for the interface XSpreadsheetDocument
            XSpreadsheetDocument xSpreadsheetDoc =
                (XSpreadsheetDocument) UnoRuntime.queryInterface(
                    XSpreadsheetDocument.class, xComponent);

            // Getting all sheets from the spreadsheet document.
            XSpreadsheets xSpreadsheets = xSpreadsheetDoc.getSheets() ;

            // Querying for the interface XIndexAccess.
            XIndexAccess xIndexAccess = (XIndexAccess) UnoRuntime.queryInterface(
                XIndexAccess.class, xSpreadsheets);

            // Getting the first spreadsheet.
            XSpreadsheet xSpreadsheet = (XSpreadsheet) UnoRuntime.queryInterface(
                XSpreadsheet.class, xIndexAccess.getByIndex(0));

            Session session;
            if ( !stringHost.equals( "" ) ) {
                // Creating a Notes session for remote calls to the Domino classes.
                session = NotesFactory.createSession(stringHost, stringUser,
                                                     stringPassword);
            }
            else {
                // Creating a Notes session for only local calls to the
                // Domino classes.
                session = NotesFactory.createSession();
            }

            // Getting the specified Notes database.
            Database database = session.getDatabase( "", stringDatabase );

            // Getting a collection of all documents from the database.
            DocumentCollection documentCollection = database.getAllDocuments();

            // Getting the first document from the database
            Document document = documentCollection.getFirstDocument();

            // Start to write to cells at this row.
            int intRowToStart = 0;

            // The current row.
            int intRow = intRowToStart;

            // The current column.
            int intColumn = 0;

            // Process all documents
            while ( document != null ) {
                // Getting the name of the stock.
                String stringName = document.getItemValueString("Name");

                // Inserting the name to a specified cell.
                insertIntoCell(intColumn, intRow, stringName, xSpreadsheet, "");

                // Getting the number of stocks.
                double intNumber = document.getItemValueInteger( "Number" );

                // Inserting the number of stocks to a specified cell.
                insertIntoCell( intColumn + 1, intRow, String.valueOf(intNumber),
                                xSpreadsheet, "V" );

                // Getting current share price.
                double doubleSharePrice = document.getItemValueDouble("SharePrice");

                // Inserting the current share price to a specified cell.
                insertIntoCell(intColumn + 2, intRow,
                               String.valueOf(doubleSharePrice),
                               xSpreadsheet, "V");

                // Inserting the total value.
                insertIntoCell(intColumn + 3, intRow, "=B"
                               + String.valueOf( intRow + 1 )
                               + "*C" + String.valueOf(intRow + 1),
                               xSpreadsheet, "");

                // Increasing the current row.
                intRow++;

                // Getting the next document from the collection.
                document = documentCollection.getNextDocument();
            }

            // Summing all specific amounts.
            insertIntoCell(intColumn + 3, intRow, "=sum(D"
                           + String.valueOf( intRowToStart + 1 ) + ":D"
                           + String.valueOf( intRow ),
                           xSpreadsheet, "");

            xContext = null;

            // Leaving the program.
            System.exit(0);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    /** Inserting a value or formula to a cell defined by the row and column.
     * @param intCellX Row.
     * @param intCellY Column.
     * @param stringValue This value will be written to the cell.
     * @param xSpreadsheet Write the value to the cells of this spreadsheet.
     * @param stringFlag If this string contains "V", the value will be written,
     *                   otherwise the formula.
   */
    public static void insertIntoCell(int intCellX, int intCellY,
                                      String stringValue,
                                      XSpreadsheet xSpreadsheet,
                                      String stringFlag)
    {
        XCell xCell = null;

        try {
            xCell = xSpreadsheet.getCellByPosition( intCellX, intCellY );
        } catch ( com.sun.star.lang.IndexOutOfBoundsException exception ) {
            System.out.println( "Could not get Cell" );
        }
        if ( stringFlag.equals( "V" )) {
            xCell.setValue((new Float(stringValue)).floatValue());
        }
        else {
            xCell.setFormula(stringValue);
        }
    }
}
