public WallCoord(NodeTemplate.Wall wall, Vector2Int coord)
 {
     this.wall  = wall;
     this.coord = new Vector2Int(coord.x, coord.y);
 }
    void ApplyPathToMap(List <Vector2Int> pathList, MapTemplate template)
    {
        // Path segment building
        List <PathSegment> pathSegments      = new List <PathSegment>();
        Vector2Int         previousCoord     = new Vector2Int(0, 0);
        PathSegment        currentSegment    = new PathSegment(previousCoord);
        Vector2Int         previousDirection = new Vector2Int(0, 0);
        Vector2Int         currentDirection  = new Vector2Int(0, 0); // used to see if we still going the same direction


        string currentAxis  = "x";
        string previousAxis = currentAxis;


        List <MapTemplate.WallCoord> leftWall  = new List <MapTemplate.WallCoord>();
        List <MapTemplate.WallCoord> rightWall = new List <MapTemplate.WallCoord>();

        NodeTemplate.Wall currentLeftWall  = NodeTemplate.Wall.N;
        NodeTemplate.Wall currentRightWall = NodeTemplate.Wall.S;

        NodeTemplate.Wall previousLeftWall  = currentLeftWall;
        NodeTemplate.Wall previousRightWall = currentRightWall;


        // Shorten the cardinal directions
        NodeTemplate.Wall N = NodeTemplate.Wall.N;
        NodeTemplate.Wall E = NodeTemplate.Wall.E;
        NodeTemplate.Wall S = NodeTemplate.Wall.S;
        NodeTemplate.Wall W = NodeTemplate.Wall.W;

        // Translate path onto map
        var          arr = pathList.ToArray();
        NodeTemplate node;
        int          segmentC = 1;

        bool isLastTile      = false;
        bool isFirstTile     = false;
        bool isSecondTile    = false;
        bool updateWallSides = false;

        for (int i = 0; i < arr.Length; ++i)
        {
            updateWallSides = false;
            isLastTile      = i == arr.Length - 1;
            isFirstTile     = i == 0;
            isSecondTile    = i == 1;

            Vector2Int currentCoord = arr[i];



            // #############################################################

            //                      ASSIGN TILE DATA

            // #############################################################
            // Assign node type to the template
            node = template.GetNode(currentCoord.y, currentCoord.x);
            node.isTowerPlacable = false;
            if (i == 0)
            {
                node.type = "start";
            }
            else if (i == arr.Length - 1)
            {
                node.type = "end";


                for (int p = -2; p < 3; ++p)
                {
                    for (int j = -2; j < 4; ++j)
                    {
                        Vector2Int   tempCoord = currentCoord + new Vector2Int(p, j);
                        NodeTemplate temp      = template.GetNode(tempCoord.y, tempCoord.x);

                        if (temp != null)
                        {
                            temp.isEnvPlacable   = false;
                            temp.isTowerPlacable = false;
                        }
                    }
                }
            }
            else
            {
                node.type = "path";
            }



            // #############################################################

            //                      BUILD PATH SEGMENTS

            // #############################################################

            // Is first node?
            if (isFirstTile)
            {
                // Start the first segment
                currentSegment.start = currentCoord;
            }
            else
            {
                // Is second node
                if (isSecondTile)
                {
                    // Establish the movement direction
                    currentDirection  = currentCoord - previousCoord;
                    previousDirection = currentDirection;

                    currentSegment.end = currentCoord;
                    currentAxis        = previousCoord.x != currentCoord.x ? "y" : "x";
                    currentSegment.SetAxis(currentAxis);

                    // Track wall
                    leftWall.Add(new MapTemplate.WallCoord(previousLeftWall, previousCoord));
                    rightWall.Add(new MapTemplate.WallCoord(previousRightWall, previousCoord));
                }
                else
                {
                    // Is going same direction?
                    currentDirection = currentCoord - previousCoord;
                    if (currentDirection == previousDirection)
                    {
                        // Increment segment
                        currentSegment.end = currentCoord;

                        // Track wall
                        leftWall.Add(new MapTemplate.WallCoord(previousLeftWall, previousCoord));
                        rightWall.Add(new MapTemplate.WallCoord(previousRightWall, previousCoord));
                    }
                    // Is changing direction?
                    else
                    {
                        ++segmentC;
                        // Save segment
                        pathSegments.Add(currentSegment);
                        // Start a new segment from the previous position to the current
                        currentSegment = new PathSegment(previousCoord, currentCoord);

                        currentAxis = previousCoord.x != currentCoord.x ? "y" : "x";
                        currentSegment.SetAxis(currentAxis);

                        updateWallSides = true;
                    }
                }
            }

            // Was this the last segment?
            if (isLastTile)
            {
                // Add it to the list
                pathSegments.Add(currentSegment);
                updateWallSides = true;
            }



            // #############################################################

            //                  TOGGLE WALLS AND PILLARS

            // #############################################################

            // Reminder Y represent the incrementing in the column ->
            // Reminder X represent the incrementing in the Row ^

            // Handle start and end
            if (isFirstTile || isLastTile)
            {
                NodeTemplate currentNodeTemplate = template.GetNode(currentCoord.y, currentCoord.x);
                // Vertical
                currentNodeTemplate.hasWall[(int)NodeTemplate.Wall.N] = true;
                currentNodeTemplate.hasWall[(int)NodeTemplate.Wall.S] = true;

                //Excluse regular pillars at the ends of the path
                if (isFirstTile)
                {
                    currentNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.NE] = true;
                    currentNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.SE] = true;
                }
            }



            if (previousDirection == currentDirection)
            {
                NodeTemplate previousNodeTemplate = template.GetNode(previousCoord.y, previousCoord.x);
                if (previousDirection.y == 0)
                {
                    // Vertical
                    previousNodeTemplate.hasWall[(int)NodeTemplate.Wall.E] = true;
                    previousNodeTemplate.hasWall[(int)NodeTemplate.Wall.W] = true;


                    // We wont put regular pillars at the extreams of the path... we got fancy ones for that
                    if (!isLastTile)
                    {
                        previousNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.NE] = true;
                        previousNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.NW] = true;
                    }
                }
                else
                {
                    // Horizontal
                    previousNodeTemplate.hasWall[(int)NodeTemplate.Wall.N] = true;
                    previousNodeTemplate.hasWall[(int)NodeTemplate.Wall.S] = true;

                    if (!isLastTile)
                    {
                        previousNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.SE] = true;
                        previousNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.NE] = true;
                    }
                }
            }
            else if (i != 1)
            {
                NodeTemplate previousNodeTemplate = template.GetNode(previousCoord.y, previousCoord.x);

                // Cap off the previous direction

                // Handle Corner

                // Vertically
                if (-1 * previousDirection.x == 1)
                {
                    previousNodeTemplate.hasWall[(int)NodeTemplate.Wall.N]      = true;
                    previousNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.NE] = true;
                }
                if (-1 * previousDirection.x == -1)
                {
                    previousNodeTemplate.hasWall[(int)NodeTemplate.Wall.S]      = true;
                    previousNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.SE] = true;
                }

                // Horizontally
                if (-1 * previousDirection.y == 1)
                {
                    previousNodeTemplate.hasWall[(int)NodeTemplate.Wall.W]      = true;
                    previousNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.NW] = true;
                }
                if (-1 * previousDirection.y == -1)
                {
                    previousNodeTemplate.hasWall[(int)NodeTemplate.Wall.E]      = true;
                    previousNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.NE] = true;
                }



                // Call off the beginning of the new direction
                // Handle Corner
                if (-1 * currentDirection.x == 1)
                {
                    previousNodeTemplate.hasWall[(int)NodeTemplate.Wall.S]      = true;
                    previousNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.SE] = true;
                }
                if (-1 * currentDirection.x == -1)
                {
                    previousNodeTemplate.hasWall[(int)NodeTemplate.Wall.N]      = true;
                    previousNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.NE] = true;
                }
                if (-1 * currentDirection.y == 1)
                {
                    previousNodeTemplate.hasWall[(int)NodeTemplate.Wall.E]      = true;
                    previousNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.NE] = true;
                }
                if (-1 * currentDirection.y == -1)
                {
                    previousNodeTemplate.hasWall[(int)NodeTemplate.Wall.W]      = true;
                    previousNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.NW] = true;
                }



                // Pillar edge case
                if (-1 * previousDirection.x == -1 && currentDirection.x == 0) // Down to horizontal
                {
                    previousNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.SW] = true;
                    previousNodeTemplate.hasPillar[(int)NodeTemplate.Pillar.NE] = true;
                }
            }


            // END TOGGLE WALLS AND PILLARS ________________________________



            // #############################################################

            //                      KEEP TRACK OF WALLS

            // #############################################################
            if (updateWallSides)
            {
                if (isLastTile)
                {
                    previousAxis = currentAxis;

                    previousLeftWall  = currentLeftWall;
                    previousRightWall = currentRightWall;

                    previousCoord     = currentCoord;
                    previousDirection = currentDirection;
                }


                // Translate the vectors to N,E,S,W
                NodeTemplate.Wall previousTowardWall = NodeTemplate.Wall.E;
                NodeTemplate.Wall currentTowardWall  = NodeTemplate.Wall.E;
                if (previousDirection.y == 0)
                {
                    previousTowardWall = (previousDirection.x < 0) ? N : S;
                }
                else
                {
                    previousTowardWall = (previousDirection.y < 0) ? W : E;
                }

                if (currentDirection.y == 0)
                {
                    currentTowardWall = (currentDirection.x < 0) ? N : S;
                }
                else
                {
                    currentTowardWall = (currentDirection.y < 0) ? W : E;
                }



                /*
                 * Hashtable dirMap = new Hashtable();
                 * dirMap.Add(NodeTemplate.Wall.N, "North");
                 * dirMap.Add(NodeTemplate.Wall.E, "East");
                 * dirMap.Add(NodeTemplate.Wall.S, "South");
                 * dirMap.Add(NodeTemplate.Wall.W, "West");
                 *
                 * Debug.Log("Dir: (" + previousDirection.x + "," + previousDirection.y + ") (" + currentDirection.x + ", " + currentDirection.y + ")");
                 * Debug.Log("COO: (" + (string)dirMap[currentTowardWall] + ")");
                 */

                bool turnedLeft = false;
                // Right -> up
                if (previousTowardWall == E && currentTowardWall == N)
                {
                    turnedLeft = true;
                }

                // Down -> Right
                if (previousTowardWall == S && currentTowardWall == E)
                {
                    turnedLeft = true;
                }

                // Left -> Down
                if (previousTowardWall == W && currentTowardWall == S)
                {
                    turnedLeft = true;
                }

                // UP -> Left
                if (previousTowardWall == N && currentTowardWall == W)
                {
                    turnedLeft = true;
                }



                // Rotate Coordiantes (N, E, S, W = 0, 1, 2, 3) % 4
                // Base cases are relative to that respecive side being North... IE = 0 there for all end directions can be transformed into offsets
                if (turnedLeft)
                {
                    // Based on LEFTWALL = N
                    // Relative to left wall
                    rightWall.Add(new MapTemplate.WallCoord(NodeTemplate.IncrementWall(previousLeftWall, 2), previousCoord)); // Add S wall
                    rightWall.Add(new MapTemplate.WallCoord(NodeTemplate.IncrementWall(previousLeftWall, 1), previousCoord)); // Add E wall
                    currentLeftWall  = NodeTemplate.IncrementWall(previousLeftWall, 3);                                       // W
                    currentRightWall = NodeTemplate.IncrementWall(previousLeftWall, 1);                                       // E
                }
                else
                {
                    // Based on RIGHTWALL = N
                    // Relative to right wall
                    leftWall.Add(new MapTemplate.WallCoord(NodeTemplate.IncrementWall(previousRightWall, 2), previousCoord)); // Add S wall
                    leftWall.Add(new MapTemplate.WallCoord(NodeTemplate.IncrementWall(previousRightWall, 3), previousCoord)); // Add W wall
                    currentLeftWall  = NodeTemplate.IncrementWall(previousRightWall, 3);                                      // W
                    currentRightWall = NodeTemplate.IncrementWall(previousRightWall, 1);                                      // E
                }
            }
            // END KEEP TRACK OF WALLS _____________________________________



            previousAxis = currentAxis;

            previousLeftWall  = currentLeftWall;
            previousRightWall = currentRightWall;

            previousCoord     = currentCoord;
            previousDirection = currentDirection;
            //  END BUILD PATH SEGMENTS ____________________________________
        }// end for



        // Indicate the parimiter on the map
        for (int row = 0; row < m_mapSizeY; ++row)
        {
            template.GetNode(row, 0).isPlayablePerimeter = true;
            template.GetNode(row, m_mapSizeX - 1).isPlayablePerimeter = true;
        }

        for (int col = 0; col < m_mapSizeX; ++col)
        {
            template.GetNode(0, col).isPlayablePerimeter = true;
            template.GetNode(m_mapSizeY - 1, col).isPlayablePerimeter = true;
        }


        // ADD LAMPS
        // Even on left side
        for (int i = 0; i < leftWall.Count; ++i)
        {
            if (i % 4 == 0)
            {
                MapTemplate.WallCoord walCoord     = leftWall[i];
                NodeTemplate          nodeTemplate = template.GetNode(walCoord.coord.y, walCoord.coord.x);

                NodeTemplate.Wall wall = walCoord.wall;
                //nodeTemplate.hasWall[(int)wall] = false;

                nodeTemplate.hasLamp[(int)wall] = true;
            }
        }

        // Off on right side
        for (int i = 0; i < rightWall.Count; ++i)
        {
            if ((i + 2) % 4 == 0)
            {
                MapTemplate.WallCoord walCoord     = rightWall[i];
                NodeTemplate          nodeTemplate = template.GetNode(walCoord.coord.y, walCoord.coord.x);

                NodeTemplate.Wall wall = walCoord.wall;
                //nodeTemplate.hasWall[(int)wall] = false;

                nodeTemplate.hasLamp[(((int)wall) % 4)] = true;
            }
        }


        template.SetLeftWall(leftWall);
        template.SetRightWall(rightWall);
        template.SetPathSegments(pathSegments);
    }