/*
 * 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 freemarker.template.TemplateException;
import freemarker.template.TemplateModel;
import freemarker.template._TemplateAPI;

/**
 * A class that represents a Range between two integers.
 */
final class Range extends Expression {

    static final int END_INCLUSIVE = 0; 
    static final int END_EXCLUSIVE = 1; 
    static final int END_UNBOUND = 2; 
    static final int END_SIZE_LIMITED = 3; 
    
    final Expression lho;
    final Expression rho;
    final int endType;

    Range(Expression lho, Expression rho, int endType) {
        this.lho = lho;
        this.rho = rho;
        this.endType = endType;
    }
    
    int getEndType() {
        return endType;
    }

    @Override
    TemplateModel _eval(Environment env) throws TemplateException {
        final int begin = lho.evalToNumber(env).intValue();
        if (endType != END_UNBOUND) {
            final int lhoValue = rho.evalToNumber(env).intValue();
            return new BoundedRangeModel(
                    begin, endType != END_SIZE_LIMITED ? lhoValue : begin + lhoValue,
                    endType == END_INCLUSIVE, endType == END_SIZE_LIMITED); 
        } else {
            return _TemplateAPI.getTemplateLanguageVersionAsInt(this) >= _TemplateAPI.VERSION_INT_2_3_21
                    ? (RangeModel) new ListableRightUnboundedRangeModel(begin)
                    : (RangeModel) new NonListableRightUnboundedRangeModel(begin);
        }
    }
    
    // Surely this way we can tell that it won't be a boolean without evaluating the range, but why was this important?
    @Override
    boolean evalToBoolean(Environment env) throws TemplateException {
        throw new NonBooleanException(this, new BoundedRangeModel(0, 0, false, false), env);
    }

    @Override
    public String getCanonicalForm() {
        String rhs = rho != null ? rho.getCanonicalForm() : "";
        return lho.getCanonicalForm() + getNodeTypeSymbol() + rhs;
    }
    
    @Override
    String getNodeTypeSymbol() {
        switch (endType) {
        case END_EXCLUSIVE: return "..<";
        case END_INCLUSIVE: return "..";
        case END_UNBOUND: return "..";
        case END_SIZE_LIMITED: return "..*";
        default: throw new BugException(endType);
        }
    }
    
    @Override
    boolean isLiteral() {
        boolean rightIsLiteral = rho == null || rho.isLiteral();
        return constantValue != null || (lho.isLiteral() && rightIsLiteral);
    }
    
    @Override
    protected Expression deepCloneWithIdentifierReplaced_inner(
            String replacedIdentifier, Expression replacement, ReplacemenetState replacementState) {
        return new Range(
                lho.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState),
                rho.deepCloneWithIdentifierReplaced(replacedIdentifier, replacement, replacementState),
                endType);
    }
    
    @Override
    int getParameterCount() {
        return 2;
    }

    @Override
    Object getParameterValue(int idx) {
        switch (idx) {
        case 0: return lho;
        case 1: return rho;
        default: throw new IndexOutOfBoundsException();
        }
    }

    @Override
    ParameterRole getParameterRole(int idx) {
        return ParameterRole.forBinaryOperatorOperand(idx);
    }
    
}
