/*
 * 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 freemarker.core;

import java.util.List;

import freemarker.core.IteratorBlock.IterationContext;
import freemarker.template.SimpleNumber;
import freemarker.template.SimpleScalar;
import freemarker.template.TemplateBooleanModel;
import freemarker.template.TemplateException;
import freemarker.template.TemplateMethodModelEx;
import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelException;


class BuiltInsForLoopVariables {
    
    static class indexBI extends BuiltInForLoopVariable {

        @Override
        TemplateModel calculateResult(IterationContext iterCtx, Environment env) throws TemplateException {
            return new SimpleNumber(iterCtx.getIndex());
        }
        
    }
    
    static class counterBI extends BuiltInForLoopVariable {

        @Override
        TemplateModel calculateResult(IterationContext iterCtx, Environment env) throws TemplateException {
            return new SimpleNumber(iterCtx.getIndex() + 1);
        }
        
    }

    static abstract class BooleanBuiltInForLoopVariable extends BuiltInForLoopVariable {

        @Override
        final TemplateModel calculateResult(IterationContext iterCtx, Environment env) throws TemplateException {
            return calculateBooleanResult(iterCtx, env) ? TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE;
        }

        protected abstract boolean calculateBooleanResult(IterationContext iterCtx, Environment env);
        
    }
    
    static class has_nextBI extends BooleanBuiltInForLoopVariable {

        @Override
        protected boolean calculateBooleanResult(IterationContext iterCtx, Environment env) {
            return iterCtx.hasNext();
        }

    }

    static class is_lastBI extends BooleanBuiltInForLoopVariable {

        @Override
        protected boolean calculateBooleanResult(IterationContext iterCtx, Environment env) {
            return !iterCtx.hasNext();
        }
        
    }

    static class is_firstBI extends BooleanBuiltInForLoopVariable {

        @Override
        protected boolean calculateBooleanResult(IterationContext iterCtx, Environment env) {
            return iterCtx.getIndex() == 0;
        }
        
    }

    static class is_odd_itemBI extends BooleanBuiltInForLoopVariable {

        @Override
        protected boolean calculateBooleanResult(IterationContext iterCtx, Environment env) {
            return iterCtx.getIndex() % 2 == 0;
        }
        
    }

    static class is_even_itemBI extends BooleanBuiltInForLoopVariable {

        @Override
        protected boolean calculateBooleanResult(IterationContext iterCtx, Environment env) {
            return iterCtx.getIndex() % 2 != 0;
        }
        
    }
    
    static class item_parityBI extends BuiltInForLoopVariable {
        
        private static final SimpleScalar ODD = new SimpleScalar("odd");
        private static final SimpleScalar EVEN = new SimpleScalar("even");

        @Override
        TemplateModel calculateResult(IterationContext iterCtx, Environment env) throws TemplateException {
            return iterCtx.getIndex() % 2 == 0 ? ODD: EVEN;
        }
        
    }

    static class item_parity_capBI extends BuiltInForLoopVariable {
        
        private static final SimpleScalar ODD = new SimpleScalar("Odd");
        private static final SimpleScalar EVEN = new SimpleScalar("Even");

        @Override
        TemplateModel calculateResult(IterationContext iterCtx, Environment env) throws TemplateException {
            return iterCtx.getIndex() % 2 == 0 ? ODD: EVEN;
        }
        
    }

    static class item_cycleBI extends BuiltInForLoopVariable {

        private class BIMethod implements TemplateMethodModelEx {
            
            private final IterationContext iterCtx;
    
            private BIMethod(IterationContext iterCtx) {
                this.iterCtx = iterCtx;
            }
    
            @Override
            public Object exec(List args) throws TemplateModelException {
                checkMethodArgCount(args, 1, Integer.MAX_VALUE);
                return args.get(iterCtx.getIndex() % args.size());
            }
        }
        
        @Override
        TemplateModel calculateResult(IterationContext iterCtx, Environment env) throws TemplateException {
            return new BIMethod(iterCtx);
        }
        
    }
    
}
