/*
 * This file is part of NucleusFramework for Bukkit, licensed under the MIT License (MIT).
 *
 * Copyright (c) JCThePants (www.jcwhatever.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.jcwhatever.nucleus.utils.potions;

import com.jcwhatever.nucleus.internal.NucLang;
import com.jcwhatever.nucleus.managed.language.Localizable;
import com.jcwhatever.nucleus.utils.PreCon;
import com.jcwhatever.nucleus.utils.ThreadSingletons;
import org.bukkit.potion.Potion;
import org.bukkit.potion.PotionType;

/**
 * Stores potion display names.
 */
public class PotionNames {

    private PotionNames() {}

    @Localizable static final String _WATER = "Water Bottle";
    @Localizable static final String _REGEN = "Potion of Regeneration";
    @Localizable static final String _SPEED = "Potion of Swiftness";
    @Localizable static final String _FIRE_RESISTANCE = "Potion of Fire Resistance";
    @Localizable static final String _POISON = "Potion of Poison";
    @Localizable static final String _INSTANT_HEAL ="Potion of Healing";
    @Localizable static final String _NIGHT_VISION = "Potion of Night Vision";
    @Localizable static final String _WEAKNESS = "Potion of Weakness";
    @Localizable static final String _STRENGTH = "Potion of Strength";
    @Localizable static final String _SLOWNESS = "Potion of Slowness";
    @Localizable static final String _JUMP = "Potion of Leaping";
    @Localizable static final String _INSTANT_DAMAGE = "Potion of Harming";
    @Localizable static final String _WATER_BREATHING = "Potion of Water Breathing";
    @Localizable static final String _INVISIBILITY = "Potion of Invisibility";

    @Localizable static final String _SPLASH = "Splash";
    @Localizable static final String _LEVEL2 = "II";
    @Localizable static final String _EXTENDED_DURATION = "(ext)";

    private static final ThreadSingletons<StringBuilder> BUFFERS = new ThreadSingletons<>(
            new ThreadSingletons.ISingletonFactory<StringBuilder>() {
                @Override
                public StringBuilder create(Thread thread) {
                    return new StringBuilder(45);
                }
            });

    /**
     * Get a simple potion name.
     *
     * @param potion  The potion.
     */
    public static String getSimple(Potion potion) {
        PreCon.notNull(potion);

        return getSimple(potion.getType());
    }

    /**
     * Get a simple potion name.
     *
     * @param type  The potion type.
     */
    public static String getSimple(PotionType type) {
        PreCon.notNull(type);

        StringBuilder buffer = buffer();
        appendSimple(buffer, type);
        return buffer.toString();
    }

    /**
     * Get a full potion name including characteristics.
     *
     * @param potion  The potion.
     */
    public static String getFull(Potion potion) {
        PreCon.notNull(potion);

        PotionType type = potion.getType();
        StringBuilder buffer = buffer();

        if (potion.isSplash()) {
            append(buffer, _SPLASH);
            buffer.append(' ');
        }

        appendSimple(buffer, type);

        if (potion.getLevel() == 2) {
            buffer.append(' ');
            append(buffer, _LEVEL2);
        }

        if (potion.hasExtendedDuration()) {
            buffer.append(' ');
            append(buffer, _EXTENDED_DURATION);
        }

        return buffer.toString();
    }

    private static void appendSimple(StringBuilder buffer, PotionType type) {
        switch (type) {
            case WATER:
                append(buffer, _WATER);
                break;
            case REGEN:
                append(buffer, _REGEN);
                break;
            case SPEED:
                append(buffer, _SPEED);
                break;
            case FIRE_RESISTANCE:
                append(buffer, _FIRE_RESISTANCE);
                break;
            case POISON:
                append(buffer, _POISON);
                break;
            case INSTANT_HEAL:
                append(buffer, _INSTANT_HEAL);
                break;
            case NIGHT_VISION:
                append(buffer, _NIGHT_VISION);
                break;
            case WEAKNESS:
                append(buffer, _WEAKNESS);
                break;
            case STRENGTH:
                append(buffer, _STRENGTH);
                break;
            case SLOWNESS:
                append(buffer, _SLOWNESS);
                break;
            case JUMP:
                append(buffer, _JUMP);
                break;
            case INSTANT_DAMAGE:
                append(buffer, _INSTANT_DAMAGE);
                break;
            case WATER_BREATHING:
                append(buffer, _WATER_BREATHING);
                break;
            case INVISIBILITY:
                append(buffer, _INVISIBILITY);
                break;
        }
    }

    private static void append(StringBuilder buffer, String text) {
        buffer.append(NucLang.get(text));
    }

    private static StringBuilder buffer() {
        StringBuilder buffer = BUFFERS.get();
        buffer.setLength(0);
        return buffer;
    }
}

@@ -1641,16 +1641,211 @@
 s() %7B%7D%0A%0A
+    @Localizable static final String _AWKWARD = %22Awkward Potion%22;%0A    @Localizable static final String _THICK = %22Thick Potion%22;%0A    @Localizable static final String _MUNDANE = %22Mundane Potion%22;%0A%0A
     @Loc
@@ -4133,24 +4133,416 @@
 .getType();%0A
+        if (type == null) %7B%0A%0A            switch (potion.getNameId()) %7B%0A                case 16:%0A                    return NucLang.get(_AWKWARD);%0A                case 32:%0A                    return NucLang.get(_THICK);%0A                case 64:%0A                    return NucLang.get(_MUNDANE);%0A                default:%0A                    throw new AssertionError();%0A            %7D%0A        %7D%0A%0A
         Stri

fix null reference for base potions in PotionNames