/// <summary>
 /// Sets the callback information for this schedule.
 /// </summary>
 /// <param name="methodToCall">The delegate to trigger.</param>
 /// <param name="dataToSend">Data to pass.</param>
 public CallbackInformation(ScheduledEventDelegate methodToCall, object dataToSend)
 {
     MethodToCall = methodToCall;
     DataToSend = dataToSend;
     EventId = 0;
 }
        /// <summary>
        /// Schedule a method to execute at a specific time.
        /// </summary>
        /// <param name="deltaTime">The amount of time in milliseconds into the future you wish this method to be invoked.
        /// The actual game-time may be slightly later than when you specify (but never earlier).
        /// <para>Value must be greater than zero.</para></param>
        /// <param name="methodToCall">The method you wish to invoke.</param>
        /// <param name="dataToSend">Any object, this will be sent to the specified method in the SecheduleEventArguments.</param>
        public int Schedule(int deltaTime, ScheduledEventDelegate methodToCall, object dataToSend)
        {
            Assert.Fatal(deltaTime >= 0, "Time can't go backwards");
            int targetTime = _currentTime + deltaTime;
            CallbackInformation toSchedule = new CallbackInformation(methodToCall, dataToSend);
            toSchedule.EventId = ++_nextEventId;

            LinkedListNode<KeyValuePair<int, CallbackInformation>> currentNode = this._scheduledEvents.First;

            while (currentNode != null)
            {
                if (currentNode.Value.Key == targetTime)
                {
                    currentNode.List.AddAfter(currentNode, new KeyValuePair<int, CallbackInformation>(targetTime, toSchedule));

                    return toSchedule.EventId;
                }
                if (currentNode.Value.Key > targetTime)
                {
                    currentNode.List.AddBefore(currentNode, new KeyValuePair<int, CallbackInformation>(targetTime, toSchedule));
                    return toSchedule.EventId;
                }
                currentNode = currentNode.Next;
            }
            this._scheduledEvents.AddLast(new KeyValuePair<int, CallbackInformation>(targetTime, toSchedule));

            return toSchedule.EventId;
        }
 /// <summary>
 /// Schedule a method to execute at a specific time.
 /// </summary>
 /// <param name="deltaTime">The amount of time in milliseconds into the future you wish this method to be invoked.
 /// The actual game-time may be slightly later than when you specify (but never earlier).
 /// <para>Value must be greater than zero.</para></param>
 /// <param name="methodToCall">The method you wish to invoke.</param>
 public int Schedule(int deltaTime, ScheduledEventDelegate methodToCall)
 {
     return this.Schedule(deltaTime, methodToCall, null);
 }
        /// <summary>
        /// Remove a scheduled method at a specific time.
        /// <para>If the same method has multiple schedules for the same time, the first occurance is removed. (call this multiple times to remove multiple occurances)</para>
        /// </summary>
        /// <returns>false if unable to remove a scheduled method (due to it not existing at the time given)</returns>
        public bool Remove(int time, ScheduledEventDelegate methodToCall)
        {
            LinkedListNode<KeyValuePair<int, CallbackInformation>> currentNode = this._scheduledEvents.First;

            while (currentNode != null)
            {
                if (currentNode.Value.Key < time)
                {
                    currentNode = currentNode.Next;
                    continue;
                }
                if (currentNode.Value.Key > time)
                    return false;

                CallbackInformation methodInfo = currentNode.Value.Value;

                if (methodToCall.Equals(methodInfo.MethodToCall))
                {
                    LinkedListNode<KeyValuePair<int, CallbackInformation>> toRemove = currentNode;
                    currentNode = currentNode.Next;
                    this._scheduledEvents.Remove(toRemove);
                    return true;
                }
                else
                    currentNode = currentNode.Next;
            }

            return false;
        }