using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.CompilerServices;

namespace System.Reactive
{
	[Serializable]
	public struct Timestamped<T> : IEquatable<Timestamped<T>>
	{
		public Timestamped(T value, DateTimeOffset timestamp)
		{
			this.Timestamp = timestamp;
			this.Value = value;
		}

		public T Value
		{
			[IsReadOnlyAttribute{5A691055-D045-4E5A-854F-8B26A5346F0C}]
			get;
		}

		public DateTimeOffset Timestamp
		{
			[IsReadOnlyAttribute{5A691055-D045-4E5A-854F-8B26A5346F0C}]
			get;
		}

		public bool Equals(Timestamped<T> other)
		{
			return other.Timestamp.Equals(this.Timestamp) && EqualityComparer<T>.Default.Equals(this.Value, other.Value);
		}

		public static bool operator ==(Timestamped<T> first, Timestamped<T> second)
		{
			return first.Equals(second);
		}

		public static bool operator !=(Timestamped<T> first, Timestamped<T> second)
		{
			return !first.Equals(second);
		}

		public override bool Equals(object obj)
		{
			if (!(obj is Timestamped<T>))
			{
				return false;
			}
			Timestamped<T> timestamped = (Timestamped<T>)obj;
			return this.Equals(timestamped);
		}

		public override int GetHashCode()
		{
			int hashCode = this.Timestamp.GetHashCode();
			T value = this.Value;
			return hashCode ^ ((value != null) ? value.GetHashCode() : 1979);
		}

		public override string ToString()
		{
			return string.Format(CultureInfo.CurrentCulture, "{0}@{1}", this.Value, this.Timestamp);
		}
	}
}
