/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2023 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * 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 org.jboss.installer.core;

import java.util.HashSet;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;

/**
 * Utility class to create unique mnemonic character for buttons.
 * The mnemonic can be unique globally (e.g. navigation buttons), or locally within a single screen.
 * Each screen should use a new instance on {@code MnemonicUtils} to ensure local-uniqness. After the global elements are generated,
 * their mnemonics should be reserved by calling {@code MnemonicUtils#reserveGlobal}.
 */
public class MnemonicUtils {

    private static final Set<Character> globalReserved = new HashSet<>();

    private Set<Character> screenReserved = new HashSet<>();

    public static void reserveGlobal(Set<Character> reserved) {
        MnemonicUtils.globalReserved.addAll(reserved);
    }

    public static void resetGlobal() {
        // remove all elements
        MnemonicUtils.globalReserved.removeIf(p->true);
    }

    public Optional<Character> findMnemonic(String text) {
        return findMnemonic(text, false);
    }

    public Optional<Character> findMnemonic(String text, boolean ignoreGlobal) {
        Objects.requireNonNull(text);

        text = text.toLowerCase();
        for (int i = 0; i < text.length(); i++) {
            final char c = text.charAt(i);
            if (!screenReserved.contains(c) && (ignoreGlobal || !globalReserved.contains(c))) {
                screenReserved.add(c);
                return Optional.of(c);
            }
        }
        return Optional.empty();
    }
}
