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



package mod._sc;

import java.io.PrintWriter;

import lib.StatusException;
import lib.TestCase;
import lib.TestEnvironment;
import lib.TestParameters;
import util.AccessibilityTools;
import util.SOfficeFactory;
import util.utils;

import com.sun.star.accessibility.AccessibleRole;
import com.sun.star.accessibility.XAccessible;
import com.sun.star.accessibility.XAccessibleAction;
import com.sun.star.accessibility.XAccessibleContext;
import com.sun.star.accessibility.XAccessibleText;
import com.sun.star.awt.XExtendedToolkit;
import com.sun.star.awt.XWindow;
import com.sun.star.beans.PropertyValue;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;

public class ScAccessibleCsvRuler extends TestCase {

    Thread lThread = null;
    static XAccessibleAction accAction = null;

    /**
     * Called to create an instance of <code>TestEnvironment</code> with an
     * object to test and related objects. Subclasses should implement this
     * method to provide the implementation and related objects. The method is
     * called from <code>getTestEnvironment()</code>.
     *
     * @param Param test parameters
     * @param log writer to log information while testing
     *
     * @see TestEnvironment
     * @see #getTestEnvironment
     */
    protected TestEnvironment createTestEnvironment(TestParameters Param, 
                                                    PrintWriter log) {
        XInterface oObj = null;

        shortWait();

        XMultiServiceFactory msf = (XMultiServiceFactory) Param.getMSF();

        try {
            oObj = (XInterface) msf.createInstance("com.sun.star.awt.Toolkit");
        } catch (com.sun.star.uno.Exception e) {
            log.println("Couldn't get toolkit");
            e.printStackTrace(log);
            throw new StatusException("Couldn't get toolkit", e);
        }

        XExtendedToolkit tk = (XExtendedToolkit) UnoRuntime.queryInterface(
                                      XExtendedToolkit.class, oObj);

        XWindow xWindow = (XWindow) UnoRuntime.queryInterface(XWindow.class, 
                                                              tk.getActiveTopWindow());

        XAccessible xRoot = AccessibilityTools.getAccessibleObject(xWindow);

        oObj = AccessibilityTools.getAccessibleObjectForRole(xRoot, AccessibleRole.PUSH_BUTTON, 
                                             "Cancel");

        accAction = (XAccessibleAction) UnoRuntime.queryInterface(
                            XAccessibleAction.class, oObj);

        XAccessibleContext acc = AccessibilityTools.getAccessibleObjectForRole(xRoot, 
                                                               AccessibleRole.RADIO_BUTTON);

        log.println("Click on: " + acc.getAccessibleName());

        XAccessibleAction accAction2 = (XAccessibleAction) UnoRuntime.queryInterface(
                                               XAccessibleAction.class, acc);

        try {
            accAction2.doAccessibleAction(0);
        } catch (com.sun.star.lang.IndexOutOfBoundsException iae) {
        }


        //util.dbg.printInterfaces(oObj);
        AccessibilityTools.printAccessibleTree(log, xRoot);        
        oObj = AccessibilityTools.getAccessibleObjectForRole(xRoot, AccessibleRole.TEXT, 
                                             "Ruler", true);

        log.println("ImplementationName " + utils.getImplName(oObj));

        TestEnvironment tEnv = new TestEnvironment(oObj);

        tEnv.addObjRelation("EditOnly", 
                            "This method isn't supported in this dialog");

        XAccessibleText text = (XAccessibleText) UnoRuntime.queryInterface(
                                       XAccessibleText.class, oObj);

        int lastone = 100;

        for (int i = 0; i < 1000; i++) {
            try {
                text.getCharacterBounds(i);
            } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
                lastone = i - 1;

                break;
            }
        }

        tEnv.addObjRelation("LimitedBounds", new Integer(lastone));
        tEnv.addObjRelation("PreviousUsed",new int[]{11,22,33,44,55,66,77,88,99});

        return tEnv;
    }
    
    /**
    * Called while disposing a <code>TestEnvironment</code>.
    * Disposes calc document.
    * @param Param test parameters
    * @param log writer to log information while testing
    */
    protected void cleanup( TestParameters Param, PrintWriter log) {
/*        log.println( "    closing Dialog " );
        try {
            accAction.doAccessibleAction(0);
        } catch (com.sun.star.lang.IndexOutOfBoundsException iae) {
            log.println("Couldn't close dialog");
        } */
    }

    /**
     * Called while the <code>TestCase</code> initialization. In the
     * implementation does nothing. Subclasses can override to initialize
     * objects shared among all <code>TestEnvironment</code>s.
     *
     * @param Param test parameters
     * @param log writer to log information while testing
     *
     * @see #initializeTestCase
     */
    protected void initialize(TestParameters Param, PrintWriter log) {
        // get a soffice factory object
        SOfficeFactory SOF = SOfficeFactory.getFactory( (XMultiServiceFactory)Param.getMSF());

        log.println("opening dialog");
        
        PropertyValue[] args = new PropertyValue[1];
        try {
            args[0] = new PropertyValue();
            args[0].Name = "InteractionHandler";
            args[0].Value = ((XMultiServiceFactory)Param.getMSF()).createInstance(
                "com.sun.star.comp.uui.UUIInteractionHandler");
        } catch(com.sun.star.uno.Exception e) {
        }
        
        lThread = new loadThread(SOF, args);
        lThread.start();
        shortWait();

    }
    
    /**
    * Sleeps for 2 sec. to allow StarOffice to react on <code>
    * reset</code> call.
    */
    private void shortWait() {
        try {
            Thread.sleep(2000) ;
        } catch (InterruptedException e) {
            log.println("While waiting :" + e) ;
        }
    }    
    
    public class loadThread extends Thread {
        
        private SOfficeFactory SOF = null ;
        private PropertyValue[] args = null;
        public XComponent xSpreadSheedDoc = null;

        public loadThread(SOfficeFactory SOF, PropertyValue[] Args) {
            this.SOF = SOF;
            this.args = Args;
        }

        public void run() {
            try {                
                String url= utils.getFullTestURL("10test.csv");
                log.println("loading "+url);
                SOF.loadDocument(url,args);                
            } catch (com.sun.star.uno.Exception e) {
                e.printStackTrace();
                throw new StatusException( "Couldn't create document ", e );
            }
        }        
    }    
    
}
