001package ball.game.crossword;
002/*-
003 * ##########################################################################
004 * Game Applications and Utilities
005 * %%
006 * Copyright (C) 2010 - 2022 Allen D. Ball
007 * %%
008 * Licensed under the Apache License, Version 2.0 (the "License");
009 * you may not use this file except in compliance with the License.
010 * You may obtain a copy of the License at
011 *
012 *      http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing, software
015 * distributed under the License is distributed on an "AS IS" BASIS,
016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017 * See the License for the specific language governing permissions and
018 * limitations under the License.
019 * ##########################################################################
020 */
021import ball.util.CoordinateMap;
022import java.util.Map;
023import java.util.TreeMap;
024import java.util.stream.Stream;
025
026import static java.util.Collections.unmodifiableMap;
027
028/**
029 * Crossword clue {@link Direction}.
030 *
031 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball}
032 */
033public enum Direction {
034    ACROSS, DOWN;
035
036    private static final Map<String,Direction> MAP;
037
038    static {
039        TreeMap<String,Direction> map = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
040
041        Stream.of(values())
042            .forEach(t -> map.put(t.name().substring(0, 1), t));
043
044        MAP = unmodifiableMap(map);
045    }
046
047    /**
048     * Static method to parse a {@link String} consistent with
049     * {@link #name()} and {@link #toString()} to a {@link Direction}.
050     *
051     * @param   string          The {@link String} to parse.
052     *
053     * @return  The {@link Direction}.
054     */
055    public static Direction parse(String string) {
056        var direction = MAP.get(string);
057
058        if (direction == null) {
059            direction = Enum.valueOf(Direction.class, string);
060        }
061
062        return direction;
063    }
064
065    /**
066     * Static method to analyze {@link CoordinateMap} to determine a
067     * {@link Direction}.
068     *
069     * @param   map             The {@link CoordinateMap} to analyze.
070     *
071     * @return  The {@link Direction}.
072     *
073     * @throws  IllegalArgumentException
074     *                          If both {@link CoordinateMap#getRowCount()}
075     *                          and {@link CoordinateMap#getColumnCount()}
076     *                          are not equal to {@code 1}.
077     */
078    public static Direction of(CoordinateMap<?> map) {
079        Direction direction = null;
080
081        if (map.getRowCount() > 1) {
082            direction = Direction.DOWN;
083        } else if (map.getColumnCount() > 1) {
084            direction = Direction.ACROSS;
085        } else {
086            throw new IllegalArgumentException();
087        }
088
089        return direction;
090    }
091}