/*
 * ProGuard -- shrinking, optimization, obfuscation, and preverification
 *             of Java bytecode.
 *
 * Copyright (c) 2002-2014 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.classfile.editor;

import proguard.classfile.*;

/**
 * This class can add interfaces and class members to a given class.
 * Elements to be added must be filled out beforehand, including their
 * references to the constant pool.
 *
 * @author Eric Lafortune
 */
public class ClassEditor
{
    private static final boolean DEBUG = false;

    private ProgramClass targetClass;


    /**
     * Creates a new ClassEditor that will edit elements in the given
     * target class.
     */
    public ClassEditor(ProgramClass targetClass)
    {
        this.targetClass = targetClass;
    }


    /**
     * Adds the given interface.
     */
    public void addInterface(int interfaceConstantIndex)
    {
        int   interfacesCount = targetClass.u2interfacesCount;
        int[] interfaces      = targetClass.u2interfaces;

        // Make sure there is enough space for the new interface.
        if (interfaces.length <= interfacesCount)
        {
            targetClass.u2interfaces = new int[interfacesCount+1];
            System.arraycopy(interfaces, 0,
                             targetClass.u2interfaces, 0,
                             interfacesCount);
            interfaces = targetClass.u2interfaces;
        }

        if (DEBUG)
        {
            System.out.println(targetClass.getName()+": adding interface ["+targetClass.getClassName(interfaceConstantIndex)+"]");
        }

        // Add the interface.
        interfaces[targetClass.u2interfacesCount++] = interfaceConstantIndex;
    }

    /**
     * Removes the given interface.
     */
    public void removeInterface(int interfaceConstantIndex)
    {
        int   interfacesCount = targetClass.u2interfacesCount;
        int[] interfaces      = targetClass.u2interfaces;

        int interfaceIndex = findInterfaceIndex(interfaceConstantIndex);

        // Shift the interface entries.
        System.arraycopy(interfaces, interfaceIndex+1,
                         interfaces, interfaceIndex,
                         interfacesCount - interfaceIndex - 1);

        // Clear the last entry.
        interfaces[--targetClass.u2interfacesCount] = 0;
    }


    /**
     * Finds the index of the given interface in the target class.
     */

    private int findInterfaceIndex(int interfaceConstantIndex)
    {
        int   interfacesCount = targetClass.u2interfacesCount;
        int[] interfaces      = targetClass.u2interfaces;

        for (int index = 0; index < interfacesCount; index++)
        {
            if (interfaces[index] == interfaceConstantIndex)
            {
                return index;
            }
        }

        return interfacesCount;
    }


    /**
     * Adds the given field.
     */
    public void addField(Field field)
    {
        int     fieldsCount = targetClass.u2fieldsCount;
        Field[] fields      = targetClass.fields;

        // Make sure there is enough space for the new field.
        if (fields.length <= fieldsCount)
        {
            targetClass.fields = new ProgramField[fieldsCount+1];
            System.arraycopy(fields, 0,
                             targetClass.fields, 0,
                             fieldsCount);
            fields = targetClass.fields;
        }

        if (DEBUG)
        {
            System.out.println(targetClass.getName()+": adding field ["+field.getName(targetClass)+" "+field.getDescriptor(targetClass)+"]");
        }

        // Add the field.
        fields[targetClass.u2fieldsCount++] = field;
    }


    /**
     * Removes the given field. Note that removing a field that is still being
     * referenced can cause unpredictable effects.
     */
    public void removeField(Field field)
    {
        int     fieldsCount = targetClass.u2fieldsCount;
        Field[] fields      = targetClass.fields;

        int fieldIndex = findFieldIndex(field);

        // Shift the field entries.
        System.arraycopy(fields, fieldIndex+1,
                         fields, fieldIndex,
                         fieldsCount - fieldIndex - 1);

        // Clear the last entry.
        fields[--targetClass.u2fieldsCount] = null;
    }


    /**
     * Finds the index of the given field in the target class.
     */

    private int findFieldIndex(Field field)
    {
        int     fieldsCount = targetClass.u2fieldsCount;
        Field[] fields      = targetClass.fields;

        for (int index = 0; index < fieldsCount; index++)
        {
            if (fields[index].equals(field))
            {
                return index;
            }
        }

        return fieldsCount;
    }


    /**
     * Adds the given method.
     */
    public void addMethod(Method method)
    {
        int      methodsCount = targetClass.u2methodsCount;
        Method[] methods      = targetClass.methods;

        // Make sure there is enough space for the new method.
        if (methods.length <= methodsCount)
        {
            targetClass.methods = new ProgramMethod[methodsCount+1];
            System.arraycopy(methods, 0,
                             targetClass.methods, 0,
                             methodsCount);
            methods = targetClass.methods;
        }

        if (DEBUG)
        {
            System.out.println(targetClass.getName()+": adding method ["+method.getName(targetClass)+method.getDescriptor(targetClass)+"]");
        }

        // Add the method.
        methods[targetClass.u2methodsCount++] = method;
    }


    /**
     * Removes the given method. Note that removing a method that is still being
     * referenced can cause unpredictable effects.
     */
    public void removeMethod(Method method)
    {
        int      methodsCount = targetClass.u2methodsCount;
        Method[] methods      = targetClass.methods;

        int methodIndex = findMethodIndex(method);

        // Shift the method entries.
        System.arraycopy(methods, methodIndex+1,
                         methods, methodIndex,
                         methodsCount - methodIndex - 1);

        // Clear the last entry.
        methods[--targetClass.u2methodsCount] = null;
    }


    /**
     * Finds the index of the given method in the target class.
     */

    private int findMethodIndex(Method method)
    {
        int      methodsCount = targetClass.u2methodsCount;
        Method[] methods      = targetClass.methods;

        for (int index = 0; index < methodsCount; index++)
        {
            if (methods[index].equals(method))
            {
                return index;
            }
        }

        return methodsCount;
    }
}
