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


package org.apache.jasper.tagplugins.jstl.core;

import org.apache.jasper.compiler.tagplugin.*;

public final class ForEach implements TagPlugin {
    
    private boolean hasVar, hasBegin, hasEnd, hasStep;
    
    public void doTag(TagPluginContext ctxt) {
        
        String index = null;
        
        boolean hasVarStatus = ctxt.isAttributeSpecified("varStatus");
        if (hasVarStatus) {
            ctxt.dontUseTagPlugin();
            return;
        }
        
        hasVar = ctxt.isAttributeSpecified("var");
        hasBegin = ctxt.isAttributeSpecified("begin");
        hasEnd = ctxt.isAttributeSpecified("end");
        hasStep = ctxt.isAttributeSpecified("step");
        
        boolean hasItems = ctxt.isAttributeSpecified("items");
        if (hasItems) {
            doCollection(ctxt);
            return;
        }
        
        // We must have a begin and end attributes
        index = ctxt.getTemporaryVariableName();
        ctxt.generateJavaSource("for (int " + index + " = ");
        ctxt.generateAttribute("begin");
        ctxt.generateJavaSource("; " + index + " <= ");
        ctxt.generateAttribute("end");
        if (hasStep) {
            ctxt.generateJavaSource("; " + index + "+=");
            ctxt.generateAttribute("step");
            ctxt.generateJavaSource(") {");
        }
        else {
            ctxt.generateJavaSource("; " + index + "++) {");
        }
        
        // If var is specified and the body contains an EL, then sycn
        // the var attribute
        if (hasVar /* && ctxt.hasEL() */) {
            ctxt.generateJavaSource("_jspx_page_context.setAttribute(");
            ctxt.generateAttribute("var");
            ctxt.generateJavaSource(", String.valueOf(" + index + "));");
        }
        ctxt.generateBody();
        ctxt.generateJavaSource("}");
    }
    
    /**
     * Generate codes for Collections
     * The pseudo code is:
     */
    private void doCollection(TagPluginContext ctxt) {
        
        ctxt.generateImport("java.util.*");
        generateIterators(ctxt);
        
        String itemsV = ctxt.getTemporaryVariableName();
        ctxt.generateJavaSource("Object " + itemsV + "= ");
        ctxt.generateAttribute("items");
        ctxt.generateJavaSource(";");
        
        String indexV=null, beginV=null, endV=null, stepV=null;
        if (hasBegin) {
            beginV = ctxt.getTemporaryVariableName();
            ctxt.generateJavaSource("int " + beginV + " = ");
            ctxt.generateAttribute("begin");
            ctxt.generateJavaSource(";");
        }
        if (hasEnd) {
            indexV = ctxt.getTemporaryVariableName();
            ctxt.generateJavaSource("int " + indexV + " = 0;");
            endV = ctxt.getTemporaryVariableName();
            ctxt.generateJavaSource("int " + endV + " = ");
            ctxt.generateAttribute("end");
            ctxt.generateJavaSource(";");
        }
        if (hasStep) {
            stepV = ctxt.getTemporaryVariableName();
            ctxt.generateJavaSource("int " + stepV + " = ");
            ctxt.generateAttribute("step");
            ctxt.generateJavaSource(";");
        }
        
        String iterV = ctxt.getTemporaryVariableName();
        ctxt.generateJavaSource("Iterator " + iterV + " = null;");
        // Object[]
        ctxt.generateJavaSource("if (" + itemsV + " instanceof Object[])");
        ctxt.generateJavaSource(iterV + "=toIterator((Object[])" + itemsV + ");");
        // boolean[]
        ctxt.generateJavaSource("else if (" + itemsV + " instanceof boolean[])");
        ctxt.generateJavaSource(iterV + "=toIterator((boolean[])" + itemsV + ");");
        // byte[]
        ctxt.generateJavaSource("else if (" + itemsV + " instanceof byte[])");
        ctxt.generateJavaSource(iterV + "=toIterator((byte[])" + itemsV + ");");
        // char[]
        ctxt.generateJavaSource("else if (" + itemsV + " instanceof char[])");
        ctxt.generateJavaSource(iterV + "=toIterator((char[])" + itemsV + ");");
        // short[]
        ctxt.generateJavaSource("else if (" + itemsV + " instanceof short[])");
        ctxt.generateJavaSource(iterV + "=toIterator((short[])" + itemsV + ");");
        // int[]
        ctxt.generateJavaSource("else if (" + itemsV + " instanceof int[])");
        ctxt.generateJavaSource(iterV + "=toIterator((int[])" + itemsV + ");");
        // long[]
        ctxt.generateJavaSource("else if (" + itemsV + " instanceof long[])");
        ctxt.generateJavaSource(iterV + "=toIterator((long[])" + itemsV + ");");
        // float[]
        ctxt.generateJavaSource("else if (" + itemsV + " instanceof float[])");
        ctxt.generateJavaSource(iterV + "=toIterator((float[])" + itemsV + ");");
        // double[]
        ctxt.generateJavaSource("else if (" + itemsV + " instanceof double[])");
        ctxt.generateJavaSource(iterV + "=toIterator((double[])" + itemsV + ");");
        
        // Collection
        ctxt.generateJavaSource("else if (" + itemsV + " instanceof Collection)");
        ctxt.generateJavaSource(iterV + "=((Collection)" + itemsV + ").iterator();");
        
        // Iterator
        ctxt.generateJavaSource("else if (" + itemsV + " instanceof Iterator)");
        ctxt.generateJavaSource(iterV + "=(Iterator)" + itemsV + ";");
        
        // Enumeration
        ctxt.generateJavaSource("else if (" + itemsV + " instanceof Enumeration)");
        ctxt.generateJavaSource(iterV + "=toIterator((Enumeration)" + itemsV + ");");
        
        // Map
        ctxt.generateJavaSource("else if (" + itemsV + " instanceof Map)");
        ctxt.generateJavaSource(iterV + "=((Map)" + itemsV + ").entrySet().iterator();");
        
        if (hasBegin) {
            String tV = ctxt.getTemporaryVariableName();
            ctxt.generateJavaSource("for (int " + tV + "=" + beginV + ";" +
                    tV + ">0 && " + iterV + ".hasNext(); " +
                    tV + "--)");
            ctxt.generateJavaSource(iterV + ".next();");
        }
        
        ctxt.generateJavaSource("while (" + iterV + ".hasNext()){");
        if (hasVar) {
            ctxt.generateJavaSource("_jspx_page_context.setAttribute(");
            ctxt.generateAttribute("var");
            ctxt.generateJavaSource(", " + iterV + ".next());");
        }
        
        ctxt.generateBody();
        
        if (hasStep) {
            String tV = ctxt.getTemporaryVariableName();
            ctxt.generateJavaSource("for (int " + tV + "=" + stepV + "-1;" +
                    tV + ">0 && " + iterV + ".hasNext(); " +
                    tV + "--)");
            ctxt.generateJavaSource(iterV + ".next();");
        }
        if (hasEnd) {
            if (hasStep) {
                ctxt.generateJavaSource(indexV + "+=" + stepV + ";");
            }
            else {
                ctxt.generateJavaSource(indexV + "++;");
            }
            if (hasBegin) {
                ctxt.generateJavaSource("if(" + beginV + "+" + indexV +
                        ">"+ endV + ")");
            }
            else {
                ctxt.generateJavaSource("if(" + indexV + ">" + endV + ")");
            }
            ctxt.generateJavaSource("break;");
        }
        ctxt.generateJavaSource("}");	// while
    }
    
    /**
     * Generate iterators for data types supported in items
     */
    private void generateIterators(TagPluginContext ctxt) {
        
        // Object[]
        ctxt.generateDeclaration("ObjectArrayIterator", 
                "private Iterator toIterator(final Object[] a){\n" +
                "  return (new Iterator() {\n" +
                "    int index=0;\n" +
                "    public boolean hasNext() {\n" +
                "      return index < a.length;}\n" +
                "    public Object next() {\n" +
                "      return a[index++];}\n" +
                "    public void remove() {}\n" +
                "  });\n" +
                "}"
        );
        
        // boolean[]
        ctxt.generateDeclaration("booleanArrayIterator", 
                "private Iterator toIterator(final boolean[] a){\n" +
                "  return (new Iterator() {\n" +
                "    int index=0;\n" +
                "    public boolean hasNext() {\n" +
                "      return index < a.length;}\n" +
                "    public Object next() {\n" +
                "      return new Boolean(a[index++]);}\n" +
                "    public void remove() {}\n" +
                "  });\n" +
                "}"
        );
        
        // byte[]
        ctxt.generateDeclaration("byteArrayIterator", 
                "private Iterator toIterator(final byte[] a){\n" +
                "  return (new Iterator() {\n" +
                "    int index=0;\n" +
                "    public boolean hasNext() {\n" +
                "      return index < a.length;}\n" +
                "    public Object next() {\n" +
                "      return new Byte(a[index++]);}\n" +
                "    public void remove() {}\n" +
                "  });\n" +
                "}"
        );
        
        // char[]
        ctxt.generateDeclaration("charArrayIterator", 
                "private Iterator toIterator(final char[] a){\n" +
                "  return (new Iterator() {\n" +
                "    int index=0;\n" +
                "    public boolean hasNext() {\n" +
                "      return index < a.length;}\n" +
                "    public Object next() {\n" +
                "      return new Character(a[index++]);}\n" +
                "    public void remove() {}\n" +
                "  });\n" +
                "}"
        );
        
        // short[]
        ctxt.generateDeclaration("shortArrayIterator", 
                "private Iterator toIterator(final short[] a){\n" +
                "  return (new Iterator() {\n" +
                "    int index=0;\n" +
                "    public boolean hasNext() {\n" +
                "      return index < a.length;}\n" +
                "    public Object next() {\n" +
                "      return new Short(a[index++]);}\n" +
                "    public void remove() {}\n" +
                "  });\n" +
                "}"
        );
        
        // int[]
        ctxt.generateDeclaration("intArrayIterator", 
                "private Iterator toIterator(final int[] a){\n" +
                "  return (new Iterator() {\n" +
                "    int index=0;\n" +
                "    public boolean hasNext() {\n" +
                "      return index < a.length;}\n" +
                "    public Object next() {\n" +
                "      return new Integer(a[index++]);}\n" +
                "    public void remove() {}\n" +
                "  });\n" +
                "}"
        );
        
        // long[]
        ctxt.generateDeclaration("longArrayIterator", 
                "private Iterator toIterator(final long[] a){\n" +
                "  return (new Iterator() {\n" +
                "    int index=0;\n" +
                "    public boolean hasNext() {\n" +
                "      return index < a.length;}\n" +
                "    public Object next() {\n" +
                "      return new Long(a[index++]);}\n" +
                "    public void remove() {}\n" +
                "  });\n" +
                "}"
        );
        
        // float[]
        ctxt.generateDeclaration("floatArrayIterator",
                "private Iterator toIterator(final float[] a){\n" +
                "  return (new Iterator() {\n" +
                "    int index=0;\n" +
                "    public boolean hasNext() {\n" +
                "      return index < a.length;}\n" +
                "    public Object next() {\n" +
                "      return new Float(a[index++]);}\n" +
                "    public void remove() {}\n" +
                "  });\n" +
                "}"
        );
        
        // double[]
        ctxt.generateDeclaration("doubleArrayIterator",
                "private Iterator toIterator(final double[] a){\n" +
                "  return (new Iterator() {\n" +
                "    int index=0;\n" +
                "    public boolean hasNext() {\n" +
                "      return index < a.length;}\n" +
                "    public Object next() {\n" +
                "      return new Double(a[index++]);}\n" +
                "    public void remove() {}\n" +
                "  });\n" +
                "}"
        );
        
        // Enumeration
        ctxt.generateDeclaration("enumIterator",
                "private Iterator toIterator(final Enumeration e){\n" +
                "  return (new Iterator() {\n" +
                "    public boolean hasNext() {\n" +
                "      return e.hasMoreElements();}\n" +
                "    public Object next() {\n" +
                "      return e.nextElement();}\n" +
                "    public void remove() {}\n" +
                "  });\n" +
                "}"
        );
        
    }
}
