/**************************************************************
 * 
 * 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 ifc.beans;

import java.util.Vector;

import lib.MultiMethodTest;
import util.ValueChanger;
import util.utils;

import com.sun.star.beans.Property;
import com.sun.star.beans.PropertyAttribute;
import com.sun.star.beans.PropertyChangeEvent;
import com.sun.star.beans.XPropertyChangeListener;
import com.sun.star.beans.XPropertySet;
import com.sun.star.beans.XPropertySetInfo;
import com.sun.star.beans.XVetoableChangeListener;
import com.sun.star.lang.EventObject;

/**
* Testing <code>com.sun.star.beans.XPropertySet</code>
* interface methods :
* <ul>
*  <li><code>getPropertySetInfo()</code></li>
*  <li><code>setPropertyValue()</code></li>
*  <li><code>getPropertyValue()</code></li>
*  <li><code>addPropertyChangeListener()</code></li>
*  <li><code>removePropertyChangeListener()</code></li>
*  <li><code>addVetoableChangeListener()</code></li>
*  <li><code>removeVetoableChangeListener()</code></li>
* </ul>
* @see com.sun.star.beans.XPropertySet
*/
public class _XPropertySet extends MultiMethodTest {

    public XPropertySet oObj = null;

    /**
    * Flag that indicates change listener was called.
    */
    private boolean propertyChanged = false;

    /**
    * Listener that must be called on bound property changing.
    */
    public class MyChangeListener implements XPropertyChangeListener {
         /**
         * Just set <code>propertyChanged</code> flag to true.
         */
         public void propertyChange(PropertyChangeEvent e) {
            propertyChanged = true;
         }
         public void disposing (EventObject obj) {}
    };

    private final XPropertyChangeListener PClistener = new MyChangeListener();

    /**
    * Flag that indicates veto listener was called.
    */
    private boolean vetoableChanged = false;

    /**
    * Listener that must be called on constrained property changing.
    */
    public class MyVetoListener implements XVetoableChangeListener {
         /**
         * Just set <code>vetoableChanged</code> flag to true.
         */
         public void vetoableChange(PropertyChangeEvent e) {
            vetoableChanged = true;
         }
         public void disposing (EventObject obj) {}
    };

    private final XVetoableChangeListener VClistener = new MyVetoListener();

    /**
    * Structure that collects the properties of different types to test :
    * Constrained, Bound and Normal.
    */
    private final class PropsToTest {
        Vector< String > constrained = new Vector< String >();
        Vector< String > bound = new Vector< String >();
        Vector< String > normal = new Vector< String >();
    }

    private final PropsToTest PTT = new PropsToTest();

    /**
    * Tests method <code>getPropertySetInfo</code>. After test completed
    * call {@link #getPropsToTest} method to retrieve different kinds
    * of properties to test then. <p>
    * Has OK status if not null <code>XPropertySetInfo</code>
    * object returned.<p>
    * Since <code>getPropertySetInfo</code> is optional, it may return null,
    * if it is not implemented. This method uses then an object relation
    * <code>PTT</code> (Properties To Test) to determine available properties.
    * All tests for services without <code>getPropertySetInfo</code> must
    * provide this object relation.
    */
    public void _getPropertySetInfo() {

        XPropertySetInfo propertySetInfo = oObj.getPropertySetInfo();

        if (propertySetInfo == null) {
            log.println("getPropertySetInfo() method returned null");
            tRes.tested("getPropertySetInfo()", true) ;
            String[] ptt = (String[]) tEnv.getObjRelation("PTT");
            PTT.normal.clear();
            PTT.bound.clear();
            PTT.constrained.clear();
            PTT.normal.add( ptt[0] );
            PTT.bound.add( ptt[1] );
            PTT.constrained.add( ptt[2] );
        } else {
            tRes.tested("getPropertySetInfo()", true );
            getPropsToTest(propertySetInfo);
        }

        return;

    } // end of getPropertySetInfo()

    /**
    * Tests change listener which added for bound properties.
    * Adds listener to bound property (if it exists), then changes
    * its value and check if listener was called. <p>
    * Method tests to be successfully completed before :
    * <ul>
    *  <li> <code>getPropertySetInfo</code> : in this method test
    *    one of bound properties is retrieved. </li>
    * </ul> <p>
    * Has OK status if NO bound properties exist or if listener
    * was successfully called.
    */
    public void _addPropertyChangeListener() {

        requiredMethod("getPropertySetInfo()");
        
        int count = PTT.bound.size();
        if ( count==0 || PTT.bound.get(0).equals("none") ) {
            log.println("*** No bound properties found ***");
            tRes.tested("addPropertyChangeListener()", true) ;
        } else {
            boolean error = false;
            for (int i = 0; i < count; i++) {
                String propertyName = PTT.bound.get(i);
                propertyChanged = false;
                try {
                    oObj.addPropertyChangeListener(propertyName,PClistener);
                    Object gValue = oObj.getPropertyValue(propertyName);
                    log.println("Check bound property: " + propertyName );
                    oObj.setPropertyValue(propertyName,
                        ValueChanger.changePValue(gValue));
                } catch (com.sun.star.beans.PropertyVetoException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.lang.IllegalArgumentException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.beans.UnknownPropertyException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.lang.WrappedTargetException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } // end of try-catch
                error = error || !propertyChanged;
                if (!propertyChanged) {
                    log.println("propertyChangeListener wasn't called for '"+
                        propertyName+"'");
                }
            }
            tRes.tested("addPropertyChangeListener()", !error);
        }
        
        return;

    } // end of addPropertyChangeListener()

    /**
    * Tests vetoable listener which added for constrained properties.
    * Adds listener to constrained property (if it exists), then changes
    * its value and check if listener was called. <p>
    * Method tests to be successfully completed before :
    * <ul>
    *  <li> <code>getPropertySetInfo</code> : in this method test
    *    one of constrained properties is retrieved. </li>
    * </ul> <p>
    * Has OK status if NO constrained properties exist or if listener
    * was successfully called.
    */
    public void _addVetoableChangeListener() {

        requiredMethod("getPropertySetInfo()");

        int count = PTT.constrained.size();
        if ( count==0 || PTT.constrained.get(0).equals("none") ) {
            log.println("*** No constrained properties found ***");
            tRes.tested("addVetoableChangeListener()", true) ;
        } else {
            boolean error = false;
            for (int i = 0; i < count; i++) {
                String propertyName = PTT.constrained.get(i);
                vetoableChanged = false;
                try {
                    oObj.addVetoableChangeListener(propertyName,VClistener);
                    Object gValue = oObj.getPropertyValue(propertyName);
                    oObj.setPropertyValue(propertyName,
                        ValueChanger.changePValue(gValue));
                } catch (com.sun.star.beans.PropertyVetoException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.lang.IllegalArgumentException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.beans.UnknownPropertyException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.lang.WrappedTargetException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } // end of try-catch
                error = error || !vetoableChanged;
                if (!vetoableChanged) {
                    log.println("vetoableChangeListener wasn't called for '"+
                        propertyName+"'");
                }
            }
            tRes.tested("addVetoableChangeListener()",!error);
        }

        return;

    } // end of addVetoableChangeListener()


    /**
    * Tests <code>setPropertyValue</code> method.
    * Stores value before call, and compares it with value after
    * call. <p>
    * Method tests to be successfully completed before :
    * <ul>
    *  <li> <code>getPropertySetInfo</code> : in this method test
    *    one of normal properties is retrieved. </li>
    * </ul> <p>
    * Has OK status if NO normal properties exist or if value before
    * method call is not equal to value after.
    */
    public void _setPropertyValue() {

        requiredMethod("getPropertySetInfo()");

        Object gValue = null;
        Object sValue = null;

        int count = PTT.normal.size();
        if ( count==0 || PTT.normal.get(0).equals("none") ) {
            log.println("*** No changeable properties found ***");
            tRes.tested("setPropertyValue()", true) ;
        } else {
            boolean error = false;
            for (int i = 0; i < count; i++) {
                String propertyName = PTT.normal.get(i);
                try {
                    log.println("try to change value of property '" + propertyName + "'" );
                    gValue = oObj.getPropertyValue(propertyName);
                    sValue = ValueChanger.changePValue(gValue);
                    oObj.setPropertyValue(propertyName, sValue);
                    sValue = oObj.getPropertyValue(propertyName);
                } catch (com.sun.star.beans.PropertyVetoException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.lang.IllegalArgumentException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.beans.UnknownPropertyException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.lang.WrappedTargetException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } // end of try-catch
                if( gValue.equals(sValue) )
                {
                    log.println("setting property '"+ propertyName+"' failed");
                    error = true;
                }
            }
            tRes.tested("setPropertyValue()",!error);
        } //endif

        return;

    } // end of setPropertyValue()

    /**
    * Tests <code>getPropertyValue</code> method for the given property.
    * Returns true if no exceptions occured
    */
    private boolean getSinglePropertyValue( String propertyName )
    {
        boolean runOk = false;
        try {
            oObj.getPropertyValue(propertyName);
            runOk = true;
        } catch (com.sun.star.beans.UnknownPropertyException e) {
            log.println("Exception occured while trying to get property '"+
                 propertyName+"'");
            e.printStackTrace(log);
        } catch (com.sun.star.lang.WrappedTargetException e) {
            log.println("Exception occured while trying to get property '"+
                propertyName+"'");
            e.printStackTrace(log);
        }
        return runOk;
    }
                
    /**
    * Tests <code>getPropertyValue</code> method.
    * Just call this method and checks for no exceptions <p>
    * Method tests to be successfully completed before :
    * <ul>
    *  <li> <code>getPropertySetInfo</code> : in this method test
    *    one of normal properties is retrieved. </li>
    * </ul> <p>
    * Has OK status if NO normal properties exist or if no
    * exceptions were thrown.
    */
    public void _getPropertyValue() {

        requiredMethod("getPropertySetInfo()");

        int count = PTT.normal.size();
        if ( count==0 || PTT.normal.get(0).equals("none") ) {
            Property[] properties = oObj.getPropertySetInfo().getProperties();    
            if( properties.length > 0 ) {
                String propertyName = properties[0].Name;
                log.println("All properties are Read Only");
                log.println("Using: "+propertyName);
                tRes.tested("getPropertyValue()", getSinglePropertyValue( propertyName ) );
            }
            else {
                log.println("*** No properties found ***");
                tRes.tested("getPropertyValue()", true) ;
            }
        } else {
            boolean error = false;
            for (int i = 0; i < count; i++) {
                String propertyName = PTT.normal.get(i);
                boolean runOk = getSinglePropertyValue( propertyName );
                if( !runOk )
                {
                    error = true;
                    log.println("getPropertyValue() failed for property '"+propertyName+"'");
                }
            }
            tRes.tested("getPropertyValue()", !error) ;
        }

        return;
    }

    /**
    * Tests <code>removePropertyChangeListener</code> method.
    * Removes change listener, then changes bound property value
    * and checks if the listener was NOT called.
    * Method tests to be successfully completed before :
    * <ul>
    *  <li> <code>addPropertyChangeListener</code> : here listener
    *   was added. </li>
    * </ul> <p>
    * Has OK status if NO bound properties exist or if listener
    * was not called and no exceptions arose.
    */
    public void _removePropertyChangeListener() {

        requiredMethod("addPropertyChangeListener()");

        int count = PTT.bound.size();
        if ( count==0 || PTT.bound.get(0).equals("none") ) {
            log.println("*** No bound properties found ***");
            tRes.tested("removePropertyChangeListener()", true) ;
        } else {
            
            //remove all listeners first
            for (int i = 0; i < count; i++) {
                String propertyName = PTT.bound.get(i);
                try {
                    oObj.removePropertyChangeListener(propertyName,PClistener);
                } catch (Exception e) {
                    log.println("Exception occured while removing change listener from"+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                }
            }
            
            boolean error = false;
            for (int i = 0; i < count; i++) {
                String propertyName = PTT.bound.get(i);
                try {
                    propertyChanged = false;
                    oObj.addPropertyChangeListener(propertyName,PClistener);
                    oObj.removePropertyChangeListener(propertyName,PClistener);
                    Object gValue = oObj.getPropertyValue(propertyName);
                    oObj.setPropertyValue(propertyName,
                        ValueChanger.changePValue(gValue));
                } catch (com.sun.star.beans.PropertyVetoException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.lang.IllegalArgumentException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.beans.UnknownPropertyException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.lang.WrappedTargetException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } // end of try-catch

                error = error || propertyChanged;
                if (propertyChanged) {
                    log.println("propertyChangeListener was called after removing"+
                        " for '"+propertyName+"'");
                }
            }
            tRes.tested("removePropertyChangeListener()",!error);
        }

        return;

    } // end of removePropertyChangeListener()


    /**
    * Tests <code>removeVetoableChangeListener</code> method.
    * Removes vetoable listener, then changes constrained property value
    * and checks if the listener was NOT called.
    * Method tests to be successfully completed before :
    * <ul>
    *  <li> <code>addPropertyChangeListener</code> : here vetoable listener
    *   was added. </li>
    * </ul> <p>
    * Has OK status if NO constrained properties exist or if listener
    * was NOT called and no exceptions arose.
    */
    public void _removeVetoableChangeListener() {

        requiredMethod("addVetoableChangeListener()");

        int count = PTT.constrained.size();
        if ( count==0 || PTT.constrained.get(0).equals("none") ) {
            log.println("*** No constrained properties found ***");
            tRes.tested("removeVetoableChangeListener()", true) ;
        } else {
        
            //remove all listeners first
            for (int i = 0; i < count; i++) {
                String propertyName = PTT.constrained.get(i);
                try {
                    oObj.removeVetoableChangeListener(propertyName,VClistener);
                } catch (Exception e) {
                    log.println("Exception occured while removing veto listener from"+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                }
            }
            
            boolean error = false;
            for (int i = 0; i < count; i++) {
                String propertyName = PTT.constrained.get(i);
                vetoableChanged = false;
                try {
                    oObj.addVetoableChangeListener(propertyName,VClistener);
                    oObj.removeVetoableChangeListener(propertyName,VClistener);
                    Object gValue = oObj.getPropertyValue(propertyName);
                    oObj.setPropertyValue(propertyName,
                        ValueChanger.changePValue(gValue));
                } catch (com.sun.star.beans.PropertyVetoException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.lang.IllegalArgumentException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.beans.UnknownPropertyException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } catch (com.sun.star.lang.WrappedTargetException e) {
                    log.println("Exception occured while trying to change "+
                        "property '"+ propertyName+"'");
                    e.printStackTrace(log);
                } // end of try-catch
                error = error || vetoableChanged;
                if (vetoableChanged) {
                    log.println("vetoableChangeListener was called after "+
                        "removing for '"+propertyName+"'");
                }
            }
            tRes.tested("removeVetoableChangeListener()",!error);
        }

        return;

    } // end of removeVetoableChangeListener()

    /**
    * Gets the properties being tested. Searches and stores by one
    * property of each kind (Bound, Vetoable, Normal).
    */
    public void getPropsToTest(XPropertySetInfo xPSI) {

        Property[] properties = xPSI.getProperties();
        // some properties should not be changed in a unspecific way
        String[] skip = {"PrinterName", "CharRelief", "IsLayerMode"};

        for (int i = 0; i < properties.length; i++) {

            Property property = properties[i];
            String name = property.Name;
            
            boolean cont = false;
            for (int j = 0; j < skip.length; j++) {
                if (name.equals(skip[j])){
                    log.println("skipping '" + name + "'");
                    cont = true;
                }
            }
            
            if (cont) continue;
            
            if (name.equals(oObj))
            log.println("Checking '"+name+"'");
            boolean isWritable = ((property.Attributes &
                PropertyAttribute.READONLY) == 0);
            boolean isNotNull = ((property.Attributes &
                PropertyAttribute.MAYBEVOID) == 0);
            boolean isBound = ((property.Attributes &
                PropertyAttribute.BOUND) != 0);
            boolean isConstr = ((property.Attributes &
                PropertyAttribute.CONSTRAINED) != 0);
            boolean canChange = false;

            if ( !isWritable ) log.println("Property '"+name+"' is READONLY");

            if (name.endsWith("URL")) isWritable = false;
            if (name.startsWith("Fill")) isWritable = false;
            if (name.startsWith("Font")) isWritable = false;
            if (name.startsWith("IsNumbering")) isWritable = false;
            if (name.startsWith("LayerName")) isWritable = false;
            if (name.startsWith("Line")) isWritable = false;
            if (name.startsWith("TextWriting")) isWritable = false;

            //if (name.equals("xinterfaceA") || name.equals("xtypeproviderA")
            //|| name.equals("arAnyA")) isWritable=false;

            if ( isWritable && isNotNull ) canChange = isChangeable(name);

            if ( isWritable && isNotNull && isBound && canChange) {
                PTT.bound.add(name);
            }

            if ( isWritable && isNotNull && isConstr && canChange) {
                PTT.constrained.add(name);
            }

            if ( isWritable && isNotNull && canChange) {
                PTT.normal.add(name);
            }


        } // endfor
    }

    public boolean isChangeable(String name) {
        boolean hasChanged = false;
        try {
            Object getProp = oObj.getPropertyValue(name);
            log.println("Getting: "+getProp);
            if (name.equals("xinterfaceA")) {
                System.out.println("drin");
            }

            Object setValue = null;
            if (getProp != null) {
                if (!utils.isVoid(getProp))
                    setValue = ValueChanger.changePValue(getProp);
                else log.println("Property '"+name+
                    "' is void but MAYBEVOID isn't set");
            } else log.println("Property '"+name+"'is null and can't be changed");
            if (name.equals("LineStyle")) setValue = null;
            if (setValue != null) {
                log.println("Setting to :"+setValue);
                oObj.setPropertyValue(name, setValue);
                hasChanged = (! getProp.equals(oObj.getPropertyValue(name)));
            } else log.println("Couldn't change Property '"+name+"'");
        } catch (com.sun.star.beans.PropertyVetoException e) {
            log.println("'" + name + "' throws exception '" + e + "'");
            e.printStackTrace(log);
        } catch (com.sun.star.lang.IllegalArgumentException e) {
            log.println("'" + name + "' throws exception '" + e + "'");
            e.printStackTrace(log);
        } catch (com.sun.star.beans.UnknownPropertyException e) {
            log.println("'" + name + "' throws exception '" + e + "'");
            e.printStackTrace(log);
        } catch (com.sun.star.lang.WrappedTargetException e) {
            log.println("'" + name + "' throws exception '" + e + "'");
            e.printStackTrace(log);
        } catch (com.sun.star.uno.RuntimeException e) {
            log.println("'" + name + "' throws exception '" + e + "'");
            e.printStackTrace(log);
        } catch (java.lang.ArrayIndexOutOfBoundsException e) {
            log.println("'" + name + "' throws exception '" + e + "'");
            e.printStackTrace(log);
        }

        return hasChanged;
    }

    /**
    * Forces environment recreation.
    */
    protected void after() {
        disposeEnvironment();
    }


}  // finish class _XPropertySet

