/*
 * Copyright (c) 2006-2008 MiniMe. Code released under The MIT/X Window System
 * License. Full license text can be found in license.txt
 */
package minime;

import java.util.*;

import javax.microedition.lcdui.*;

/**
 * The Drawable composite, it can contain more than one Drawable instance.
 * 
 * @author yishu
 * 
 */
public class Composite extends Drawable
{
    // The vector to contain drawables
    protected Vector drawables;

    static final Logger LOG = Logger.getLogger("minime.Composite");

    /**
     * Constructs an empty Composite instance
     * 
     */
    public Composite()
    {
        this.drawables = new Vector();
    }

    /**
     * Renders the Drawables in composite one by one.The last added drawable
     * will be drawed in the end.
     * 
     * @param gc
     *            the Graphics object to be used for rendering the Drawable
     */
    public void renderImpl(Graphics gc)
    {
        Drawable drawable;
        for (Enumeration e = drawables.elements(); e.hasMoreElements();)
        {
            drawable = (Drawable) e.nextElement();
            drawable.render(gc);
        }
    }

    /**
     * Adds a drawable into Composite vector.
     * 
     * @param drawable
     *            the Drawable instance.
     */
    public void addDrawable(Drawable drawable)
    {
        // LOG.debug("Add Drawable:" + drawable);
        drawables.addElement(drawable);
    }

    /**
     * Sets the drawable at the specified index in this composite to be the
     * specified drawable. The previous drawable at that position is discarded.
     * 
     * The index must be a value greater than or equal to 0 and less than the
     * current size of the vector.
     * 
     * @param drawable
     *            what the drawable is to be set to.
     * @param index
     *            the specified index.
     * @throws IndexOutOfBoundsException
     *             if the index was invalid.
     */
    public void setDrawableAt(Drawable drawable, int index) throws IndexOutOfBoundsException
    {
        if (index < 0 || index >= drawables.size())
            throw new IndexOutOfBoundsException();

        drawables.setElementAt(drawable, index);
    }

    /**
     * Inserts the specified drawable as a component in this composite at the
     * specified index.Each drawable in this composite with an index greater or
     * equal to the specified index is shifted upward to have an index one
     * greater than the value it had previously.
     * 
     * The index must be a value greater than or equal to 0 and less than or
     * equal to the current size of the composite.
     * 
     * @param drawable
     *            the drawable to insert.
     * @param index
     *            where to insert the new drawable.
     * @throws IndexOutOfBoundsException
     *             if the index was invalid.
     */
    public void insertDrawable(Drawable drawable, int index) throws IndexOutOfBoundsException
    {
        if (index < 0 || index > drawableSize())
            throw new IndexOutOfBoundsException();

        drawables.insertElementAt(drawable, index);
    }

    /**
     * Removes the drawable from the Composite.
     * 
     * @param drawable
     *            the Drawable instance.
     */
    public void removeDrawable(Drawable drawable)
    {
        // LOG.debug("Remove drawable:" + drawable);
        drawables.removeElement(drawable);
    }

    /**
     * Deletes the drawable at the specified index. Each drawable in this
     * composite with an index greater or equal to the specified index is
     * shifted downward to have an index one smaller than the value it had
     * previously.
     * 
     * The index must be a value greater than or equal to 0 and less than the
     * current size of the vector.
     * 
     * @param index
     *            the index of the drawable to remove.
     * @throws IndexOutOfBoundsException
     *             if the index was invalid.
     */
    public void removeDrawable(int index) throws IndexOutOfBoundsException
    {
        if (index < 0 || index >= drawableSize())
            throw new IndexOutOfBoundsException();

        drawables.removeElementAt(index);
    }

    /**
     * Returns the drawable at the specified index.
     * 
     * @param elementIndex
     *            an index into this Composite vector.
     * @return the drawable at the specified index.
     * @throws IndexOutOfBoundsException
     *             if the elementIndex was invalid.
     */
    public Drawable drawableAt(int elementIndex) throws IndexOutOfBoundsException
    {
        if (elementIndex < 0 || elementIndex >= drawableSize())
            throw new IndexOutOfBoundsException();
        
        Drawable drawable = (Drawable) drawables.elementAt(elementIndex);
        return drawable;
    }

    /**
     * Returns the number of drawbles in composite.
     * 
     * @return the number of drawbles in composite.
     */
    public int drawableSize()
    {
        return drawables.size();
    }

    /**
     * Removes all drawables in composite.
     * 
     */
    public void removeAll()
    {
        drawables.removeAllElements();
    }
    
    public boolean drawablesInitialized()
    {
    	return (drawables.size() != 0);
    }

}
