/*
 * ProGuard -- shrinking, optimization, obfuscation, and preverification
 *             of Java bytecode.
 *
 * Copyright (c) 2002-2009 Eric Lafortune (eric@graphics.cornell.edu)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package proguard.evaluation.value;

import proguard.classfile.ClassConstants;

/**
 * This class represents a partially evaluated instruction offset. It can
 * contain 0 or more specific instruction offsets.
 *
 * @author Eric Lafortune
 */
public class InstructionOffsetValue extends Category1Value
{
    public static final InstructionOffsetValue EMPTY_VALUE = new InstructionOffsetValue();


    private int[] values;


    private InstructionOffsetValue()
    {
    }


    public InstructionOffsetValue(int value)
    {
        this.values = new int[] { value };
    }


    public InstructionOffsetValue(int[] values)
    {
        this.values = values;
    }


    public int instructionOffsetCount()
    {
        return values == null ? 0 : values.length;
    }


    public int instructionOffset(int index)
    {
        return values[index];
    }


    /**
     * Returns whether the given value is present in this list of instruction
     * offsets.
     */
    public boolean contains(int value)
    {
        if (values != null)
        {
            for (int index = 0; index < values.length; index++)
            {
                if (values[index] == value)
                {
                    return true;
                }
            }
        }

        return false;
    }


    /**
     * Returns the minimum value from this list of instruction offsets.
     * Returns <code>Integer.MAX_VALUE</code> if the list is empty.
     */
    public int minimumValue()
    {
        int minimumValue = Integer.MAX_VALUE;

        if (values != null)
        {
            for (int index = 0; index < values.length; index++)
            {
                int value = values[index];

                if (minimumValue > value)
                {
                    minimumValue = value;
                }
            }
        }

        return minimumValue;
    }


    /**
     * Returns the maximum value from this list of instruction offsets.
     * Returns <code>Integer.MIN_VALUE</code> if the list is empty.
     */
    public int maximumValue()
    {
        int maximumValue = Integer.MIN_VALUE;

        if (values != null)
        {
            for (int index = 0; index < values.length; index++)
            {
                int value = values[index];

                if (maximumValue < value)
                {
                    maximumValue = value;
                }
            }
        }

        return maximumValue;
    }


    /**
     * Returns the generalization of this InstructionOffsetValue and the given
     * other InstructionOffsetValue. The values of the other InstructionOffsetValue
     * are guaranteed to remain at the end of the list, in the same order.
     */
    public final Value generalize(InstructionOffsetValue other)
    {
        // If the values array of either is null, return the other one.
        if (this.values == null)
        {
            return other;
        }

        if (other.values == null)
        {
            return this;
        }

        // Compute the length of the union of the arrays.
        int newLength = this.values.length;
        for (int index = 0; index < other.values.length; index++)
        {
            if (!this.contains(other.values[index]))
            {
                newLength++;
            }
        }

        // If the length of the union array is equal to the length of the values
        // array of either, return it.
        if (newLength == other.values.length)
        {
            return other;
        }

        // The ordering of the this array may not be right, so we can't just
        // use it.
        //if (newLength == this.values.length)
        //{
        //    return this;
        //}

        // Create the union array.
        int[] newValues = new int[newLength];

        int newIndex = 0;

        // Copy the values that are different from the other array.
        for (int index = 0; index < this.values.length; index++)
        {
            if (!other.contains(this.values[index]))
            {
                newValues[newIndex++] = this.values[index];
            }
        }

        // Copy the values from the other array.
        for (int index = 0; index < other.values.length; index++)
        {
            newValues[newIndex++] = other.values[index];
        }

        return new InstructionOffsetValue(newValues);
    }


    // Implementations for Value.

    public final InstructionOffsetValue instructionOffsetValue()
    {
        return this;
    }

    public boolean isSpecific()
    {
        return true;
    }

    public boolean isParticular()
    {
        return true;
    }

    public final Value generalize(Value other)
    {
        return this.generalize(other.instructionOffsetValue());
    }

    public final int computationalType()
    {
        return TYPE_INSTRUCTION_OFFSET;
    }

    public final String internalType()
    {
        return String.valueOf(ClassConstants.INTERNAL_TYPE_INT);
    }


    // Implementations for Object.

    public boolean equals(Object object)
    {
        if (object == null ||
            this.getClass() != object.getClass())
        {
            return false;
        }

        InstructionOffsetValue other = (InstructionOffsetValue)object;
        if (this.values == other.values)
        {
            return true;
        }

        if (this.values  == null ||
            other.values == null ||
            this.values.length != other.values.length)
        {
            return false;
        }

        for (int index = 0; index < other.values.length; index++)
        {
            if (!this.contains(other.values[index]))
            {
                return false;
            }
        }

        return true;
    }


    public int hashCode()
    {
        int hashCode = this.getClass().hashCode();

        if (values != null)
        {
            for (int index = 0; index < values.length; index++)
            {
                hashCode ^= values[index];
            }
        }

        return hashCode;
    }


    public String toString()
    {
        StringBuffer buffer = new StringBuffer();

        if (values != null)
        {
            for (int index = 0; index < values.length; index++)
            {
                if (index > 0)
                {
                    buffer.append(',');
                }
                buffer.append(values[index]);
            }
        }

        return buffer.append(':').toString();
    }
}
