/**************************************************************
 * 
 * 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 com.sun.star.wizards.ui.event;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import com.sun.star.wizards.common.PropertyNames;

/**
 * @author rpiterman
 * DataAware objects are used to live-synchronize UI and DataModel/DataObject.
 * It is used as listener on UI events, to keep the DataObject up to date.
 * This class, as a base abstract class, sets a frame of functionality,
 * delegating the data Object get/set methods to a Value object,
 * and leaving the UI get/set methods abstract.
 * Note that event listenning is *not* a part of this model.
 * the updateData() or updateUI() methods should be porogramatically called.
 * in child classes, the updateData() will be binded to UI event calls.
 * <br><br>
 * This class holds references to a Data Object and a Value object.
 * The Value object "knows" how to get and set a value from the 
 * Data Object.
 */
public abstract class DataAware {

    /**
     * this is the data object.
     */
    protected Object dataObject;
    //protected Method setMethod;
    //protected Method getMethod;
    /**
     * A Value Object knows how to get/set a value
     * from/to the data object.
     */
    protected Value value;
    
    /**
     * creates a DataAware object for the given data object and Value object.
     * @param dataObject_
     * @param value_
     */
    protected DataAware(Object dataObject_, Value value_) {
        dataObject = dataObject_;
        value = value_;
        //getMethod = createGetMethod(dataPropName, dataObject);
        //setMethod = createSetMethod(dataPropName, dataObject, getMethod.getReturnType());
    }

    /**
     * returns the data object.
     * @return
     */
    public Object getDataObject() {
        return dataObject;
    }

    /**
     * sets a new data object. Optionally
     * update the UI.
     * @param obj the new data object.
     * @param updateUI if true updateUI() will be called.
     */
    public void setDataObject(Object obj, boolean updateUI) {

        if (obj != null && !value.isAssignable(obj.getClass())) 
            throw new ClassCastException("can not cast new DataObject to original Class");

        dataObject = obj;

        if (updateUI)
            updateUI();

    }

    /**
     * Sets the given value to the data object.
     * this method delegates the job to the
     * Value object, but can be overwritten if
     * another kind of Data is needed.
     * @param newValue the new value to set to the DataObject.
     */
    protected void setToData(Object newValue) {
        value.set(newValue,getDataObject());
    }

    /**
     * gets the current value from the data obejct.
     * this method delegates the job to 
     * the value object.
     * @return the current value of the data object.
     */
    protected Object getFromData() {
        return value.get(getDataObject());
    }
    
    /**
     * sets the given value to the UI control
     * @param newValue the value to set to the ui control.
     */
    protected abstract void setToUI(Object newValue);

    /**
     * gets the current value from the UI control.
     * @return the current value from the UI control.
     */
    protected abstract Object getFromUI();

    /**
     * updates the UI control according to the
     * current state of the data object.
     */
    public void updateUI() {
        Object data = getFromData();
        Object ui = getFromUI();
        if (!equals(data, ui))
            try {
                setToUI(data);
            } catch (Exception ex) {
                ex.printStackTrace();
                //TODO tell user...
            }
        enableControls(data);
    }

    /**
     * enables
     * @param currentValue
     */
    protected void enableControls(Object currentValue) {
    }

    /**
     * updates the DataObject according to
     * the current state of the UI control.
     */
    public void updateData() {
        Object data = getFromData();
        Object ui = getFromUI();
        if (!equals(data, ui))
            setToData(ui);
        enableControls(ui);
    }

    public interface Listener {
        public void eventPerformed(Object event);
    }

    /**
     * compares the two given objects.
     * This method is null safe and returns true also if both are null...
     * If both are arrays, treats them as array of short and compares them.
     * @param a first object to compare
     * @param b second object to compare.
     * @return true if both are null or both are equal.
     */
    protected boolean equals(Object a, Object b) {
        if (a == null && b == null)
            return true;
        if (a == null || b == null)
            return false;
        if (a.getClass().isArray()) {
            if (b.getClass().isArray())
                return Arrays.equals((short[]) a, (short[]) b);
            else
                return false;
        }
        return a.equals(b);
    }

    /**
     * given a collection containing DataAware objects,
     * calls updateUI() on each memebr of the collection.
     * @param dataAwares a collection containing DataAware objects.
     */
    public static void updateUI(Collection dataAwares) {
        for (Iterator i = dataAwares.iterator(); i.hasNext();)
             ((DataAware) i.next()).updateUI();
    }

    public static void updateData(Collection dataAwares) {
        for (Iterator i = dataAwares.iterator(); i.hasNext();)
             ((DataAware) i.next()).updateData();
    }

    /**
     * /**
     * Given a collection containing DataAware objects,
     * sets the given DataObject to each DataAware object
     * in the given collection
     * @param dataAwares a collection of DataAware objects.
     * @param dataObject new data object to set to the DataAware objects in the given collection.
     * @param updateUI if true, calls updateUI() on each DataAware object.
     */public static void setDataObject(Collection dataAwares, Object dataObject, boolean updateUI) {
        for (Iterator i = dataAwares.iterator(); i.hasNext();)
             ((DataAware) i.next()).setDataObject(dataObject, updateUI);
    }
    
    /**
     * Value objects read and write a value from and
     * to an object. Typically using reflection and JavaBeans properties 
     * or directly using memeber reflection API.
     * DataAware delegates the handling of the DataObject
     * to a Value object.
     * 2 implementations currently exist: PropertyValue,
     * using JavaBeans properties reflection, and DataAwareFields classes
     * which implement different memeber types.
     */
    public interface Value {
        /**
         * gets a value from the given object.
         * @param target the object to get the value from.
         * @return the value from the given object.
         */
        public Object get(Object target);
        /**
         * sets a value to the given object.
         * @param value the value to set to the object.
         * @param target the object to set the value to.
         */
        public void set(Object value, Object target);
        /**
         * checks if this Value object can handle
         * the given object type as a target.
         * @param type the type of a target to check
         * @return true if the given class is acceptible for
         * the Value object. False if not.
         */
        public boolean isAssignable(Class type);
    }
    
    /**
     * implementation of Value, handling JavaBeans properties through
     * reflection.
     * This Object gets and sets a value a specific
     * (JavaBean-style) property on a given object.
     * @author rp143992
     */
    public static class PropertyValue implements Value {
        /**
         * the get method of the JavaBean-style property
         */
        private Method getMethod;
        /**
         * the set method of the JavaBean-style property
         */
        private Method setMethod;

        /**
         * creates a PropertyValue for the property with
         * the given name, of the given JavaBean object.
         * @param propertyName the property to access. Must be a Cup letter (e.g. PropertyNames.PROPERTY_NAME for getName() and setName("..."). )
         * @param propertyOwner the object which "own" or "contains" the property.
         */
        public PropertyValue(String propertyName, Object propertyOwner) {
            getMethod = createGetMethod(propertyName, propertyOwner);
            setMethod = createSetMethod(propertyName, propertyOwner, getMethod.getReturnType());
        }
        
        /**
         * called from the constructor, and creates a get method reflection object
         * for the given property and object.
         * @param propName the property name0
         * @param obj the object which contains the property.
         * @return the get method reflection object.
         */
        private static Class[] EMPTY_ARRAY = new Class[0];

        protected Method createGetMethod(String propName, Object obj)
        {
            Method m = null;
            try
            { //try to get a "get" method.

                m = obj.getClass().getMethod("get" + propName, EMPTY_ARRAY);
            }
            catch (NoSuchMethodException ex1)
            {
                throw new IllegalArgumentException("get" + propName + "() method does not exist on " + obj.getClass().getName());
            }
            return m;
        }
        
        /* (non-Javadoc)
         * @see com.sun.star.wizards.ui.event.DataAware.Value#get(java.lang.Object)
         */
        public Object get(Object target) {
            try {
                return getMethod.invoke(target, EMPTY_ARRAY);
            } catch (IllegalAccessException ex1) {
                ex1.printStackTrace();
            } catch (InvocationTargetException ex2) {
                ex2.printStackTrace();
            } catch (NullPointerException npe) {
                if (getMethod.getReturnType().equals(String.class))
                    return PropertyNames.EMPTY_STRING;
                if (getMethod.getReturnType().equals(Short.class))
                    return new Short((short) 0);
                if (getMethod.getReturnType().equals(Integer.class))
                    return 0;
                if (getMethod.getReturnType().equals(short[].class))
                    return new short[0];
            }
            return null;
        
        }

        protected Method createSetMethod(String propName, Object obj, Class paramClass) {
            Method m = null;
            try {
                m = obj.getClass().getMethod("set" + propName, new Class[] { paramClass });
            } catch (NoSuchMethodException ex1) {
                throw new IllegalArgumentException("set" + propName + "(" + getMethod.getReturnType().getName() + ") method does not exist on " + obj.getClass().getName());
            }
            return m;
        }

        /* (non-Javadoc)
         * @see com.sun.star.wizards.ui.event.DataAware.Value#set(java.lang.Object, java.lang.Object)
         */
        public void set(Object value, Object target) {
            try {
                setMethod.invoke(target, value);
            } catch (IllegalAccessException ex1) {
                ex1.printStackTrace();
            } catch (InvocationTargetException ex2) {
                ex2.printStackTrace();
            }
        }

        /* (non-Javadoc)
         * @see com.sun.star.wizards.ui.event.DataAware.Value#isAssignable(java.lang.Class)
         */
        public boolean isAssignable(Class type) {
            return getMethod.getDeclaringClass().isAssignableFrom(type) &&
                setMethod.getDeclaringClass().isAssignableFrom(type);
        }
    }
}
