using System;
using UnityEngine;

public static class FloatExtentions {

    static public float Epsilon = 1.192093E-07f;

    static public string ToTimeString(this float f){
        TimeSpan time = TimeSpan.FromSeconds(f);
        string result = string.Format("{0:D2}'{1:D2}\"{2:D3}", time.Minutes, time.Seconds, time.Milliseconds);
        if(time.Hours > 0){
            result = string.Format("{0:D2}:{1}", time.Hours, result);
        }
        return result;
    }
    static public string ToTimeString(this float f, string secondsStr = "", string minutesStr = "", string hoursStr = "", string daysStr = "", bool isFull = false){
        TimeSpan time = TimeSpan.FromSeconds(f);
        string result = "";
        int days = time.Days;
        int hours = time.Hours;
        int minutes = time.Minutes;
        int seconds = time.Seconds;
        if(daysStr.Length > 0){
            if(days > 0){
                result = string.Format("{0}{1}", days, daysStr);
            }
        }else{
            hours += days * 24;
        }
        if(hoursStr.Length > 0){
            if(hours > 0 || (isFull && result.Length > 0)){
                if(result.Length > 0){
                    result = string.Format("{0}{1:D2}{2}", result, hours, hoursStr);
                }else{
                    result = string.Format("{0}{1}", hours, hoursStr);
                }
            }
        }else{
            minutes += hours * 60;
        }
        if(minutesStr.Length > 0){
            if(minutes > 0 || (isFull && result.Length > 0)){
                if(result.Length > 0){
                    result = string.Format("{0}{1:D2}{2}", result, minutes, minutesStr);
                }else{
                    result = string.Format("{0}{1}", minutes, minutesStr);
                }
            }
        }else{
            seconds += minutes * 60;
        }
        if(secondsStr.Length > 0){
            if(result.Length == 0 || seconds > 0 || (isFull && result.Length > 0)){
                if(result.Length > 0){
                    result = string.Format("{0}{1:D2}{2}", result, seconds, secondsStr);
                }else{
                    result = string.Format("{0}{1}", seconds, secondsStr);
                }
            }
        }
        return result;
    }
    static public string ToTimerString(this float f){
        TimeSpan time = TimeSpan.FromSeconds(f);
        string result = string.Format("{0:D2}", time.Seconds);
        if(time.Minutes > 0 || time.Hours > 0){
            result = string.Format("{0:D2}:{1}", time.Minutes, result);
        }
        if(time.Hours > 0){
            result = string.Format("{0:D2}:{1}", time.Hours, result);
        }
        return result;
    }
    static public string ToTimerString(this float f, string secondsStr, string minutesStr, string hoursStr, string daysStr, bool isFull = true){
        TimeSpan time = TimeSpan.FromSeconds(f);
        string result = "";
        int days = time.Days;
        int hours = time.Hours;
        int minutes = time.Minutes;
        int seconds = time.Seconds;
        if(daysStr.Length > 0){
            if(days > 0){
                if(isFull){
                    result = string.Format("{0}{1}", days, daysStr);
                }else{
                    return string.Format("{0}{1}", days + 1, daysStr);
                }
            }
        }else{
            hours += days * 24;
        }
        if(hoursStr.Length > 0){
            if(hours > 0 || (isFull && result.Length > 0)){
                if(result.Length > 0){
                    result = string.Format("{0}{1:D2}{2}", result, hours, hoursStr);
                }else{
                    if(isFull){
                        result = string.Format("{0}{1}", hours, hoursStr);
                    }else{
                        return string.Format("{0}{1}", hours + 1, hoursStr);
                    }
                }
            }
        }else{
            minutes += hours * 60;
        }
        if(minutesStr.Length > 0){
            if(minutes > 0 || (isFull && result.Length > 0)){
                if(result.Length > 0){
                    result = string.Format("{0}{1:D2}{2}", result, minutes, minutesStr);
                }else{
                    if(isFull){
                        result = string.Format("{0}{1}", minutes, minutesStr);
                    }else{
                        return string.Format("{0}{1}", minutes + 1, minutesStr);
                    }
                }
            }
        }else{
            seconds += minutes * 60;
        }
        if(secondsStr.Length > 0){
            if(result.Length == 0 || seconds > 0 || (isFull && result.Length > 0)){
                if(result.Length > 0){
                    result = string.Format("{0}{1:D2}{2}", result, seconds + 1, secondsStr);
                }else{
                    result = string.Format("{0}{1}", seconds + 1, secondsStr);
                }
            }
        }
        return result;
    }

    static public string ToTimeStringJ(this float f, bool isFull = false){
        return f.ToTimeString("秒", "分", "時間", "日", isFull);
    }
    static public string ToTimerStringJ(this float f){
        return (f + 1.0f).ToTimeStringJ(true);
    }

    public static float Floor(this float f, uint i){
        if(i == 0){
            return Mathf.Floor(f);
        }else{
            return Mathf.Floor(f * Mathf.Pow(10.0f, i)) * Mathf.Pow(10.0f, -i);
        }
    }


    public static float EaseInQuadratic(this float t){
        return t * t;
    }
    public static float EaseOutQuadratic(this float t){
        return -t * (t - 2.0f);
    }
    public static float EaseInOutQuadratic(this float t){
        t *= 2.0f;
        if(t < 1.0f) return 0.5f * t * t;
        t -= 1.0f;
        return -0.5f * (t * (t - 2.0f) - 1.0f);
    }

    public static float EaseInCubic(this float t){
        return t * t * t;
    }
    public static float EaseOutCubic(this float t){
        t -= 1.0f;
        return t * t * t + 1;
    }
    public static float EaseInOutCubic(this float t){
        t *= 2.0f;
        if(t < 1.0f) return 0.5f * t * t * t;
        t -= 2.0f;
        return 0.5f * (t * t * t + 2);
    }

    public static float EaseInQuartic(this float t){
        return t * t * t * t;
    }
    public static float EaseOutQuartic(this float t){
        t -= 1.0f;
        return -(t * t * t * t - 1);
    }
    public static float EaseInOutQuartic(this float t){
        t *= 2.0f;
        if(t < 1.0f) return 0.5f * t * t * t * t;
        t -= 2.0f;
        return -0.5f * (t * t * t * t - 2);
    }

    public static float EaseInQuintic(this float t){
        return t * t * t * t * t;
    }
    public static float EaseOutQuintic(this float t){
        t -= 1.0f;
        return t * t * t * t * t + 1;
    }
    public static float EaseInOutQuintic(this float t){
        t *= 2.0f;
        if(t < 1.0f) return 0.5f * t * t * t * t * t;
        t -= 2.0f;
        return 0.5f * (t * t * t * t * t + 2);
    }

    public static float EaseInSinusoidal(this float t){
        return -Mathf.Cos(Mathf.PI / 2.0f * t) + 1.0f;
    }
    public static float EaseOutSinusoidal(this float t){
        return Mathf.Sin(Mathf.PI / 2.0f * t);
    }
    public static float EaseInOutSinusoidal(this float t){
        return -0.5f * (Mathf.Cos(Mathf.PI * t) - 1.0f);
    }
/*
    public static float EaseInExponential(this float t){
        return 2.0f ** (10.0f * (t - 1.0f));
    }
    public static float EaseOutExponential(this float t){
        return -(2.0f ** (-10.0f * t)) + 1.0f;
    }
    public static float EaseInOutExponential(this float t){
        t *= 2.0f;
        if(t < 1.0f) return 0.5f * 2.0f ** (10.0f * (t - 1.0f));
        t -= 2.0f;
        return 0.5f * (-(2.0f ** (-10.0f * t)) + 2 );
    }
*/
    public static float EaseInCircular(this float t){
        return -(Mathf.Sqrt(1 - t * t) - 1);
    }
    public static float EaseOutCircular(this float t){
        t -= 1.0f;
        return Mathf.Sqrt(1 - t * t);
    }
    public static float EaseInOutCircular(this float t){
        t *= 2.0f;
        if(t < 1.0f) return -0.5f * (Mathf.Sqrt(1 - t * t) - 1);
        t -= 2.0f;
        return 0.5f * (Mathf.Sqrt(1 - t * t) + 1);
    }
}
