using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using RecrownedAthenaeum.Render;
using RecrownedAthenaeum.SpecialTypes;
using RecrownedAthenaeum.UI.SkinSystem;
using RecrownedAthenaeum.UI.SkinSystem.Definitions;

namespace RecrownedAthenaeum.UI.Modular.Modules.Interactive
{
    /// <summary>
    /// Button that holds a string.
    /// </summary>
    public class TextButton : Button
    {
        /// <summary>
        /// The text that is used to display the string.
        /// </summary>
        public readonly Text text;

        /// <summary>
        /// The color the font should be rendered in.
        /// </summary>
        public Color FontColor { get { return text.color; } set { text.color = value; } }

        /// <summary>
        /// Constructs text button with the positions represented by <see cref="ISpecialDrawable"/>
        /// </summary>
        /// <param name="text">The string representing the text to be displayed.</param>
        /// <param name="font">The font to be used to display the text.</param>
        /// <param name="down">What to draw as button is pushed down.</param>
        /// <param name="up">What to draw as button is not pushed.</param>
        /// <param name="disabled">What to draw as button is disabled.</param>
        /// <param name="selected">What to draw as button is selected.</param>
        public TextButton(string text, SpriteFont font, ISpecialDrawable down, ISpecialDrawable up, ISpecialDrawable disabled = null, ISpecialDrawable selected = null) : base(down, up, disabled, selected)
        {
            this.text = new Text(font, text);
            this.text.autoScale = true;
            this.text.centered = true;
        }

        /// <summary>
        /// Constructs a text button using a skin and definition.
        /// </summary>
        /// <param name="text">The text to display.</param>
        /// <param name="font">The font to be used.</param>
        /// <param name="skin">The skin to use.</param>
        /// <param name="definitionName">Name of the definition for this type in the skin given.</param>
        public TextButton(string text, SpriteFont font, ISkin skin, string definitionName = null) : base(skin, skin.ObtainDefinition<TextButtonSkinDefinition>(definitionName))
        {
            TextButtonSkinDefinition skinDefinition = skin.ObtainDefinition<TextButtonSkinDefinition>(definitionName);
            this.text = new Text(font, text);
            this.text.autoScale = true;
            this.text.centered = true;
            FontColor = skin.GetColor(skinDefinition.fontColor);
        }

        /// <summary>
        /// Creates a text button with a given definition.
        /// </summary>
        /// <param name="text">The text to be displayed on this button.</param>
        /// <param name="font">The font to use for this button.</param>
        /// <param name="skin">The skin the definition is from.</param>
        /// <param name="skinDefinition">The definition to use.</param>
        public TextButton(string text, SpriteFont font, ISkin skin, TextButtonSkinDefinition skinDefinition) : 
            this(text, 
                font, 
                skin.GetTextureAtlasRegion(skinDefinition.downRegion, true),
                skin.GetTextureAtlasRegion(skinDefinition.upRegion, true), 
                skin.GetTextureAtlasRegion(skinDefinition.disabledRegion), 
                skin.GetTextureAtlasRegion(skinDefinition.selectedRegion))
        { }

        /// <summary>
        /// Updates the text button.
        /// </summary>
        /// <param name="gameTime">Snapshot of information about time for game.</param>
        public override void Update(GameTime gameTime)
        {
            text.SetPositionAndDimensions(Boundaries);
            text.Update(gameTime);
            base.Update(gameTime);
        }

        /// <summary>
        /// Called whenever game wants to render this button.
        /// </summary>
        /// <param name="batch">Batch to use. Batch should already be started.</param>
        public override void Draw(ConsistentSpriteBatch batch)
        {
            base.Draw(batch);
            text.Draw(batch);
        }
    }
}
