001package ball.game.scrabble;
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 static java.util.Objects.requireNonNull;
022
023/**
024 * Scrabble {@link Board} square.
025 *
026 * {@bean.info}
027 *
028 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball}
029 */
030public class SQ {
031    private final int letterPremium;
032    private final int wordPremium;
033    private Tile tile = null;
034    private char letter = ' ';
035    private String string = null;
036
037    /**
038     * Sole public constructor.
039     */
040    public SQ() { this("."); }
041
042    /**
043     * Protected constructor to specify the {@link SQ} representation.
044     *
045     * @param   string          The {@link String} representation of this
046     *                          {@link SQ} if no {@link Tile} has been
047     *                          played.
048     */
049    protected SQ(String string) {
050        if (getClass().getAnnotation(LetterPremium.class) != null) {
051            letterPremium = getClass().getAnnotation(LetterPremium.class).value();
052        } else {
053            letterPremium = 0;
054        }
055
056        if (getClass().getAnnotation(WordPremium.class) != null) {
057            wordPremium = getClass().getAnnotation(WordPremium.class).value();
058        } else {
059            wordPremium = 0;
060        }
061
062        this.string = requireNonNull(string, "string");
063    }
064
065    public boolean isPremium() {
066        return (letterPremium > 1 || wordPremium > 1);
067    }
068
069    /**
070     * @return  The letter premium value.
071     *
072     * @see LetterPremium
073     */
074    public int getLetterPremium() { return letterPremium; }
075
076    /**
077     * @return  The word premium value.
078     *
079     * @see WordPremium
080     */
081    public int getWordPremium() { return wordPremium; }
082
083    public boolean isEmpty() { return (tile == null); }
084
085    public void play(Tile tile) { play(tile, tile.getLetter()); }
086
087    public void play(Tile tile, char letter) {
088        if (isEmpty()) {
089            this.tile = tile;
090            this.letter = letter;
091        } else {
092            throw new IllegalStateException();
093        }
094
095        if (tile.isBlank()) {
096            string = String.valueOf(letter).toLowerCase();
097        } else {
098            string = tile.toString().toUpperCase();
099        }
100    }
101
102    @Override
103    public String toString() { return string; }
104}