// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using System;
using System.Collections.Generic;
using System.Globalization;
namespace System.Windows.Controls.DataVisualization
{
///
/// A range of values.
///
/// The type of the values.
/// Preview
public struct Range
where T : IComparable
{
///
/// A flag that determines whether the range is empty or not.
///
private bool _hasData;
///
/// Gets a value indicating whether the range is empty or not.
///
public bool HasData
{
get
{
return _hasData;
}
}
///
/// The maximum value in the range.
///
private T _maximum;
///
/// Gets the maximum value in the range.
///
public T Maximum
{
get
{
if (!HasData)
{
throw new InvalidOperationException(Properties.Resources.Range_get_Maximum_CannotReadTheMaximumOfAnEmptyRange);
}
return _maximum;
}
}
///
/// The minimum value in the range.
///
private T _minimum;
///
/// Gets the minimum value in the range.
///
public T Minimum
{
get
{
if (!HasData)
{
throw new InvalidOperationException(Properties.Resources.Range_get_Minimum_CannotReadTheMinimumOfAnEmptyRange);
}
return _minimum;
}
}
///
/// Initializes a new instance of the Range class.
///
/// The minimum value.
/// The maximum value.
public Range(T minimum, T maximum)
{
if (minimum == null)
{
throw new ArgumentNullException("minimum");
}
if (maximum == null)
{
throw new ArgumentNullException("maximum");
}
_hasData = true;
_minimum = minimum;
_maximum = maximum;
int compareValue = ValueHelper.Compare(minimum, maximum);
if (compareValue == 1)
{
throw new InvalidOperationException(Properties.Resources.Range_ctor_MaximumValueMustBeLargerThanOrEqualToMinimumValue);
}
}
///
/// Compare two ranges and return a value indicating whether they are
/// equal.
///
/// Left-hand side range.
/// Right-hand side range.
/// A value indicating whether the ranges are equal.
public static bool operator ==(Range leftRange, Range rightRange)
{
if (!leftRange.HasData)
{
return !rightRange.HasData;
}
if (!rightRange.HasData)
{
return !leftRange.HasData;
}
return leftRange.Minimum.Equals(rightRange.Minimum) && leftRange.Maximum.Equals(rightRange.Maximum);
}
///
/// Compare two ranges and return a value indicating whether they are
/// not equal.
///
/// Left-hand side range.
/// Right-hand side range.
/// A value indicating whether the ranges are not equal.
///
public static bool operator !=(Range leftRange, Range rightRange)
{
return !(leftRange == rightRange);
}
///
/// Adds a range to the current range.
///
/// A range to add to the current range.
/// A new range that encompasses the instance range and the
/// range parameter.
public Range Add(Range range)
{
if (!this.HasData)
{
return range;
}
else if (!range.HasData)
{
return this;
}
T minimum = ValueHelper.Compare(this.Minimum, range.Minimum) == -1 ? this.Minimum : range.Minimum;
T maximum = ValueHelper.Compare(this.Maximum, range.Maximum) == 1 ? this.Maximum : range.Maximum;
return new Range(minimum, maximum);
}
///
/// Compares the range to another range.
///
/// A different range.
/// A value indicating whether the ranges are equal.
public bool Equals(Range range)
{
return this == range;
}
///
/// Compares the range to an object.
///
/// Another object.
/// A value indicating whether the other object is a range,
/// and if so, whether that range is equal to the instance range.
///
public override bool Equals(object obj)
{
Range range = (Range)obj;
if (range == null)
{
return false;
}
return this == range;
}
///
/// Returns a value indicating whether a value is within a range.
///
/// The value.
/// Whether the value is within the range.
public bool Contains(T value)
{
return ValueHelper.Compare(Minimum, value) <= 0 && ValueHelper.Compare(value, Maximum) <= 0;
}
///////
/////// Returns a new range that contains the value.
///////
/////// The value to extend the range to.
/////// The range which contains the value.
////public Range ExtendTo(T value)
////{
//// if (!HasData)
//// {
//// return new Range(value, value);
//// }
//// if (ValueHelper.Compare(Minimum, value) > 0)
//// {
//// return new Range(value, Maximum);
//// }
//// else if (ValueHelper.Compare(Maximum, value) < 0)
//// {
//// return new Range(Minimum, value);
//// }
//// return this;
////}
///
/// Returns a value indicating whether two ranges intersect.
///
/// The range to compare against this range.
/// A value indicating whether the ranges intersect.
public bool IntersectsWith(Range range)
{
if (!this.HasData || !range.HasData)
{
return false;
}
Func, Range, bool> rightCollidesWithLeft =
(leftRange, rightRange) =>
(ValueHelper.Compare(rightRange.Minimum, leftRange.Maximum) <= 0 && ValueHelper.Compare(rightRange.Minimum, leftRange.Minimum) >= 0)
|| (ValueHelper.Compare(leftRange.Minimum, rightRange.Maximum) <= 0 && ValueHelper.Compare(leftRange.Minimum, rightRange.Minimum) >= 0);
return rightCollidesWithLeft(this, range) || rightCollidesWithLeft(range, this);
}
///
/// Computes a hash code value.
///
/// A hash code value.
public override int GetHashCode()
{
if (!HasData)
{
return 0;
}
int num = 0x5374e861;
num = (-1521134295 * num) + EqualityComparer.Default.GetHashCode(Minimum);
return ((-1521134295 * num) + EqualityComparer.Default.GetHashCode(Maximum));
}
///
/// Returns the string representation of the range.
///
/// The string representation of the range.
public override string ToString()
{
if (!this.HasData)
{
return Properties.Resources.Range_ToString_NoData;
}
else
{
return string.Format(CultureInfo.CurrentCulture, Properties.Resources.Range_ToString_Data, this.Minimum, this.Maximum);
}
}
}
}