/**
 *  Licensed under GPL. For more information, see
 *    http://jaxodraw.sourceforge.net/license.html
 *  or the LICENSE file in the jaxodraw distribution.
 */
package net.sf.jaxodraw;

import java.awt.Component;
import java.awt.Container;

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import junit.framework.Assert;

import net.sf.jaxodraw.object.JaxoObject;


/** Static utility methods. */
public final class JaxoTestUtils {
    /** Private constructor. */
    private JaxoTestUtils() {
        // empty
    }

    /** Tests serialization.
     * @param object The object to test.
     */
    public static void checkSerializedEquality(final JaxoObject object) {
        JaxoObject object2 = (JaxoObject) serializeAndRecover(object);
        Assert.assertNotNull(object2);
        Assert.assertTrue(object2.isCopy(object));
        object2 = (JaxoObject) serializeXMLAndRecover(object);
        Assert.assertNotNull(object2);
        Assert.assertTrue(object2.isCopy(object));
    }

    /**
     * Serializes and deserializes an object using java.io.ObjectIn/OutputStream.
     *
     * @param o The object to test.
     *          This must implement the Serializable interface.
     * @return The object after being serialized and deserialized,
     * or null, if there was a problem.
     */
    public static Object serializeAndRecover(final Object o) {
        Object result = null;

        ObjectInputStream in = null;
        ObjectOutputStream out = null;

        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            out = new ObjectOutputStream(bos);
            out.writeObject(o);

            byte[] buf = bos.toByteArray();

            // deserialize it
            in = new ObjectInputStream(new ByteArrayInputStream(buf));
            result = in.readObject();
            in.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        } finally {
            try {
                out.close();
                in.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        return result;
    }

    /**
     * Serializes and deserializes an object using java.beans.XMLEn/Decoder.
     *
     * @param o The serializable object to test.
     * @return The object after being serialized and deserialized.
     */
    public static Object serializeXMLAndRecover(final Object o) {
        Object result = null;

        // serialize the Object
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        XMLEncoder enc = new XMLEncoder(bos);
        enc.writeObject(o);
        enc.close();

        byte[] buf = bos.toByteArray();

        // deserialize it
        XMLDecoder dec = new XMLDecoder(new ByteArrayInputStream(buf));
        result = dec.readObject();
        dec.close();

        return result;
    }

    /** Makes a copy and checks equality.
     * @param object The object to test.
     */
    public static void checkCopyEquality(JaxoObject object) {
        JaxoObject object2 = object.copy();
        Assert.assertTrue(object2.isCopy(object));
    }

    /** Checks that two JacoObject are not equal.
     @param object1 The object1 to compare.
     @param object2 The object2 to compare.
     */
    public static void checkCopyInEquality(JaxoObject object1,
        JaxoObject object2) {
        Assert.assertFalse(object2.isCopy(object1));
    }

    /** Looks for sub-components of a given name.
     * @param parent The parent to search in.
     * @param name The name of the component to look for.
     * @return The component of given name, or null if no component
     * of given name is found in parent.
     */
    public static Component getChildNamed(Component parent, String name) {

        if (name.equals(parent.getName())) {
            return parent;
        }

        if (parent instanceof Container) {
           Component[] children = ((Container) parent).getComponents();

            for (int i = 0; i < children.length; ++i) {
                Component child = getChildNamed(children[i], name);
                if (child != null) {
                    return child;
                }
            }
        }

        return null;
     }

}
