/**
 * FlexChat - Licensed under the MIT License (MIT)
 *
 * Copyright (c) Stealth2800 <http://stealthyone.com/>
 * Copyright (c) contributors <https://github.com/FlexSeries>
 *
 * 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 me.st28.flexseries.flexchat.api.channel;

import me.st28.flexseries.flexchat.api.chatter.Chatter;
import me.st28.flexseries.flexchat.api.chatter.ChatterPlayer;
import me.st28.flexseries.flexchat.api.format.ChatFormat;
import me.st28.flexseries.flexchat.api.format.ReferencedChatFormat;
import me.st28.flexseries.flexchat.backend.channel.ChannelManagerImpl;
import me.st28.flexseries.flexlib.log.LogHelper;
import me.st28.flexseries.flexlib.permission.PermissionHelper;
import org.apache.commons.lang.Validate;
import org.bukkit.ChatColor;
import org.bukkit.configuration.ConfigurationSection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public abstract class Channel {

    private String name;
    private String fileName;
    private String tag;

    private ChatColor color;
    private int radius;

    private String logFormat;

    private final Map<String, ChatFormat> formats = new LinkedHashMap<>();

    public Channel(String name) {
        this(name, null);
    }

    public Channel(String name, String fileName) {
        Validate.notNull(name, "Name cannot be null.");
        this.name = name;
        this.fileName = fileName;

        color = ChatColor.WHITE;
        radius = 0;
    }

    public void reload(ChannelManagerImpl channelManager, ConfigurationSection config) {
        name = config.getString("name");
        Validate.notNull(name, "Name cannot be null.");

        tag = config.getString("tag");
        if (tag != null && tag.equals("")) {
            tag = null;
        }

        color = ChatColor.valueOf(config.getString("color", "WHITE").toUpperCase());

        logFormat = config.getString("log format", null);
        if (logFormat != null && logFormat.equals("")) {
            logFormat = null;
        }

        radius = config.getInt("chat radius", 0);
        if (radius < 0) {
            radius = 0;
        }

        formats.clear();
        ConfigurationSection formatSec = config.getConfigurationSection("formats");
        if (formatSec != null) {
            for (String group : formatSec.getKeys(false)) {
                ChatFormat format;
                try {
                    format = ChatFormat.getChatFormat(channelManager, formatSec, group);
                } catch (Exception ex) {
                    LogHelper.warning(channelManager, "Unable to load chat format '" + group + "'", ex);
                    continue;
                }
                formats.put(group, format);
            }
        }

        if (!formats.containsKey("default")) {
            formats.put("default",  new ReferencedChatFormat(null));
        }
    }

    public void save() {}

    public String getName() {
        return name;
    }

    public String getFileName() {
        return fileName == null ? name : fileName;
    }

    public String getTag() {
        return tag;
    }

    public ChatColor getColor() {
        return color;
    }

    public int getRadius() {
        return radius;
    }

    public Collection<ChatFormat> getChatFormats() {
        return Collections.unmodifiableCollection(formats.values());
    }

    public ChatFormat getChatFormat(String group) {
        return formats.get(group == null ? "default" : group.toLowerCase());
    }

    public ChatFormat getChatFormat(Chatter chatter) {
        if (!(chatter instanceof ChatterPlayer)) {
            return getChatFormat((String) null);
        }
        return formats.get(PermissionHelper.getTopGroup(((ChatterPlayer) chatter).getPlayer(), new ArrayList<>(formats.keySet()), "default"));
    }

    /**
     * @return All of the {@link ChannelInstance}s this Channel has.
     */
    public abstract Collection<ChannelInstance> getInstances();

    /**
     * @return A {@link ChannelInstance} with the given name.
     */
    public ChannelInstance getInstance(String name) {
        Validate.notNull(name, "Name cannot be null.");
        for (ChannelInstance instance : getInstances()) {
            if (instance.getDisplayName() != null && (instance.getDisplayName().equalsIgnoreCase(name) || instance.getLabel().equalsIgnoreCase("label"))) {
                return instance;
            }
        }
        return null;
    }

    /**
     * @return The {@link ChannelInstance}s a particular {@link Chatter} belongs in.
     */
    public abstract List<ChannelInstance> getInstances(Chatter chatter);

}
@@ -5139,17 +5139,97 @@
 en name.
+ Null input returns the default instance%0A     *         (assuming there is one).
 %0A
-
      */%0A
@@ -5286,64 +5286,8 @@
 ) %7B%0A
-        Validate.notNull(name, %22Name cannot be null.%22);%0A
     
@@ -5354,16 +5354,92 @@
       if
+ ((name == null && instance.getDisplayName() == null)%0A                    %7C%7C
  (instan
@@ -5563,18 +5563,28 @@
 ase(
-%22label%22)))
+name))))%0A           
  %7B%0A 

Allow direct retrieval of default channel instance.