using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using System;

public abstract class TextWithCaptionSpeedParent : Text {

    public UnityEvent onEndChangingCaption;
    public float intervalForCharacterDisplay = 0.05f;
    private bool isChangingCaption;
    public bool IsChangingCaption{
        get{ return isChangingCaption; }
    }
    private float timeUntilDisplay = 0.0f;
    public float TimeUnitlDisplay{
        get{ return timeUntilDisplay; }
    }
    protected string currentText = string.Empty;
    protected float timeElapsed = 1;
    protected int lastUpdateCharacter = -1;
    protected int textLength;

    void Update(){
        if(isChangingCaption){
            int displayCharacterCount = (int)(Mathf.Clamp01((Time.realtimeSinceStartup - timeElapsed) / timeUntilDisplay) * textLength);
            if(displayCharacterCount != lastUpdateCharacter){
                UpdateText(currentText, displayCharacterCount);
                lastUpdateCharacter = displayCharacterCount;
                if(displayCharacterCount == currentText.Length){
                    ImmidiateEnd();
                }
            }
        }
    }

    protected abstract void UpdateText(string currentText, int displayCharacterCount);

    public void BeginChangingCaption(string text, float intervalForCharacterDisplay){
        BeginChangingCaption(text, intervalForCharacterDisplay, ActionExtensions.EmptyAction);
    }
    public void BeginChangingCaption(string text, float intervalForCharacterDisplay, Action callback){
        this.intervalForCharacterDisplay = intervalForCharacterDisplay;
        BeginChangingCaption(text, callback);
    }
    public void BeginChangingCaption(float intervalForCharacterDisplay){
        BeginChangingCaption(intervalForCharacterDisplay, ActionExtensions.EmptyAction);
    }
    public void BeginChangingCaption(float intervalForCharacterDisplay, Action callback){
        this.intervalForCharacterDisplay = intervalForCharacterDisplay;
        BeginChangingCaption(callback);
    }
    public void BeginChangingCaption(string text){
        BeginChangingCaption(text, ActionExtensions.EmptyAction);
    }
    public void BeginChangingCaption(){
        BeginChangingCaption(text, ActionExtensions.EmptyAction);
    }
    public void BeginChangingCaption(Action callback){
        BeginChangingCaption(text, callback);
    }
    public void BeginChangingCaption(string text, Action callback){
        isChangingCaption = true;
        currentText = text;
        onEndChangingCaption.AddListener(() => callback());
        timeUntilDisplay = currentText.Length * intervalForCharacterDisplay;
        textLength = currentText.Length;
        timeElapsed = Time.realtimeSinceStartup;
        lastUpdateCharacter = -1;
    }
    
    public void ImmidiateEnd(){
        isChangingCaption = false;
        onEndChangingCaption.Invoke();
        text = currentText;
    }
}