// © 2017 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
package com.ibm.icu.impl.number;

import java.text.Format.Field;
import java.util.Arrays;

import com.ibm.icu.impl.FormattedStringBuilder;

/**
 * An implementation of {@link Modifier} that allows for multiple types of fields in the same modifier.
 * Constructed based on the contents of two {@link FormattedStringBuilder} instances (one for the prefix,
 * one for the suffix).
 */
public class ConstantMultiFieldModifier implements Modifier {

    // NOTE: In Java, these are stored as array pointers. In C++, the FormattedStringBuilder is stored by
    // value and is treated internally as immutable.
    protected final char[] prefixChars;
    protected final char[] suffixChars;
    protected final Object[] prefixFields;
    protected final Object[] suffixFields;
    private final boolean overwrite;
    private final boolean strong;

    // Parameters: used for number range formatting
    private final Parameters parameters;

    public ConstantMultiFieldModifier(
            FormattedStringBuilder prefix,
            FormattedStringBuilder suffix,
            boolean overwrite,
            boolean strong) {
        this(prefix, suffix, overwrite, strong, null);
    }

    public ConstantMultiFieldModifier(
            FormattedStringBuilder prefix,
            FormattedStringBuilder suffix,
            boolean overwrite,
            boolean strong,
            Parameters parameters) {
        prefixChars = prefix.toCharArray();
        suffixChars = suffix.toCharArray();
        prefixFields = prefix.toFieldArray();
        suffixFields = suffix.toFieldArray();
        this.overwrite = overwrite;
        this.strong = strong;
        this.parameters = parameters;
    }

    @Override
    public int apply(FormattedStringBuilder output, int leftIndex, int rightIndex) {
        int length = output.insert(leftIndex, prefixChars, prefixFields);
        if (overwrite) {
            length += output.splice(leftIndex + length, rightIndex + length, "", 0, 0, null);
        }
        length += output.insert(rightIndex + length, suffixChars, suffixFields);
        return length;
    }

    @Override
    public int getPrefixLength() {
        return prefixChars.length;
    }

    @Override
    public int getCodePointCount() {
        return Character.codePointCount(prefixChars, 0, prefixChars.length)
                + Character.codePointCount(suffixChars, 0, suffixChars.length);
    }

    @Override
    public boolean isStrong() {
        return strong;
    }

    @Override
    public boolean containsField(Field field) {
        for (int i = 0; i < prefixFields.length; i++) {
            if (prefixFields[i] == field) {
                return true;
            }
        }
        for (int i = 0; i < suffixFields.length; i++) {
            if (suffixFields[i] == field) {
                return true;
            }
        }
        return false;
    }

    @Override
    public Parameters getParameters() {
        return parameters;
    }

    @Override
    public boolean semanticallyEquivalent(Modifier other) {
        if (!(other instanceof ConstantMultiFieldModifier)) {
            return false;
        }
        ConstantMultiFieldModifier _other = (ConstantMultiFieldModifier) other;
        if (parameters != null && _other.parameters != null && parameters.obj == _other.parameters.obj) {
            return true;
        }
        return Arrays.equals(prefixChars, _other.prefixChars) && Arrays.equals(prefixFields, _other.prefixFields)
                && Arrays.equals(suffixChars, _other.suffixChars) && Arrays.equals(suffixFields, _other.suffixFields)
                && overwrite == _other.overwrite && strong == _other.strong;
    }

    @Override
    public String toString() {
        FormattedStringBuilder temp = new FormattedStringBuilder();
        apply(temp, 0, 0);
        int prefixLength = getPrefixLength();
        return String.format("<ConstantMultiFieldModifier prefix:'%s' suffix:'%s'>",
                temp.subSequence(0, prefixLength),
                temp.subSequence(prefixLength, temp.length()));
    }
}
