package org.apache.velocity.tools.generic;

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

import java.util.Collection;

/**
 * Utility class for easily alternating over values in a list.
 *
 * <p><b>Example usage:</b></p>
 * <pre>
 * java...
 *      String[] myColors = new String[]{"red", "blue"};
 *      context.put("color", new Alternator(myColors));
 *      String[] myStyles = new String[]{"hip", "fly", "groovy"};
 *      // demonstrate manual alternation with this one
 *      context.put("style", new Alternator(false, myStyles));
 *
 * template...
 *      #foreach( $foo in [1..5] )
 *       $foo is $color and $style.next
 *      #end
 *
 * output...
 *      1 is red and hip
 *      2 is blue and fly
 *      3 is red and groovy
 *      4 is blue and hip
 *      5 is red and fly
 * </pre>
 *
 * @since Velocity Tools 1.2
 * @version $Id$
 */
public class Alternator
{
    private Object[] list;
    private int index = 0;
    private boolean auto = true;

    /**
     * Creates a new Alternator for the specified list.  Alternation
     * defaults to automatic.
     * @param list the elements to alternate over
     */
    public Alternator(Object... list)
    {
        this(true, list);
    }

    /**
     * Creates a new Alternator for the specified list with the specified
     * automatic shifting preference.
     *
     * @param auto See {@link #setAuto(boolean auto)}.
     * @param list The elements to alternate over
     */
    public Alternator(boolean auto, Object... list)
    {
        this.auto = auto;
        if (list.length == 1 && list[0] instanceof Collection)
        {
            this.list = ((Collection)list[0]).toArray();
        }
        else
        {
            this.list = list;
        }
    }

    /**
     * @return Whether this Alternator shifts the list index
     * automatically after a call to {@link #toString()}.
     */
    public boolean isAuto()
    {
        return auto;
    }

    /**
     * If set to true, the list index will shift automatically after a
     * call to toString().
     * @param auto flag value
     */
    public void setAuto(boolean auto)
    {
        this.auto = auto;
    }

    /**
     * Manually shifts the list index. If it reaches the end of the list,
     * it will start over again at zero.
     */
    public void shift()
    {
        index = (index + 1) % list.length;
    }

    /**
     * Returns the current item without shifting the list index.
     * @return current item
     */
    public Object getCurrent()
    {
        return list[index];
    }

    /**
     * Returns the current item, then shifts the list index.
     * @return current item
     */
    public Object getNext()
    {
        Object o = getCurrent();
        shift();
        return o;
    }

    /**
     * Returns a string representation of the current item or
     * <code>null</code> if the current item is null.  <b>If {@link
     * #auto} is true, this will shift after returning the current
     * item</b>.
     * @return string representation of the current item
     */
    public String toString()
    {
        Object o = list[index];
        if (auto)
        {
            shift();
        }
        if (o == null)
        {
            return null;
        }
        return o.toString();
    }
}
