/// <summary>
/// Finds the vertices that make up the area the new line is cordoning off. Implementing the Left-Right Technique I created
/// </summary>
/// <param name="startVertex">The start vertex of the line</param>
/// <param name="endVertex">The end vertex of the line</param>
/// <param name="newLine">The new Line</param>
/// <param name="lines">The list of all lines</param>
/// <param name="direction">The direction to be checking in relation to the new line. (perpendicular to the lines original vector)</param>
/// <returns>List of vertices</returns>
private List<Vertex> FindVertices(Vertex startVertex, Vertex endVertex, GameObject newLine, List<GameObject> lines, Vector3 direction)
{
    // Define variables to help during the loop
    List<Vertex> startVertices = new List<Vertex>();
    startVertices.Add(startVertex);
    GameObject startPreviousLineTaken = null;
    bool startPreviousLineReversed = false;

    List<Vertex> endVertices = new List<Vertex>();
    endVertices.Add(endVertex);
    GameObject endPreviousLineTaken = null;
    bool endPreviousLineReversed = false;

    bool updateStart = true; // Controls whether to update the start path or the end path this loop
    int numberOfLoops = 0;

    // Loop until the start and end point paths have met
    while (startVertices[startVertices.Count - 1] != endVertices[endVertices.Count - 1])
    {
        if (numberOfLoops < 20) // Limit the number of loops to a reasonable amount
        {
            // Update the start and end paths on alternate loops
            if (updateStart)
            {
                if (startVertices[startVertices.Count - 1] != null)
                {
                    startVertices.Add(FindNextVertex(out startPreviousLineTaken, out startPreviousLineReversed, newLine, lines, direction, startVertex, startVertices[startVertices.Count - 1], endVertex, startPreviousLineTaken, startPreviousLineReversed));
                }
                updateStart = !updateStart;
            }
            else
            {
                if (endVertices[endVertices.Count - 1] != null)
                {
                    endVertices.Add(FindNextVertex(out endPreviousLineTaken, out endPreviousLineReversed, newLine, lines, direction, endVertex, endVertices[endVertices.Count - 1], startVertex, endPreviousLineTaken, endPreviousLineReversed));
                }
                updateStart = !updateStart;
            }
            numberOfLoops++;
        }
        else break;
    }

    // Concat the lists after reversing the end vertices, removing the duplicate from the start of endvertices
    List<Vertex> FoundVertices = startVertices;
    endVertices.Reverse();
    endVertices.RemoveAt(0);
    FoundVertices.AddRange(endVertices);
    FoundVertices.RemoveAll(x => x == null);

    string logString = "Found Vertices: ";
    foreach (Vertex vert in FoundVertices)
    {
        logString += "[" + vert.GetVector3().ToString() + "], ";
    }
    Debug.Log(logString);
    return FoundVertices;

}

/// <summary>
/// Finds the next vertex in the given direction, a single step of the Left-Right technique
/// </summary>
/// <param name="lineTaken"></param>
/// <param name="newLine"></param>
/// <param name="lines"></param>
/// <param name="direction"></param>
/// <param name="originalVetex"></param>
/// <param name="fromVertex"></param>
/// <param name="towardsVertex"></param>
/// <param name="previousLineTaken"></param>
/// <returns></returns>
private Vertex FindNextVertex(out GameObject lineTaken, out bool reversedLineTaken, GameObject newLine, List<GameObject> lines, Vector3 direction, Vertex originalVetex, Vertex fromVertex, Vertex towardsVertex, GameObject previousLineTaken, bool previousLineReversed)
{
    List<GameObject> intersectingLines = new List<GameObject>();
    Vector3 towardsVector = Vector3.Normalize(towardsVertex.GetVector3() - fromVertex.GetVector3());


    // Get all the lines that pass through this vertex
    foreach (GameObject thisLine in lines)
    {
        if (thisLine != newLine && thisLine.GetComponent<LineScript>().PassesThrough(fromVertex))
        {
            intersectingLines.Add(thisLine);
        }
    }

    // Find the line that moves most towards the towardsVertex after ensuring the line's directions move with the direction vector
    GameObject smallestAngleLine = null;
    float smallestAngleLineAngle = 360;
    bool smallestAngleShouldReverse = false;
    foreach (GameObject thisLine in intersectingLines)
    {

        bool shouldReverse = false;

        Vector3 thisLineDirection = thisLine.GetComponent<LineScript>().GetNormalizedDirectionVector();
        float angleTowards = Vector3.Angle(thisLineDirection, towardsVector);

        // Only find whether to reverse direction on the lines we didnt take last time
        if (thisLine == previousLineTaken)
        {
            shouldReverse = previousLineReversed;
        }
        else
        {
            // Find whether the direction of the line should be flipped
            float angle = Vector3.Angle(thisLineDirection, direction);
            float otherAngle = 180 - angle;

            bool shouldReverseAngle = false;
            if (otherAngle < angle)
            {
                angle = otherAngle;
                shouldReverseAngle = true;
            }
            else if (angle == 90) // If perpendicular to direction, make sure we find out whether this line is pointing up or down
            {
                if (thisLineDirection != Vector3.Normalize(towardsVertex.GetVector3() - originalVetex.GetVector3()))
                {
                    shouldReverseAngle = true;
                }
            }



            // Get towards angles
            bool shouldReverseAngleTowards = false;
            float otherAngleTowards = 180 - angleTowards;
            if (otherAngleTowards < angleTowards)
            {
                angleTowards = otherAngleTowards;
                shouldReverseAngleTowards = true;
            }


            if (previousLineTaken != null)
            {
                // Take the shouldReverse of the smallest of the angles
                if (angle < angleTowards)
                {
                    shouldReverse = shouldReverseAngle;
                }
                else if (angleTowards < angle)
                {
                    shouldReverse = shouldReverseAngleTowards;
                }
            }
            else
            {
                shouldReverse = shouldReverseAngle;
            }

        }

        // Check to see if this line has the smallest angle so far
        if (shouldReverse)
        {
            thisLineDirection = Quaternion.AngleAxis(180, Vector3.up) * thisLineDirection;
            angleTowards = Vector3.Angle(thisLineDirection, towardsVector);
        }

        if (smallestAngleLine == null || (smallestAngleLine != null && smallestAngleLineAngle > angleTowards))
        {
            smallestAngleLine = thisLine;
            smallestAngleLineAngle = angleTowards;
            smallestAngleShouldReverse = shouldReverse;
        }

    }

    // Now i have the line to follow and the direction in which to follow it, need to get the next vertex on that line in that direction to return
    Vertex nextVertex = null;
    if (smallestAngleLine != null)
    {
        nextVertex = smallestAngleLine.GetComponent<LineScript>().GetNextVertex(fromVertex, smallestAngleShouldReverse);
    }

    if (nextVertex == null && smallestAngleLine != null)
    {
        smallestAngleLine.GetComponent<LineScript>();
        smallestAngleLine.GetComponent<LineScript>().GetNextVertex(fromVertex, smallestAngleShouldReverse);
        Debug.Log("UpdateArea: Couldn't find next vertex");
    }

    lineTaken = smallestAngleLine;
    reversedLineTaken = smallestAngleShouldReverse;
    return nextVertex;
}