/*************************************************************************
 *
 *  $RCSfile: _XAccessibleEditableText.java,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change:$Date: 2003-04-28 12:22:40 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

package ifc.accessibility;

import lib.MultiMethodTest;
import com.sun.star.accessibility.XAccessibleEditableText;
import com.sun.star.beans.PropertyValue;
import util.ValueComparer;
import util.ValueChanger;

/**
 * Testing <code>com.sun.star.accessibility.XAccessibleEditableText</code>
 * interface methods :
 * <ul>
 *  <li><code> cutText()</code></li>
 *  <li><code> pasteText()</code></li>
 *  <li><code> deleteText()</code></li>
 *  <li><code> insertText()</code></li>
 *  <li><code> replaceText()</code></li>
 *  <li><code> setAttributes()</code></li>
 *  <li><code> setText()</code></li>
 * </ul> <p>
 *
 * This test needs the following object relations :
 * <ul>
 *  <li> <code>'XAccessibleEditableText.hasAttr'</code>
 *  (of type <code>Boolean</code>):
 *   Indicates whether or not the text has changeable attributes.
 *   E.g. text within writer document have attributes which can
 *   be changed, while the text within edit field has fixed
 *   attributes. <p>
 *   If the relation is <code>false</code> then the component
 *   has fixed text attributes. </li>
 * </ul> <p>
 *
 * @see com.sun.star.accessibility.XAccessibleEditableText
 */
public class _XAccessibleEditableText extends MultiMethodTest {
    private static final String className =
        "com.sun.star.accessibility.XAccessibleEditableText" ;

    public XAccessibleEditableText oObj = null;

    // temporary while accessibility package is in com.sun.star
    protected String getTestedClassName() {
        return className;
    }

    String pasteText = null;

    String initialText = "";

    /**
     * Indicates whether or not the text has changeable attributes.
     * E.g. text within writer document have attributes which can
     * be changed, while the text within edit field has fixed
     * attributes.
     */
     private boolean changeableAttr = true;

     /**
      * Retrieves object relation. Stores initial component text
      * for restoding it in <code>after</code>.
      */
     protected void before() {
        Boolean b = (Boolean)
            tEnv.getObjRelation("XAccessibleEditableText.hasAttr");
        if (b != null) {
            changeableAttr = b.booleanValue();
        }

        initialText = oObj.getText();
     }

    /**
     * Calls the method with the wrong indexes and with the correct indexes.
     * Stores cutted text in the variable <code>pasteText</code>.
     * Has OK status if exceptions were thrown for the wrong indexes,
     * if exception wasn't thrown for the correct indexes.
     */
    public void _cutText() {
        boolean res = true;
        boolean locRes = true;
        String curText = null;

        String oldText = oObj.getText();
        log.println("Text: '" + oldText + "'");
        int length = oObj.getCharacterCount();
        log.println("Character count: " + length);

        try {
            log.print("cutText(-1," + (length-1) + "): ");
            locRes = oObj.cutText(-1, length - 1);
            log.println(locRes);
            log.println("exception was expected");
            res &= false;
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("expected exception");
            curText = oObj.getText();
            log.println("Current text: '" + curText + "'");
            res &= curText.equals(oldText);
        }

        try {
            log.print("cutText(0," + (length+1) + "): ");
            locRes = oObj.cutText(0, length + 1);
            log.println(locRes);
            log.println("exception was expected");
            res &= false;
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("expected exception");
            curText = oObj.getText();
            log.println("Current text: '" + curText + "'");
            res &= curText.equals(oldText);
        }

        try {
            pasteText = oldText;
            log.print("cutText(0," + length + "): ");
            locRes = oObj.cutText(0, length);
            log.println(locRes);
            curText = oObj.getText();
            log.println("Current text: '" + curText + "'");
            res &= curText.length() == 0 && locRes;
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("unexpected exception");
            e.printStackTrace(log);
            res &= false;
        }

        tRes.tested("cutText()", res);
    }

    /**
     * Calls the method with the wrong indexes and with the correct indexes.
     * Has OK status if exceptions were thrown for the wrong indexes,
     * if exception wasn't thrown for the correct indexes and if cutted text was
     * pasted.
     * The following method tests are to be executed before:
     * <ul>
     *  <li> <code>cutText()</code> </li>
     * </ul>
     */
    public void _pasteText() {
        requiredMethod("cutText()");
        boolean res = true;
        boolean locRes = true;
        String curText = null;

        String text = oObj.getText();
        log.println("Text: '" + text + "'");
        int length = oObj.getCharacterCount();
        log.println("Character count: " + length);

        try {
            log.print("pasteText(-1): ");
            locRes = oObj.pasteText(-1);
            log.println(locRes);
            log.println("exception was expected");
            res &= false;
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("expected exception");
            curText = oObj.getText();
            log.println("Current text: '" + curText + "'");
            res &= curText.equals(text);
        }

        try {
            log.print("pasteText(" + (length+1) + "): ");
            locRes = oObj.pasteText(length + 1);
            log.println(locRes);
            log.println("exception was expected");
            res &= false;
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("expected exception");
            curText = oObj.getText();
            log.println("Current text: '" + curText + "'");
            res &= curText.equals(text);
        }

        try {
            log.print("pasteText(" + (length) + "): ");
            locRes = oObj.pasteText(length);
            log.println(locRes);
            curText = oObj.getText();
            log.println("Current text: '" + curText + "'");
            res &= curText.equals(text + pasteText) && locRes;
            log.println("Expected text: '" + text + pasteText + "'");
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("unexpected exception");
            e.printStackTrace(log);
            res &= false;
        }

        tRes.tested("pasteText()", res);
    }

    /**
     * Calls the method with the wrong indexes and with the correct indexes,
     * checks text after method call.
     * Has OK status if exceptions were thrown for the wrong indexes,
     * if exception wasn't thrown for the correct indexes and if deleted string
     * was really deleted from the text.
     * The following method tests are to be executed before:
     * <ul>
     *  <li> <code>insertText()</code> </li>
     * </ul>
     */
    public void _deleteText() {
        executeMethod("insertText()");
        boolean res = true;
        boolean locRes = true;
        String curText = null;

        String text = oObj.getText();
        log.println("Text: '" + text + "'");
        int length = oObj.getCharacterCount();
        log.println("Character count: " + length);

        try {
            log.print("deleteText(-1," + length + "): ");
            locRes = oObj.deleteText(-1, length);
            log.println(locRes);
            log.println("exception was expected");
            res &= false;
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("expected exception");
            curText = oObj.getText();
            log.println("Current text: '" + curText + "'");
            res &= curText.equals(text);
        }

        try {
            log.print("deleteText(0," + (length+1) + "): ");
            locRes = oObj.deleteText(0, length + 1);
            log.println(locRes);
            log.println("exception was expected");
            res &= false;
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("expected exception");
            curText = oObj.getText();
            log.println("Current text: '" + curText + "'");
            res &= curText.equals(text);
        }

        try {
            if (length >= 1) {
                log.print("deleteText(" + (length-1) + "," + (length) + "): ");
                locRes = oObj.deleteText(length - 1, length);
                log.println(locRes);
                String expStr = expStr = text.substring(0, length - 1);
                curText = oObj.getText();
                log.println("Current text: '" + curText + "'");
                res &= curText.equals(expStr);
                log.println("Expected text: '" + expStr + "'");
            }
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("unexpected exception");
            e.printStackTrace(log);
            res &= false;
        }

        tRes.tested("deleteText()", res);
    }

    /**
     * Calls the method with the wrong indexes and with the correct indexes,
     * checks text after method call.
     * Has OK status if exceptions were thrown for the wrong indexes,
     * if exception wasn't thrown for the correct indexes and if inserted string
     * was really inserted into the text.
     * The following method tests are to be executed before:
     * <ul>
     *  <li> <code>pasteText()</code> </li>
     * </ul>
     */
    public void _insertText() {
        executeMethod("pasteText()");
        boolean res = true;
        boolean locRes = true;
        String curText = null;

        String text = oObj.getText();
        log.println("Text: '" + text + "'");
        int length = oObj.getCharacterCount();
        log.println("Character count: " + length);

        final String insStr = "Inserted string";

        try {
            log.print("insertText(insStr, -1): ");
            locRes = oObj.insertText(insStr, -1);
            log.println(locRes);
            log.println("exception was expected");
            res &= false;
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("expected exception");
            curText = oObj.getText();
            log.println("Current text: '" + curText + "'");
            res &= curText.equals(text);
        }

        try {
            log.print("insertText(insStr," + (length+1) + "): ");
            locRes = oObj.insertText(insStr, length+1);
            log.println(locRes);
            log.println("exception was expected");
            res &= false;
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("expected exception");
            curText = oObj.getText();
            log.println("Current text: '" + curText + "'");
            res &= curText.equals(text);
        }

        try {
            log.print("insertText(insStr," + length + "): ");
            locRes = oObj.insertText(insStr, length);
            log.println(locRes);
            curText = oObj.getText();
            res &= curText.equals(text + insStr);
            log.println("Current text: '" + curText + "'");
            log.println("Expected text: '" + text + insStr + "'");
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("unexpected exception");
            e.printStackTrace(log);
            res &= false;
        }

        tRes.tested("insertText()", res);
    }

    /**
     * Calls the method with the wrong indexes and with the correct indexes,
     * checks text after method call.
     * Has OK status if exceptions were thrown for the wrong indexes,
     * if exception wasn't thrown for the correct indexes and if part of text
     * was really replaced by the specified replacement string.
     * The following method tests are to be executed before:
     * <ul>
     *  <li> <code>deleteText()</code> </li>
     * </ul>
     */
    public void _replaceText() {
        executeMethod("deleteText()");
        boolean res = true;
        boolean locRes = true;
        String curText = null;

        final String sReplacement = "String for replace";
        String oldText = oObj.getText();
        int startIndx = oldText.length();
        oObj.setText(oldText + " part of string for replace");

        String text = oObj.getText();
        log.println("Text: '" + text + "'");
        int length = oObj.getCharacterCount();
        log.println("Character count: " + length);

        try {
            log.print("replaceText(-1," + length + "): ");
            locRes = oObj.replaceText(-1, length, sReplacement);
            log.println(locRes);
            log.println("exception was expected");
            res &= false;
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("expected exception");
            curText = oObj.getText();
            log.println("Current text: '" + curText + "'");
            res &= curText.equals(text);
        }

        try {
            log.print("replaceText(0," + (length+1) + "): ");
            locRes = oObj.replaceText(0, length + 1, sReplacement);
            log.println(locRes);
            log.println("exception was expected");
            res &= false;
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("expected exception");
            curText = oObj.getText();
            log.println("Current text: '" + curText + "'");
            res &= curText.equals(text);
        }

        try {
            log.print("replaceText(" + startIndx + "," + length + "): ");
            locRes = oObj.replaceText(startIndx, length, sReplacement);
            log.println(locRes);
            curText = oObj.getText();
            log.println("Current text: '" + curText + "'");
            log.println("Expected text: '" + oldText + sReplacement + "'");
            res &= curText.equals(oldText + sReplacement);
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("unexpected exception");
            e.printStackTrace(log);
            res &= false;
        }

        tRes.tested("replaceText()", res);
    }

    /**
     * Calls the method with the wrong indexes and with the correct indexes,
     * checks attributes after method call.
     * Has OK status if exceptions were thrown for the wrong indexes,
     * if exception wasn't thrown for the correct indexes and if attributes
     * of text was changed.
     * The following method tests are to be executed before:
     * <ul>
     *  <li> <code>replaceText()</code> </li>
     * </ul>
     */
    public void _setAttributes() {
        executeMethod("replaceText()");
        boolean res = true;
        boolean locRes = true;

        String text = oObj.getText();
        log.println("Text: '" + text + "'");
        int length = oObj.getCharacterCount();
        log.println("Length: " + length);

        PropertyValue[] attrs = null;

        try {
            attrs = oObj.getCharacterAttributes(0, new String[]{""});
            log.print("setAttributes(-1," + (length - 1) + "):");
            locRes = oObj.setAttributes(-1, length - 1, attrs);
            log.println(locRes);
            log.println("exception was expected");
            res &= false;
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("expected exception");
            res &= true;
        }

        try {
            log.print("setAttributes(0," + (length+1) + "):");
            locRes = oObj.setAttributes(0, length + 1, attrs);
            log.println(locRes);
            log.println("exception was expected");
            res &= false;
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("expected exception");
            res &= true;
        }

        //change old attributes set
        for(int i = 0; i < attrs.length; i++) {
            if (attrs[i].Name.equals("CharColor")) {
                attrs[i].Value = new Integer(-2);
            }
        }

        try {
            log.print("setAttributes(0," + length + "):");
            locRes = oObj.setAttributes(0, length, attrs);
            log.println(locRes);
            res &= (changeableAttr && locRes)
                || (!changeableAttr && !locRes);
            if (changeableAttr) {
                log.print("checking that new attributes was set...");
                PropertyValue[] newAttrs = oObj.getCharacterAttributes(0, new String[]{""});
                locRes = ValueComparer.equalValue(attrs, newAttrs);
                log.println(locRes);
                res &= locRes;
            } else {
                log.println("Text attributes can't be changed.");
            }
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            log.println("unexpected exception");
            e.printStackTrace(log);
            res &= false;
        }

        tRes.tested("setAttributes()", res);
    }

    /**
     * Calls the method with different parameters and checks text.
     */
    public void _setText() {
        executeMethod("setAttributes()");
        boolean res = true;
        boolean locRes = true;

        String oldText = oObj.getText();
        log.println("Current text: '" + oldText + "'");

        String newText = "New text";
        log.print("setText('" + newText + "'): ");
        locRes = oObj.setText(newText);
        log.println(locRes);
        String newCurText = oObj.getText();
        log.println("getText(): '" + newCurText + "'");
        res &= locRes && newCurText.equals(newText);

        newText = "";
        log.print("setText('" + newText + "'): ");
        locRes = oObj.setText(newText);
        log.println(locRes);
        newCurText = oObj.getText();
        log.println("getText(): '" + newCurText + "'");
        res &= locRes && newCurText.equals(newText);

        log.print("setText('" + oldText + "'): ");
        locRes = oObj.setText(oldText);
        log.println(locRes);
        newCurText = oObj.getText();
        log.println("getText(): '" + newCurText + "'");
        res &= locRes && newCurText.equals(oldText);

        tRes.tested("setText()", res);
    }

    /**
     * Restores initial component text.
     */
    protected void after() {
        oObj.setText(initialText);
    }
}