// Update is called once per frame

    public void Update()
    {
        if (group && group.goals == null)
        {
            group = null;
            goal  = null;
        }



        if (!paused)
        {
            if (GridManagerScript.enableCollisions && avatar.GetComponent <Trigger>().stop)
            {
                return;
            }
            //sanity check
            if (nextNode == null || currentNode == null || currentNode.FindEdgeTo(nextNode) == null)
            {
                return;
            }

            //update a the path when end is closed
            if (GridManagerScript.usingAStarOnly &&
                (AStarPath.Count == 0 || (entering && !AStarPath.Last().goal)))
            {
                Debug.Log("NewPath " + AStarPath.Last());
                indexAtAstarPath = 0;
                AStarPath        = GridManagerScript.AStar.
                                   GenerateEntryPath(currentNode, group != null? group.goals.ToArray() : null);
                nextNode = GetBestDiffusionNode(currentNode);
            }

            if (!GridManagerScript.isTest)
            {
                float speedLimit = GridManagerScript.citySpeed;
                //get the edge speed and calculate speed limit if it exist, else assume no difference
                //calc traffic
                EdgeScript edge = currentNode.FindEdgeTo(nextNode);
                if (currentNode != null && edge != null)
                {
                    //speed in miles per hour
                    //0.0003miles/s = 0.066p/second per second (fs - fake seconds)
                    speedLimit = edge.GetSpeed();
                    //GET THIS CHECKED OUT
                    // speedLimit = speedLimit - speedLimit * (edge.nodesTraffic / EdgeScript.maxTraffic) * EdgeScript.maxTrafficP;
                }
                if (GridManagerScript.accelerationCalculations)
                {
                    //if the next node is the parking node and avatar has some speed0 slow down
                    if (nextNode.openParking && (nextNode.NodeStatus == NodeScript.NODE_STATUS.END && atmSpeed >= (speedLimit * parkingSpeed)))
                    {
                        atmSpeed -= atmSpeed * (decceleration * 2);
                    }

                    //else accelerate// decelerate
                    else
                    {
                        //calc deceleration
                        //if above speed limit or
                        if (atmSpeed > speedLimit)
                        {
                            atmSpeed -= atmSpeed * decceleration;
                        }
                        //calc acceleration
                        else if (atmSpeed < speedLimit)
                        {
                            acceleration = acceleration * accelerationSteepness;
                            atmSpeed    += atmSpeed * acceleration;
                            if (atmSpeed > speedLimit)
                            {
                                atmSpeed = speedLimit;                        //skip coming into calculations for dec or acc next time
                            }
                        }
                    }
                    speedLimit = atmSpeed;
                }
                //foreach frame translate
                //checkout 123 for explanation
                //1 mile irl = 240p in game
                //add about 20p to make up for inconsistency of time.deltatime
                //every update calc how much of a second has passed in game and add it on the speed

                float speedinpixels     = (speedLimit * 260) / 3600; //mile/h
                float translatePerFrame = speedinpixels * GridManagerScript.secondsPerSecond * Time.deltaTime;

                Vector3 translateAvatar = avatar.transform.position + (nextNode.transform.position - avatar.transform.position).normalized * translatePerFrame; //vector to translate by

                //get the distance between avatar and goal and see if you're overshooting
                //if you're not overshooting just continue
                //if you are overshooting just arrive
                //Db (distance before) is hypothenos from origin to goal (basic distance)
                //Da (distance after) is the hypothenos from origin to the potential new destination (towards goal)
                float Db = Vector3.Distance(avatar.transform.position, nextNode.transform.position);
                float Da = Vector3.Distance(avatar.transform.position, translateAvatar);

                if (Da > Db)
                {
                    avatar.transform.position = nextNode.transform.position;
                }
                else
                {
                    avatar.transform.position = translateAvatar;
                }
            }
            else
            {
                avatar.transform.position = avatar.transform.position + (nextNode.transform.position - avatar.transform.position).normalized;
            }

            // Check if the avatar is within the bounds of the next node's centre
            if (avatar.transform.position.x >= nextNode.transform.position.x - 1.0f &&
                avatar.transform.position.y >= nextNode.transform.position.y - 1.0f &&
                avatar.transform.position.z >= nextNode.transform.position.z - 1.0f &&
                avatar.transform.position.x <= nextNode.transform.position.x + 1.0f &&
                avatar.transform.position.y <= nextNode.transform.position.y + 1.0f &&
                avatar.transform.position.z <= nextNode.transform.position.z + 1.0f)
            {
                double timeOfDay = getTimeOfDay();

                currentNode.FindEdgeTo(nextNode).removeOccupancy(timeOfDay);
                // If not at the destination
                //TODO REWRITE THIS CHECK AND THE ONES BELOW
                //if no specific goal any goals count
                //if specific goal, all goals count
                if ((goal == null && ((nextNode.NodeStatus != NodeScript.NODE_STATUS.END && !isCityAvatar) ||
                                      (!nextNode.goal && isCityAvatar && entering) || (!nextNode.exit && isCityAvatar && !entering))) ||
                    (goal != null && goal != nextNode))
                {
                    //set the previous node to the current node
                    previousNode = currentNode;
                    // Set the current node as the next node
                    currentNode = nextNode;
                    // Calculate the next node
                    if (entering)
                    {
                        nextNode = GetBestDiffusionNode(nextNode);
                    }
                    else
                    {
                        nextNode = GetBestExitDiffusionNode(nextNode);
                    }
                    currentNode.FindEdgeTo(nextNode).addOccupancy(timeOfDay);
                    totalPathLength += currentNode.FindEdgeTo(nextNode).roadLen;
                }
                else
                {
                    // check if destination reached is in goals
                    //if goal is not specified arrive at any of the goals
                    //if goal is specified only  arrive at the given goal
                    //only arrive at redir goal
                    if ((goal == null && (group == null || group.goals == null || (group.goals.Contains(nextNode) || (redirected && group.redirectToGoals.Contains(nextNode))) || !entering)) ||
                        (goal == nextNode))
                    {
                        //reset the overlapping avatars on the node behind you
                        //if(GridManagerScript.isTest) currentNode.avatarsOverlapping = -1;
                        // If your destination was a parking lot add a car to the lot
                        if ((entering && nextNode.goal && nextNode.GetComponentInParent <ParkingLot>() || goal == nextNode))
                        {
                            timeArrived = (float)timeOfDay; //get the current time
                            timeLeftArrivedVTCAll.Add(new Tuple <float, float, float>(timeLeft, timeArrived, totalPathLength));
                            nextNode.GetComponentInParent <ParkingLot>().AddCar(this);
                            endReached = true;
                        }
                        else if (!entering)
                        {
                            endReached = true;
                        }
                    }

                    //go to the actual goal
                    else
                    {
                        //set the previous node to the current node
                        previousNode = currentNode;
                        // Set the current node as the next node
                        currentNode = nextNode;

                        // Calculate the next node
                        //passes current end that is not it's own goal
                        nextNode = GetBestDiffusionNode(nextNode);
                        currentNode.FindEdgeTo(nextNode).addOccupancy(timeOfDay);
                        totalPathLength += currentNode.FindEdgeTo(nextNode).roadLen;
                    }
                }
            }
        }
    }