package net.md_5.bungee.api.chat;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import net.md_5.bungee.api.ChatColor;
import java.util.ArrayList;
import java.util.List;
import lombok.ToString;
@Setter
@ToString(exclude = "parent")
@NoArgsConstructor
public abstract class BaseComponent
{
@Setter(AccessLevel.NONE)
BaseComponent parent;
/**
* The color of this component and any child components (unless overridden)
*/
private ChatColor color;
/**
* Whether this component and any child components (unless overridden) is
* bold
*/
private Boolean bold;
/**
* Whether this component and any child components (unless overridden) is
* italic
*/
private Boolean italic;
/**
* Whether this component and any child components (unless overridden) is
* underlined
*/
private Boolean underlined;
/**
* Whether this component and any child components (unless overridden) is
* strikethrough
*/
private Boolean strikethrough;
/**
* Whether this component and any child components (unless overridden) is
* obfuscated
*/
private Boolean obfuscated;
/**
* The text to insert into the chat when this component (and child
* components) are clicked while pressing the shift key
*/
@Getter
private String insertion;
/**
* Appended components that inherit this component's formatting and events
*/
@Getter
private List<BaseComponent> extra;
/**
* The action to preform when this component (and child components) are
* clicked
*/
@Getter
private ClickEvent clickEvent;
/**
* The action to preform when this component (and child components) are
* hovered over
*/
@Getter
private HoverEvent hoverEvent;
BaseComponent(BaseComponent old)
{
setColor( old.getColorRaw() );
setBold( old.isBoldRaw() );
setItalic( old.isItalicRaw() );
setUnderlined( old.isUnderlinedRaw() );
setStrikethrough( old.isStrikethroughRaw() );
setObfuscated( old.isObfuscatedRaw() );
setInsertion( old.getInsertion() );
setClickEvent( old.getClickEvent() );
setHoverEvent( old.getHoverEvent() );
if ( old.getExtra() != null )
{
for ( BaseComponent component : old.getExtra() )
{
addExtra( component.duplicate() );
}
}
}
/**
* Clones the BaseComponent and returns the clone.
*
* @return The duplicate of this BaseComponent
*/
public abstract BaseComponent duplicate();
/**
* Converts the components to a string that uses the old formatting codes
* ({@link net.md_5.bungee.api.ChatColor#COLOR_CHAR}
*
* @param components the components to convert
* @return the string in the old format
*/
public static String toLegacyText(BaseComponent... components)
{
StringBuilder builder = new StringBuilder();
for ( BaseComponent msg : components )
{
builder.append( msg.toLegacyText() );
}
return builder.toString();
}
/**
* Converts the components into a string without any formatting
*
* @param components the components to convert
* @return the string as plain text
*/
public static String toPlainText(BaseComponent... components)
{
StringBuilder builder = new StringBuilder();
for ( BaseComponent msg : components )
{
builder.append( msg.toPlainText() );
}
return builder.toString();
}
/**
* Returns the color of this component. This uses the parent's color if this
* component doesn't have one. {@link net.md_5.bungee.api.ChatColor#WHITE}
* is returned if no color is found.
*
* @return the color of this component
*/
public ChatColor getColor()
{
if ( color == null )
{
if ( parent == null )
{
return ChatColor.WHITE;
}
return parent.getColor();
}
return color;
}
/**
* Returns the color of this component without checking the parents color.
* May return null
*
* @return the color of this component
*/
public ChatColor getColorRaw()
{
return color;
}
/**
* Returns whether this component is bold. This uses the parent's setting if
* this component hasn't been set. false is returned if none of the parent
* chain has been set.
*
* @return whether the component is bold
*/
public boolean isBold()
{
if ( bold == null )
{
return parent != null && parent.isBold();
}
return bold;
}
/**
* Returns whether this component is bold without checking the parents
* setting. May return null
*
* @return whether the component is bold
*/
public Boolean isBoldRaw()
{
return bold;
}
/**
* Returns whether this component is italic. This uses the parent's setting
* if this component hasn't been set. false is returned if none of the
* parent chain has been set.
*
* @return whether the component is italic
*/
public boolean isItalic()
{
if ( italic == null )
{
return parent != null && parent.isItalic();
}
return italic;
}
/**
* Returns whether this component is italic without checking the parents
* setting. May return null
*
* @return whether the component is italic
*/
public Boolean isItalicRaw()
{
return italic;
}
/**
* Returns whether this component is underlined. This uses the parent's
* setting if this component hasn't been set. false is returned if none of
* the parent chain has been set.
*
* @return whether the component is underlined
*/
public boolean isUnderlined()
{
if ( underlined == null )
{
return parent != null && parent.isUnderlined();
}
return underlined;
}
/**
* Returns whether this component is underlined without checking the parents
* setting. May return null
*
* @return whether the component is underlined
*/
public Boolean isUnderlinedRaw()
{
return underlined;
}
/**
* Returns whether this component is strikethrough. This uses the parent's
* setting if this component hasn't been set. false is returned if none of
* the parent chain has been set.
*
* @return whether the component is strikethrough
*/
public boolean isStrikethrough()
{
if ( strikethrough == null )
{
return parent != null && parent.isStrikethrough();
}
return strikethrough;
}
/**
* Returns whether this component is strikethrough without checking the
* parents setting. May return null
*
* @return whether the component is strikethrough
*/
public Boolean isStrikethroughRaw()
{
return strikethrough;
}
/**
* Returns whether this component is obfuscated. This uses the parent's
* setting if this component hasn't been set. false is returned if none of
* the parent chain has been set.
*
* @return whether the component is obfuscated
*/
public boolean isObfuscated()
{
if ( obfuscated == null )
{
return parent != null && parent.isObfuscated();
}
return obfuscated;
}
/**
* Returns whether this component is obfuscated without checking the parents
* setting. May return null
*
* @return whether the component is obfuscated
*/
public Boolean isObfuscatedRaw()
{
return obfuscated;
}
public void setExtra(List<BaseComponent> components)
{
for ( BaseComponent component : components )
{
component.parent = this;
}
extra = components;
}
/**
* Appends a text element to the component. The text will inherit this
* component's formatting
*
* @param text the text to append
*/
public void addExtra(String text)
{
addExtra( new TextComponent( text ) );
}
/**
* Appends a component to the component. The text will inherit this
* component's formatting
*
* @param component the component to append
*/
public void addExtra(BaseComponent component)
{
if ( extra == null )
{
extra = new ArrayList<BaseComponent>();
}
component.parent = this;
extra.add( component );
}
/**
* Returns whether the component has any formatting or events applied to it
*
* @return Whether any formatting or events are applied
*/
public boolean hasFormatting()
{
return color != null || bold != null
|| italic != null || underlined != null
|| strikethrough != null || obfuscated != null
|| hoverEvent != null || clickEvent != null;
}
/**
* Converts the component into a string without any formatting
*
* @return the string as plain text
*/
public String toPlainText()
{
StringBuilder builder = new StringBuilder();
toPlainText( builder );
return builder.toString();
}
void toPlainText(StringBuilder builder)
{
if ( extra != null )
{
for ( BaseComponent e : extra )
{
e.toPlainText( builder );
}
}
}
/**
* Converts the component to a string that uses the old formatting codes
* ({@link net.md_5.bungee.api.ChatColor#COLOR_CHAR}
*
* @return the string in the old format
*/
public String toLegacyText()
{
StringBuilder builder = new StringBuilder();
toLegacyText( builder );
return builder.toString();
}
void toLegacyText(StringBuilder builder)
{
if ( extra != null )
{
for ( BaseComponent e : extra )
{
e.toLegacyText( builder );
}
}
}
}