// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
using System.Globalization;
namespace Microsoft.Reactive.Testing
{
    /// 
    /// Records information about subscriptions to and unsubscriptions from observable sequences.
    /// 
#if !NO_DEBUGGER_ATTRIBUTES
    [DebuggerDisplay("({Subscribe}, {Unsubscribe})")]
#endif
#if !NO_SERIALIZABLE
    [Serializable]
#endif
    public struct Subscription : IEquatable
    {
        /// 
        /// Infinite virtual time value, used to indicate an unsubscription never took place.
        /// 
        public const long Infinite = long.MaxValue;
        private long _subscribe;
        private long _unsubscribe;
        /// 
        /// Gets the subscription virtual time.
        /// 
        public long Subscribe { get { return _subscribe; } }
        /// 
        /// Gets the unsubscription virtual time.
        /// 
        public long Unsubscribe { get { return _unsubscribe; } }
        /// 
        /// Creates a new subscription object with the given virtual subscription time.
        /// 
        /// Virtual time at which the subscription occurred.-
        public Subscription(long subscribe)
        {
            _subscribe = subscribe;
            _unsubscribe = Infinite;
        }
        /// 
        /// Creates a new subscription object with the given virtual subscription and unsubscription time.
        /// 
        /// Virtual time at which the subscription occurred.
        /// Virtual time at which the unsubscription occurred.
        public Subscription(long subscribe, long unsubscribe)
        {
            _subscribe = subscribe;
            _unsubscribe = unsubscribe;
        }
        /// 
        /// Checks whether the given subscription is equal to the current instance.
        /// 
        /// Subscription object to check for equality.
        /// true if both objects are equal; false otherwise.
        public bool Equals(Subscription other)
        {
            return Subscribe == other.Subscribe && Unsubscribe == other.Unsubscribe;
        }
        /// 
        /// Determines whether the two specified Subscription values have the same Subscribe and Unsubscribe.
        /// 
        /// The first Subscription value to compare.
        /// The second Subscription value to compare.
        /// true if the first Subscription value has the same Subscribe and Unsubscribe as the second Subscription value; otherwise, false.
        public static bool operator==(Subscription left, Subscription right)
        {
            return left.Equals(right);
        }
        /// 
        /// Determines whether the two specified Subscription values don't have the same Subscribe and Unsubscribe.
        /// 
        /// The first Subscription value to compare.
        /// The second Subscription value to compare.
        /// true if the first Subscription value has a different Subscribe or Unsubscribe as the second Subscription value; otherwise, false.
        public static bool operator !=(Subscription left, Subscription right)
        {
            return !left.Equals(right);
        }
        /// 
        /// Determines whether the specified System.Object is equal to the current Subscription value.
        /// 
        /// The System.Object to compare with the current Subscription value.
        /// true if the specified System.Object is equal to the current Subscription value; otherwise, false.
        public override bool Equals(object obj)
        {
            if (obj is Subscription)
                return Equals((Subscription)obj);
            return false;
        }
        /// 
        /// Returns the hash code for the current Subscription value.
        /// 
        /// A hash code for the current Subscription value.
        public override int GetHashCode()
        {
            return Subscribe.GetHashCode() ^ Unsubscribe.GetHashCode();
        }
        /// 
        /// Returns a string representation of the current Subscription value.
        /// 
        /// String representation of the current Subscription value.
        public override string ToString()
        {
            if (Unsubscribe == Infinite)
                return string.Format(CultureInfo.CurrentCulture, "({0}, Infinite)", Subscribe);
            else
                return string.Format(CultureInfo.CurrentCulture, "({0}, {1})", Subscribe, Unsubscribe);
        }
    }
}