using Microsoft.MixedReality.Toolkit.UI;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using System;
using System.Reflection;
using Microsoft.MixedReality.Toolkit;

public class GraphAdderWindow : BackButton
{
    [SerializeField] private GameObject formulaInput;
    [SerializeField] private GameObject graphAdderWindow;
    [SerializeField] private GameObject numberInputWindow;
    [SerializeField] private GameObject plotSpace;
    [SerializeField] private GameObject graphs;
    [SerializeField] private GraphManager graphManager;

    public GraphData data;

    //画面遷移の仕方を記録  -1 -> 新規 、0,1,2->値変更
    private int identCode;
    private int graphNum;

    private List<string> messageList;

    public void Initialize(GraphData data, int code)
    {
        this.data = data;
        identCode = code;
        graphNum = 0;
        Debug.Log("GraphAdderWindow:Start()data");
        messageList = new List<string>
        {
            "タッチして直線の式を入力",
            "タッチして平面の式を入力",
            "対応していません。"
        };

        messageList[graphNum] = getFormulaMessage(data);
    }


    public void Update()
    {
        formulaInput.GetComponent<ButtonConfigHelper>().MainLabelText
            = messageList[graphNum];
    }



    public virtual void setGraphNom(int num)
    {
        /*0.直線
         * 1.平面
         * 2.その他
         */
        graphNum = num;
    }

    public void setGraphData(GraphData data)
    {
        this.data = data;

        messageList[data.getGraphNum()] = getFormulaMessage(data);

        Debug.Log("入力された平面データ\n"
            + data.getPlaneCoefficient().x
            + "," + data.getPlaneCoefficient().y
            + "," + data.getPlaneCoefficient().z
            + "," + data.getPlaneCoefficient().w);
    }

    //決定ボタン
    public void createGraph()
    {
        switch (data.getGraphNum())
        {
            case 0:
                if(data.getLineDirection() == Vector3.zero)
                {
                    error("方向ベクトルが全て0です。\n入力し直してください");
                    return;
                }

                Vector3 inLinePoint = new Vector3();
                GameObject ln = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
                ln.transform.parent = graphs.transform;

                if (data.getLineDirection().y != 0)
                {

                    float uY0 = -1 * data.getLinePassingPoint().y / data.getLineDirection().y;


                    inLinePoint = new Vector3(
                        data.getLinePassingPoint().x + uY0 * data.getLineDirection().x,
                        0,
                        data.getLinePassingPoint().z + uY0 * data.getLineDirection().z);

                }
                else if (data.getLineDirection().x != 0)
                {
                    float uX0 = -1 * data.getLinePassingPoint().x / data.getLineDirection().x;

                    inLinePoint = new Vector3(
                        0,
                        data.getLinePassingPoint().y + uX0 * data.getLineDirection().y,
                        data.getLinePassingPoint().z + uX0 * data.getLineDirection().z);

                }
                else if (data.getLineDirection().z != 0)
                {
                    float uZ0 = -1 * data.getLinePassingPoint().z / data.getLineDirection().z;

                    inLinePoint = new Vector3(
                        data.getLinePassingPoint().x + uZ0 * data.getLineDirection().x,
                        data.getLinePassingPoint().y + uZ0 * data.getLineDirection().y,
                        0);

                }
                

                ln.transform.localRotation = Quaternion.FromToRotation(Vector3.up, data.getLineDirection());
                ln.transform.localPosition = inLinePoint;
                ln.transform.localScale = new Vector3(0.01f, 20, 0.01f);
                Destroy(data.getgraphObject());
                data.setGraphObject(ln);
                graphManager.addNewGraphData(data, identCode);
                

                break;
            case 1:

                Vector3 nomalVector3 = new Vector3(
                    data.getPlaneCoefficient().x,
                    data.getPlaneCoefficient().y,
                    data.getPlaneCoefficient().z);
                nomalVector3.Normalize();

                if (nomalVector3 == Vector3.zero)
                {
                    //全て0の場合
                    error("法線ベクトルが作成できません。\n" +
                        "x,y,zのいずれかの係数を入れてください。");
                    return;
                }

                Vector3 inPlanePoint = new Vector3();


                if (data.getPlaneCoefficient().y != 0)
                {
                    inPlanePoint = new Vector3(
                        0,
                        -1 * data.getPlaneCoefficient().w / data.getPlaneCoefficient().y,
                        0);


                }
                else if (data.getPlaneCoefficient().x != 0)
                {
                    inPlanePoint = new Vector3(
                        -1 * data.getPlaneCoefficient().w / data.getPlaneCoefficient().x,
                        0,
                        0);

                }
                else if (data.getPlaneCoefficient().z != 0)
                {
                    inPlanePoint = new Vector3(
                        0,
                        0,
                        -1 * data.getPlaneCoefficient().w / data.getPlaneCoefficient().z);

                }
                
                GameObject pl = GameObject.CreatePrimitive(PrimitiveType.Cube);
                pl.transform.parent = graphs.transform;
                pl.transform.localPosition = inPlanePoint;
                pl.transform.localRotation = Quaternion.FromToRotation(Vector3.up, nomalVector3);
                pl.transform.localScale = new Vector3(5, 0.001f, 5);
                Destroy(data.getgraphObject());
                data.setGraphObject(pl);
                graphManager.addNewGraphData(data, identCode);

                break;
            case 2:
                Debug.Log("未対応");
                break;
        }

        //画面遷移：　自分を閉じる
        base.anotherButtonAction();
    }

    public void pressedFormulaInputButton()
    {
        data.setGraphNum(graphNum);
        numberInputWindow.GetComponent<NumberInputWindow>().setInitializeData(data);
        numberInputWindow.SetActive(true);
        graphAdderWindow.SetActive(false);
    }

    public string getFormulaMessage(GraphData data)
    {
        string str = "";
        if(data == null)
        {
            return str;
        }

        if (data.isDataFormulaInputted())
        {
            switch (data.getGraphNum())
            {
                case 0: //直線
                    Vector3 p = data.getLinePassingPoint();
                    Vector3 d = data.getLineDirection();
                    str = "点(" + p.x + " ," + p.y + " ," + p.z + ")を通る" +
                        "\nベクトル(" + d.x + " ," + d.y + " ," + d.z + ")に平行な直線"; ;

                    break;
                case 1:
                    Vector4 c = data.getPlaneCoefficient();

                    str = c.x + "x ";
                    if (Mathf.Sign(c.y) == -1)
                    {
                        str += c.y + "y ";
                    }
                    else
                    {
                        str += "+" + c.y + "y ";
                    }

                    if (Mathf.Sign(c.z) == -1)
                    {
                        str += c.z + "z ";
                    }
                    else
                    {
                        str += "+" + c.z + "z ";
                    }

                    if (Mathf.Sign(c.w) == -1)
                    {
                        str += c.w + " = 0";
                    }
                    else
                    {
                        str += "+" + c.w + " = 0";
                    };
                    break;
                case 2:
                    str = "Error";
                    break;
            }

        }
        else
        {
            switch (data.getGraphNum())
            {
                case 0: //直線
                    str = "タッチして直線の式を入力";
                    break;
                case 1:
                    str = "タッチして平面の式を入力";
                    break;
                case 2:
                    str = "対応していません。";
                    break;
            }

        }

        return str;
        
    }

    private void error(string str)
    {
        this.gameObject.GetComponent<ErrorWindow>().displayErrorMessage(str);
    }
}
