using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public enum State
{
    confirm,
    halfconfirm,
    unknown
}
public class Point
{
    public string name;

    public float x;
    public float y;
    public float z;

    State pointState = State.unknown;

    public List<Line> lines;
    public List<Vector> vectors;
    public List<Plane> planes;

    public List<Constraint> constraints;
    public Point(float x, float y, float z, string n = "")
    {
        this.x = x;
        this.y = y;
        this.z = z;
        
        lines = new List<Line>();
        vectors = new List<Vector>();
        planes = new List<Plane>();

        constraints = new List<Constraint>();

        if (n.Length != 0)
            name = n;
    }

    public void addLine(Line l)
    {
        lines.Add(l);
    }

    public void addVector(Vector v)
    {
        vectors.Add(v);
    }

    public void addPlane(Plane p)
    {
        planes.Add(p);
    }

    public void setPoint(float x, float y, float z)
    {
        this.x = x;
        this.y = y;
        this.z = z;
    }

    public void setPoint(Point p)
    {
        x = p.x;
        y = p.y;
        z = p.z;
    }

    public Point add(Vector3 v)
    {
        Point tmp = new Point(x, y, z);
        tmp.x += v.x;
        tmp.y += v.y;
        tmp.z += v.z;
        return tmp;
    }

    public static Point operator+(Point p, Vector3 v)
    {
        p.x += v.x;
        p.y += v.y;
        p.z += v.z;
        return p;
    }

    public void update()
    {
        foreach(Line l in lines)
        {
            l.updateDirection();
        }
        foreach (Vector v in vectors)
        {
            v.updateDirection();
        }
        foreach(Plane p in planes)
        {
            p.updateNormal();
        }
    }

    public void setState(State s)
    {
        pointState = s;
        foreach (Line l in lines)
        {
            l.updateDirection();
        }

        foreach(Constraint c in constraints)
        {
            c.checkState();
        }
    }

    public State getState()
    {
        return pointState;
    }

    public int checkConstraint()
    {
        int Anum = 0;
        int Hnum = 0;

        foreach(Constraint c in constraints)
        {
            if (c.getState() == State.confirm)
                Anum++;
            else if (c.getState() == State.halfconfirm)
                Hnum++;
        }

        if (Anum == constraints.Count)
        {
            pointState = State.confirm;
            return 0;//All finish
        }
        else if (Hnum != 0)
        {
            pointState = State.halfconfirm;
            return 1;//Half finish
        } 
        else if(Anum == 0 && Hnum == 0)
        {
            pointState = State.unknown;
            return 2;//no finish
        }
        else
            return 3;//wait

    }
}
