/*
 * 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.
 */

/* $Id$ */

package org.apache.fop.pdf;

import java.io.IOException;
import java.io.OutputStream;
import java.io.Writer;
import java.util.Collection;
import java.util.List;

import org.apache.commons.io.output.CountingOutputStream;

/**
 * Class representing an array object.
 */
public class PDFArray extends PDFObject {
    /**
     * List holding the values of this array
     */
    protected List values = new java.util.ArrayList();

    /**
     * Create a new, empty array object
     * @param parent the array's parent if any
     */
    public PDFArray(PDFObject parent) {
        /* generic creation of PDF object */
        super(parent);
    }

    /**
     * Create a new, empty array object with no parent.
     */
    public PDFArray() {
        this(null);
    }

    /**
     * Create an array object.
     * @param parent the array's parent if any
     * @param values the actual array wrapped by this object
     */
    public PDFArray(PDFObject parent, int[] values) {
        /* generic creation of PDF object */
        super(parent);

        for (int i = 0, c = values.length; i < c; i++) {
            this.values.add(new Integer(values[i]));
        }
    }

    /**
     * Create an array object.
     * @param parent the array's parent if any
     * @param values the actual array wrapped by this object
     */
    public PDFArray(PDFObject parent, double[] values) {
        /* generic creation of PDF object */
        super(parent);

        for (int i = 0, c = values.length; i < c; i++) {
            this.values.add(new Double(values[i]));
        }
    }

    /**
     * Create an array object.
     * @param parent the array's parent if any
     * @param values the actual values wrapped by this object
     */
    public PDFArray(PDFObject parent, Collection values) {
        /* generic creation of PDF object */
        super(parent);

        this.values.addAll(values);
    }

    /**
     * Create the array object
     * @param parent the array's parent if any
     * @param values the actual array wrapped by this object
     */
    public PDFArray(PDFObject parent, Object[] values) {
        /* generic creation of PDF object */
        super(parent);

        for (int i = 0, c = values.length; i < c; i++) {
            this.values.add(values[i]);
        }
    }

    /**
     * Indicates whether the given object exists in the array.
     * @param obj the object to look for
     * @return true if obj is contained
     */
    public boolean contains(Object obj) {
        return this.values.contains(obj);
    }

    /**
     * Returns the length of the array
     * @return the length of the array
     */
    public int length() {
        return this.values.size();
    }

    /**
     * Sets an entry at a given location.
     * @param index the index of the value to set
     * @param obj the new value
     */
    public void set(int index, Object obj) {
        this.values.set(index, obj);
    }

    /**
     * Sets an entry at a given location.
     * @param index the index of the value to set
     * @param value the new value
     */
    public void set(int index, double value) {
        this.values.set(index, new Double(value));
    }

    /**
     * Gets an entry at a given location.
     * @param index the index of the value to set
     * @return the requested value
     */
    public Object get(int index) {
        return this.values.get(index);
    }

    /**
     * Adds a new value to the array.
     * @param obj the value
     */
    public void add(Object obj) {
        if (obj instanceof PDFObject) {
            PDFObject pdfObj = (PDFObject)obj;
            if (!pdfObj.hasObjectNumber()) {
                pdfObj.setParent(this);
            }
        }
        this.values.add(obj);
    }

    /**
     * Adds a new value to the array.
     * @param value the value
     */
    public void add(double value) {
        this.values.add(new Double(value));
    }

    /** {@inheritDoc} */
    protected int output(OutputStream stream) throws IOException {
        CountingOutputStream cout = new CountingOutputStream(stream);
        Writer writer = PDFDocument.getWriterFor(cout);
        if (hasObjectNumber()) {
            writer.write(getObjectID());
        }

        writer.write('[');
        for (int i = 0; i < values.size(); i++) {
            if (i > 0) {
                writer.write(' ');
            }
            Object obj = this.values.get(i);
            formatObject(obj, cout, writer);
        }
        writer.write(']');

        if (hasObjectNumber()) {
            writer.write("\nendobj\n");
        }

        writer.flush();
        return cout.getCount();
    }

}
