/*
 * @(#)FigureSelection.java 5.1
 *
 */

package CH.ifa.draw.framework;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Enumeration;
import java.util.Vector;

import de.renew.draw.storables.ontology.Figure;
import de.renew.util.ObjectInputStreamUsingBottomLoader;


/**
 * FigureSelection enables to transfer the selected figures
 * to a clipboard.<p>
 * Will soon be converted to the JDK 1.1 Transferable interface.
 *
 * @see CH.ifa.draw.util.Clipboard
 */
public class FigureSelection implements de.renew.draw.ui.ontology.FigureSelection {
    /**
     * The Logger logs Events that could be interesting for the Figure Selector.
     */
    public static final org.apache.log4j.Logger LOGGER =
        org.apache.log4j.Logger.getLogger(FigureSelection.class);

    /**
     * The type identifier of the selection.
     * @deprecated This field is currently not used and will be removed in a later version.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    public final static String TYPE = "CH.ifa.draw.Figures";

    /** Flattened figures, ready to be resurrected */
    private final byte[] _data;

    /**
     * Constructs the Figure selection for the vector of figures.
     * @param figures figures to be put in the vector
     */
    public FigureSelection(Vector<Figure> figures) {
        _data = writeData(figures);
    }

    /**
     * Constructs an object of Figureselection from the given figure enumeration.
     * @param figures enumerated figures
     */
    public FigureSelection(Enumeration<Figure> figures) {
        Vector<Figure> vector = new Vector<>();
        while (figures.hasMoreElements()) {
            vector.addElement(figures.nextElement());
        }
        _data = writeData(vector);
    }

    private byte[] writeData(Vector<Figure> vector) {
        // a FigureSelection is represented as a flattened ByteStream
        // of figures.
        ByteArrayOutputStream output = new ByteArrayOutputStream(200);
        try {
            ObjectOutputStream writer = new ObjectOutputStream(output);
            writer.writeInt(vector.size());
            Enumeration<Figure> figures = vector.elements();
            while (figures.hasMoreElements()) {
                Figure figure = figures.nextElement();
                writer.writeObject(figure);
            }
            writer.close();
        } catch (IOException e) {
            LOGGER.error("Figure serialization failed: " + e + "\n");
        }
        return output.toByteArray();
    }

    /**
     * Gets the type of the selection.
     * @return type of selection
     * @deprecated This method is currently not used and will be removed in a later version.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    public String getType() {
        return TYPE;
    }

    /**
     * Gets the data of the selection. The result is returned
     * as a Vector of Figures.
     *
     * @param type type of the selection
     * @return a copy of the figure selection.
     * @deprecated This method is currently not used and will be removed in a later version.
     */
    @Deprecated(since = "5.0", forRemoval = true)
    public Vector<Figure> getData(String type) {
        if (type.equals(TYPE)) {
            return getData();
        }
        return null;
    }

    @Override
    public Vector<Figure> getData() {
        InputStream input = new ByteArrayInputStream(_data);
        Vector<Figure> result = new Vector<>(10);
        try {
            ObjectInputStream reader = new ObjectInputStreamUsingBottomLoader(input);
            int numRead = 0;
            int count = reader.readInt();
            while (numRead < count) {
                Figure newFigure = (Figure) reader.readObject();
                result.addElement(newFigure);
                numRead++;
            }
            reader.close();
        } catch (IOException | ClassNotFoundException e) {
            LOGGER.error("Figure deserialization failed: " + e);
        }
        return result;
    }
}