/**
 *  Copyright 2011 Douglas Campos <qmx@qmx.me>
 *
 *  Licensed 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.
 */

package me.qmx.jitescript;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.ClassNode;

import java.util.ArrayList;
import java.util.List;

import static me.qmx.jitescript.CodeBlock.newCodeBlock;
import static me.qmx.jitescript.util.CodegenUtils.p;
import static me.qmx.jitescript.util.CodegenUtils.sig;

/**
 * @author qmx
 */
public class JiteClass implements Opcodes {

    public static final String[] INTERFACES = new String[]{};
    private final List<MethodDefinition> methods = new ArrayList<MethodDefinition>();
    private final List<String> interfaces = new ArrayList<String>();
    private final String className;
    private final String superClassName;

    public JiteClass(String className) {
        this(className, INTERFACES);
    }

    public JiteClass(String className, String[] interfaces) {
        this(className, p((Class) Object.class), interfaces);
    }

    public JiteClass(String className, String superClassName, String[] interfaces) {
        this.className = className;
        this.superClassName = superClassName;
        for (String anInterface : interfaces) {
            this.interfaces.add(anInterface);
        }
    }

    public void defineMethod(String methodName, int modifiers, String signature, CodeBlock methodBody) {
        this.methods.add(new MethodDefinition(methodName, modifiers, signature, methodBody));
    }

    public void defineDefaultConstructor() {
        defineMethod("<init>", ACC_PUBLIC, sig(void.class),
                newCodeBlock()
                        .aload(0)
                        .invokespecial(p(Object.class), "<init>", sig(void.class))
                        .voidreturn()
        );
    }

    public byte[] toBytes() {
        return toBytes(JDKVersion.V1_6);
    }

    public byte[] toBytes(JDKVersion version) {
        ClassNode node = new ClassNode();
        node.version = version.getVer();
        node.access = ACC_PUBLIC | ACC_SUPER;
        node.name = this.className;
        node.superName = this.superClassName;
        if (!this.interfaces.isEmpty()) {
            node.interfaces.addAll(this.interfaces);
        }

        for (MethodDefinition def : methods) {
            node.methods.add(def.getMethodNode());
        }
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
        node.accept(cw);
        return cw.toByteArray();
    }

}

@@ -1820,32 +1820,100 @@
        %7D%0A    %7D%0A%0A
+    public String getClassName() %7B%0A        return className;%0A    %7D%0A%0A
     public void 

Add getter to className