using System.Collections;
using System.Collections.Generic;
using System.IO.Pipes;
using Unity.VisualScripting;
using UnityEngine;
using TMPro;
using UnityEditor;
using UnityEngine.UI;

public class NumberInputWindow : MonoBehaviour
{
    [SerializeField] GameObject graphAdderWindowGameObject;
    [SerializeField] GameObject numberInputWindowGameObject;

    [SerializeField] GraphAdderWindow graphAdderWindow;
    [SerializeField] TextMeshPro inputtedGraphFormula;
    [SerializeField] TextMeshPro inputtedForm;
    [SerializeField] TextMeshPro inputtedSignText;

    private GraphData data;
    private Vector3 linePassingPoint;
    private Vector3 lineDirection;
    private Vector4 planeCoefficient;

    private int sign;
    private string inputtedGraphFormulaString;
    private string inputtedFormString;
    private float inputtedNumber;

    private int currentInputtingNumber;
    private int inputtingSituation;


    private void Update()
    {
        inputtedForm.text = inputtedFormString;
        inputtedGraphFormula.text = inputtedGraphFormulaString;

    }

    public void setInitializeData(GraphData data)
    {
        this.data = data;
        linePassingPoint = new Vector3();
        lineDirection = new Vector3();
        planeCoefficient = new Vector4();
        pressedSignButton(0);
        inputtedFormString = "0";
        inputtingSituation = 0;
        inputtedNumber = 0;
        currentInputtingNumber = 0;
        inputtingSituation = 0;


        //直線の時
        if (data.getGraphNum() == 0)
        {
            inputtedGraphFormulaString = "点(x,y,z)を通る\nベクトル(a,b,c)に平行な直線";
        }
        else if (data.getGraphNum() == 1) //平面
        {
            inputtedGraphFormulaString = "ax + by + cz + d = 0";
        }
    }


    public void pressedKeyButton(int n)
    {
        switch(inputtingSituation)
        {
            case 0:
                if(inputtedFormString== "0")
                {
                    inputtedFormString = n.ToString();
                }
                else
                {
                    inputtedFormString += n.ToString();
                }
                
                break;
            case 1:
                inputtingSituation = 2;
                inputtedFormString += n.ToString();
                break;
            case 2:
                inputtingSituation = 3;
                inputtedFormString += n.ToString();
                break;
            case 3:
                inputtedFormString += n.ToString();
                break;

        }
        
    }

    public void pressedNextButton()
    {
        //直線ならこちら
        if (data.getGraphNum() == 0)
        {
            try
            {
                inputtedNumber = float.Parse(inputtedFormString);
                if(sign == -1)
                {
                    inputtedNumber = -inputtedNumber;
                }
            }
            catch (System.Exception)
            {

                throw;
            }
            

            switch (currentInputtingNumber)
            {
                case 0:
                    linePassingPoint.x = inputtedNumber;
                    break;
                case 1:
                    linePassingPoint.y = inputtedNumber;
                    break;
                case 2:
                    linePassingPoint.z = inputtedNumber;
                    break;
                case 3:
                    lineDirection.x = inputtedNumber;
                    break;
                case 4:
                    lineDirection.y = inputtedNumber;
                    break;
                case 5:
                    lineDirection.z = inputtedNumber;

                    finishInputtingLine();

                    break;

            }

            inputtedFormString = "0";
            inputtingSituation = 0;
            currentInputtingNumber++;
            updateInputtedGraphFormulaString();
        }
        //平面ならこっち
        else if (data.getGraphNum() == 1)
        {
            try
            {
                inputtedNumber = float.Parse(inputtedFormString);
                if (sign == -1)
                {
                    inputtedNumber = -inputtedNumber;
                }
            }
            catch (System.Exception)
            {

                throw;
            }


            switch (currentInputtingNumber)
            {
                case 0:
                    planeCoefficient.x = inputtedNumber;
                    break;
                case 1:
                    planeCoefficient.y = inputtedNumber;
                    break;
                case 2:
                    planeCoefficient.z = inputtedNumber;
                    break;
                case 3:
                    planeCoefficient.w = inputtedNumber;

                    finishInputtingPlane();
                    break;
            }

            inputtedFormString = "0";
            inputtingSituation = 0;
            currentInputtingNumber++;
            updateInputtedGraphFormulaString();
        }

    }

    

    public void pressedSignButton(int n)
    {

        //n=0 時は初期化
        if (n == 0)
        {
            inputtedSignText.text = "+";
            sign = 1;

            return;
        }

        sign = -sign;

        if(sign == 1)
        {

            inputtedSignText.text = "+";
        }
        else
        {

            inputtedSignText.text = "-";
        }
        
    }

    public void pressedPointButton()
    {
        if (inputtingSituation == 0)
        {
            inputtedFormString += ".";
            inputtingSituation = 1;
        }
    }

    public void pressedDeleteButton()
    {
        //状態遷移図参照(遷移図棄却済)
        switch(inputtingSituation)
        {
            case 0: //80,8など
                inputtedFormString = inputtedFormString.Remove(inputtedFormString.Length-1, 1);
                if (inputtedFormString == string.Empty)
                {
                    inputtedFormString = "0";
                }
                break;
            case 1: //80. , 0. など
                inputtedFormString = inputtedFormString.Remove(inputtedFormString.Length-1,1);
                inputtingSituation = 0;
                break;
            case 2: //80.0 ,5.2 など
                inputtedFormString = inputtedFormString.Remove(inputtedFormString.Length-1, 1);
                inputtingSituation = 1;
                break;
            case 3: //80.00 , 7.43 など
                inputtedFormString = inputtedFormString.Remove(inputtedFormString.Length - 1, 1);
                if(inputtedFormString.Substring(inputtedFormString.Length-2,1).Equals(".") )
                {
                    inputtingSituation = 2;
                }
                break;
        }
    }

    public void pressedBackButton()
    {
        //直線の時
        if (data.getGraphNum() == 0)
        {
            switch (currentInputtingNumber)
            {
                case 0: //まだどの値も入力されていない -> 前の画面へ
                    graphAdderWindowGameObject.SetActive(true);
                    graphAdderWindow.setGraphData(data);
                    numberInputWindowGameObject.SetActive(false);
                    break;
                case 1: //ひとつ前の入力を再現
                    inputtedFormString = linePassingPoint.x.ToString();
                    currentInputtingNumber--;
                    inputtingSituation = judgeInputtingSituation(inputtedFormString);
                    //もしも認識できなかったら0へ
                    if (inputtingSituation == -1)
                    {
                        inputtingSituation = 0;
                        inputtedFormString = "0";
                    }

                    break;
                case 2:
                    inputtedFormString = linePassingPoint.y.ToString();
                    currentInputtingNumber--;
                    inputtingSituation = judgeInputtingSituation(inputtedFormString);
                    //もしも認識できなかったら0へ
                    if (inputtingSituation == -1)
                    {
                        inputtingSituation = 0;
                        inputtedFormString = "0";
                    }
                    break;
                case 3:
                    inputtedFormString = linePassingPoint.z.ToString();
                    currentInputtingNumber--;
                    inputtingSituation = judgeInputtingSituation(inputtedFormString);
                    //もしも認識できなかったら0へ
                    if (inputtingSituation == -1)
                    {
                        inputtingSituation = 0;
                        inputtedFormString = "0";
                    }
                    break;
                case 4:
                    inputtedFormString = lineDirection.x.ToString();
                    currentInputtingNumber--;
                    inputtingSituation = judgeInputtingSituation(inputtedFormString);
                    //もしも認識できなかったら0へ
                    if (inputtingSituation == -1)
                    {
                        inputtingSituation = 0;
                        inputtedFormString = "0";
                    }
                    break;
                case 5:
                    inputtedFormString = lineDirection.y.ToString();
                    currentInputtingNumber--;
                    inputtingSituation = judgeInputtingSituation(inputtedFormString);
                    //もしも認識できなかったら0へ
                    if (inputtingSituation == -1)
                    {
                        inputtingSituation = 0;
                        inputtedFormString = "0";
                    }
                    break;
            }
        }
        //平面の時
        else if(data.getGraphNum()==1)
        {
            switch (currentInputtingNumber) 
            {
                case 0: //まだどの値も入力されていない -> 前の画面へ
                    graphAdderWindowGameObject.SetActive(true);
                    graphAdderWindow.setGraphData(data);
                    numberInputWindowGameObject.SetActive(false);
                    break;
                case 1: //ひとつ前の入力を再現
                    inputtedFormString = planeCoefficient.x.ToString();
                    currentInputtingNumber--;
                    //Debug.Log(judgeInputtingSituation(inputtedFormString));//
                    inputtingSituation = judgeInputtingSituation(inputtedFormString);
                    //もしも認識できなかったら0へ
                    if (inputtingSituation == -1)
                    {
                        inputtingSituation = 0;
                        inputtedFormString = "0";
                    }
                    break;
                case 2:
                    inputtedFormString = planeCoefficient.y.ToString();
                    currentInputtingNumber--;
                    inputtingSituation = judgeInputtingSituation(inputtedFormString);
                    //もしも認識できなかったら0へ
                    if (inputtingSituation == -1)
                    {
                        inputtingSituation = 0;
                        inputtedFormString = "0";
                    }
                    break;
                case 3:
                    inputtedFormString = planeCoefficient.z.ToString();
                    currentInputtingNumber--;
                    inputtingSituation = judgeInputtingSituation(inputtedFormString);
                    //もしも認識できなかったら0へ
                    if (inputtingSituation == -1)
                    {
                        inputtingSituation = 0;
                        inputtedFormString = "0";
                    }
                    break;

            }
        }
    }

    public void finishInputtingLine()
    {
        data.setDataFormulaInputted(true);
        data.setLinePassingPoint(linePassingPoint);
        data.setLineDirection(lineDirection);

        inputtedGraphFormulaString = "点(" + linePassingPoint.x + " ," + linePassingPoint.y + " ," + linePassingPoint.z + ")を通る" +
                        "\nベクトル(" + lineDirection.x + " ," + lineDirection.y + " ," + lineDirection.z + ")に平行な直線";


        graphAdderWindowGameObject.SetActive(true);
        graphAdderWindow.setGraphData(data);
        numberInputWindowGameObject.SetActive(false);
    }

    public void finishInputtingPlane()
    {

        data.setDataFormulaInputted(true);
        data.setPlaneCoefficient(planeCoefficient);

        if (planeCoefficient.y < 0)
        {
            if(planeCoefficient.z < 0)
            {
                if(planeCoefficient.w < 0)
                {
                    inputtedGraphFormulaString
                        = planeCoefficient.x + "x - "
                        + -planeCoefficient.y + "y - "
                        + -planeCoefficient.z + "z - "
                        + -planeCoefficient.w + " = 0";
                }
                else
                {
                    inputtedGraphFormulaString
                        = planeCoefficient.x + "x - "
                        + -planeCoefficient.y + "y - "
                        + -planeCoefficient.z + "z + "
                        + planeCoefficient.w + " = 0";
                }
            }
            else
            {
                if (planeCoefficient.w < 0)
                {
                    inputtedGraphFormulaString
                        = planeCoefficient.x + "x - "
                        + -planeCoefficient.y + "y + "
                        + planeCoefficient.z + "z - "
                        + -planeCoefficient.w + " = 0";
                }
                else
                {
                    inputtedGraphFormulaString
                        = planeCoefficient.x + "x - "
                        + -planeCoefficient.y + "y + "
                        + planeCoefficient.z + "z + "
                        + planeCoefficient.w + " = 0";
                }
            }
        }
        else
        {
            if (planeCoefficient.z < 0)
            {
                if (planeCoefficient.w < 0)
                {
                    inputtedGraphFormulaString
                        = planeCoefficient.x + "x + "
                        + -planeCoefficient.y + "y - "
                        + -planeCoefficient.z + "z - "
                        + -planeCoefficient.w + " = 0";
                }
                else
                {
                    inputtedGraphFormulaString
                        = planeCoefficient.x + "x + "
                        + -planeCoefficient.y + "y - "
                        + -planeCoefficient.z + "z + "
                        + planeCoefficient.w + " = 0";
                }
            }
            else
            {
                if (planeCoefficient.w < 0)
                {
                    inputtedGraphFormulaString
                        = planeCoefficient.x + "x + "
                        + planeCoefficient.y + "y + "
                        + planeCoefficient.z + "z - "
                        + -planeCoefficient.w + " = 0";
                }
                else
                {
                    inputtedGraphFormulaString
                        = planeCoefficient.x + "x + "
                        + planeCoefficient.y + "y + "
                        + planeCoefficient.z + "z + "
                        + planeCoefficient.w + " = 0";
                }
            }
        }

        graphAdderWindowGameObject.SetActive(true);
        graphAdderWindow.setGraphData(data);
        numberInputWindowGameObject.SetActive(false);
    }

    private int judgeInputtingSituation(string str)
    {
        if (!str.Contains("."))
        {
            return 0;
        }
        else if(str.Substring(str.Length-1 , 1).Equals("."))
        {
            return 1;
        }
        else if(str.Substring(str.Length-2 , 1).Equals(".")) 
        {
            return 2;
        }
        else if((str.Length-1) - str.LastIndexOf('.') > 1)
        {
            return 3;
        }

        
        return -1;
    }

    private void updateInputtedGraphFormulaString()
    {
        //直線ならこちら
        if(data.getGraphNum() == 0)
        {
            switch (currentInputtingNumber)
            {
                case 0:
                    inputtedGraphFormulaString = "点(x,y,z)を通る\nベクトル(a,b,c)に平行な直線";
                    break;
                case 1:
                    inputtedGraphFormulaString = "点(" + linePassingPoint.x + " ,y ,z)を通る" +
                        "\nベクトル(a ,b ,c)に平行な直線";
                    break;
                case 2:
                    inputtedGraphFormulaString = "点(" + linePassingPoint.x + " ," + linePassingPoint.y + " ,z)を通る" +
                        "\nベクトル(a ,b ,c)に平行な直線";
                    break;
                case 3:
                    inputtedGraphFormulaString = "点(" + linePassingPoint.x + " ," + linePassingPoint.y + " ," + linePassingPoint.z + ")を通る" +
                        "\nベクトル(a ,b ,c)に平行な直線";
                    break;
                case 4:
                    inputtedGraphFormulaString = "点(" + linePassingPoint.x + " ," + linePassingPoint.y + " ," + linePassingPoint.z + ")を通る" +
                        "\nベクトル(" + lineDirection.x + " ,b ,c)に平行な直線";
                    break;
                case 5:
                    inputtedGraphFormulaString = "点(" + linePassingPoint.x + " ," + linePassingPoint.y + " ," + linePassingPoint.z + ")を通る" +
                        "\nベクトル(" + lineDirection.x + " ," + lineDirection.y + " ,c)に平行な直線";
                    break;
            }
        }
        //平面はこちら
        else if(data.getGraphNum() == 1)
        {
            switch (currentInputtingNumber)
            {
                case 0:
                    inputtedGraphFormulaString = "ax + by + cz + d = 0";
                    break;
                case 1:
                    inputtedGraphFormulaString = planeCoefficient.x +"x + by + cz + d = 0";
                    break;
                case 2:
                    inputtedGraphFormulaString = planeCoefficient.x + "x + "+planeCoefficient.y + "y + cz + d = 0";
                    if (planeCoefficient.y < 0)
                    {
                        inputtedGraphFormulaString = planeCoefficient.x + "x - " + -planeCoefficient.y + "y + cz + d = 0";
                    }
                        break;
                case 3:
                    inputtedGraphFormulaString = planeCoefficient.x + "x + " + planeCoefficient.y + "y + "+ planeCoefficient.z + "z + d = 0";

                    if (planeCoefficient.y < 0)
                    {
                        if (planeCoefficient.z < 0)
                        {
                            inputtedGraphFormulaString = planeCoefficient.x + "x - " + -planeCoefficient.y + "y - " + -planeCoefficient.z + "z + d = 0";
                        }
                        else
                        {
                            inputtedGraphFormulaString = planeCoefficient.x + "x - " + -planeCoefficient.y + "y + " + planeCoefficient.z + "z + d = 0";
                        }
                    }
                    else
                    {
                        if (planeCoefficient.z < 0)
                        {
                            inputtedGraphFormulaString = planeCoefficient.x + "x + " + planeCoefficient.y + "y - " + -planeCoefficient.z + "z + d = 0";
                        }
                        else
                        {
                            inputtedGraphFormulaString = planeCoefficient.x + "x + " + planeCoefficient.y + "y + " + planeCoefficient.z + "z + d = 0";
                        }
                    }

                    break;
                
            }
        }
        
    }


    public string getMessage()
    {
        return inputtedGraphFormulaString;
    }
}
