using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

// ボタンの子のImageやTextもボタン押下時の色に同期
[RequireComponent(typeof(Button))]
public class SyncButtonPressedColor : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerEnterHandler, IPointerExitHandler {

	[SerializeField]
	private float fadeDuration = 0.1f;

    private List<Graphic> syncGraphics = new List<Graphic>();
    private Dictionary<Graphic, Color> graphic2DefaultColorMap;
    private bool isPressed;

	private Button button;
	private List<Coroutine> coroutineList = new List<Coroutine>();


    void Awake(){
		this.button = GetComponent<Button>();
        this.graphic2DefaultColorMap = new Dictionary<Graphic, Color>();
        this.isPressed = false;

		transform.FindAllChildrensComponent<Graphic>(graphic => syncGraphics.Add(graphic));
        foreach (var graphic in syncGraphics){
            this.graphic2DefaultColorMap.Add(graphic, graphic.color);
        }
    }

    public void OnPointerDown(PointerEventData eventData){
        // 押下時の色を同期
        var pressedColor = button.colors.pressedColor;

        this.isPressed = true;
		ChangeColor(this.syncGraphics, pressedColor);
    }

    public void OnPointerUp(PointerEventData eventData){
        // 押下終了時の色を同期
        this.isPressed = false;
		ToDefaultColor(this.syncGraphics);
    }

    public void OnPointerEnter(PointerEventData eventData){
        // 押下中にポインターが重なった時の色を同期
        if (!this.isPressed) return;
        var pressedColor = button.colors.pressedColor;
		ChangeColor(this.syncGraphics, pressedColor);
    }

    public void OnPointerExit(PointerEventData eventData){
        // 押下中にポインターが外れた時の色を同期
        if (!this.isPressed) return;
		ToDefaultColor(this.syncGraphics);
    }

	private void ChangeColor(List<Graphic> graphics, Color syncedColor){
		if(coroutineList.Count > 0){
			coroutineList.ForEach(coroutine => StopCoroutine(coroutine));
			coroutineList.Clear();
		}
		graphics.ForEach(graphic => {
			Color fromColor = graphic.color;
			Color targetColor = fromColor * syncedColor;
			var coroutine = this.CallLerpSmooth(fadeDuration, t => {
				graphic.color = Color.Lerp(fromColor, targetColor, t);
			});
			coroutineList.Add(coroutine);
		});
		this.CallWaitForSeconds(fadeDuration, coroutineList.Clear);
	}
	private void ToDefaultColor(List<Graphic> graphics){
		if(coroutineList.Count > 0){
			coroutineList.ForEach(coroutine => StopCoroutine(coroutine));
			coroutineList.Clear();
		}
		graphics.ForEach(graphic => {
			Color fromColor = graphic.color;
			Color targetColor = this.graphic2DefaultColorMap[graphic];
			var coroutine = this.CallLerpSmooth(fadeDuration, t => {
				graphic.color = Color.Lerp(fromColor, targetColor, t);
			});
			coroutineList.Add(coroutine);
		});
		this.CallWaitForSeconds(fadeDuration, coroutineList.Clear);
	}
}
