using Newtonsoft.Json;
using RhythmBase.Converters;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
namespace RhythmBase.Components
{
///
/// A size whose horizontal and vertical coordinates are nullable
///
[JsonConverter(typeof(RDPointsConverter))]
[DebuggerDisplay($"{{{nameof(GetDebuggerDisplay)}(),nq}}")]
public struct RDSizeE(RDExpression? width, RDExpression? height) :
IRDVortex,
IRDVortex,
IRDVortex
{
///
/// Initializes a new instance of the struct with specified width and height as floats.
///
/// The width as a float.
/// The height as a float.
public RDSizeE(float width, float height) : this((RDExpression)width, (RDExpression)height) { }
///
/// Initializes a new instance of the struct with specified width as an RDExpression and height as a float.
///
/// The width as an RDExpression.
/// The height as a float.
public RDSizeE(RDExpression? width, float height) : this(width, (RDExpression)height) { }
///
/// Initializes a new instance of the struct with specified width as a float and height as an RDExpression.
///
/// The width as a float.
/// The height as an RDExpression.
public RDSizeE(float width, RDExpression? height) : this((RDExpression)width, height) { }
///
/// Initializes a new instance of the struct with specified width as a string and height as a float.
///
/// The width as a string.
/// The height as a float.
public RDSizeE(string width, float height) : this((RDExpression)width, (RDExpression)height) { }
///
/// Initializes a new instance of the struct with specified width as a float and height as a string.
///
/// The width as a float.
/// The height as a string.
public RDSizeE(float width, string height) : this((RDExpression)width, (RDExpression)height) { }
///
/// Initializes a new instance of the struct with specified width and height as strings.
///
/// The width as a string.
/// The height as a string.
public RDSizeE(string width, string height) : this((RDExpression)width, (RDExpression)height) { }
///
/// Initializes a new instance of the struct with specified width as a string and height as an RDExpression.
///
/// The width as a string.
/// The height as an RDExpression.
public RDSizeE(string width, RDExpression? height) : this((RDExpression)width, height) { }
///
/// Initializes a new instance of the struct with specified width as an RDExpression and height as a string.
///
/// The width as an RDExpression.
/// The height as a string.
public RDSizeE(RDExpression? width, string height) : this(width, (RDExpression)height) { }
///
/// Initializes a new instance of the struct from an instance.
///
/// The instance.
public RDSizeE(RDSizeI p) : this((RDExpression?)p.Width, (RDExpression?)p.Height) { }
///
/// Initializes a new instance of the struct from an instance.
///
/// The instance.
public RDSizeE(RDSize p) : this((RDExpression?)p.Width, (RDExpression?)p.Height) { }
///
/// Initializes a new instance of the struct from an instance.
///
/// The instance.
public RDSizeE(RDPointI p) : this((RDExpression?)p.X, (RDExpression?)p.Y) { }
///
/// Initializes a new instance of the struct from an instance.
///
/// The instance.
public RDSizeE(RDPoint p) : this((RDExpression?)p.X, (RDExpression?)p.Y) { }
///
/// Initializes a new instance of the struct from an instance.
///
/// The instance.
public RDSizeE(RDPointE p) : this(p.X, p.Y) { }
///
/// Gets a value indicating whether this instance is empty.
///
public readonly bool IsEmpty => Width == null && Height == null;
///
/// Gets or sets the width.
///
public RDExpression? Width { get; set; } = width;
///
/// Gets or sets the height.
///
public RDExpression? Height { get; set; } = height;
///
/// Gets the area of the size.
///
public readonly RDExpression? Area => Width * Height;
///
/// Adds two instances and returns the result.
///
/// The first instance.
/// The second instance.
/// The result of the addition.
public static RDSizeE Add(RDSizeE sz1, RDSize sz2) => new(sz1.Width + sz2.Width, sz1.Height + sz2.Height);
///
/// Adds two instances and returns the result.
///
/// The first instance.
/// The second instance.
/// The result of the addition.
public static RDSizeE Add(RDSizeE sz1, RDSizeE sz2) => new(sz1.Width + sz2.Width, sz1.Height + sz2.Height);
///
/// Subtracts one instance from another instance and returns the result.
///
/// The first instance.
/// The second instance.
/// The result of the subtraction.
public static RDSizeE Subtract(RDSizeE sz1, RDSize sz2) => new(sz1.Width - sz2.Width, sz1.Height - sz2.Height);
///
/// Subtracts one instance from another instance and returns the result.
///
/// The first instance.
/// The second instance.
/// The result of the subtraction.
public static RDSizeE Subtract(RDSizeE sz1, RDSizeE sz2) => new(sz1.Width - sz2.Width, sz1.Height - sz2.Height);
///
public override readonly int GetHashCode() => HashCode.Combine(Width, Height);
///
public override readonly string ToString() => $"[{Width},{Height}]";
///
public readonly bool Equals(RDSizeE other) => Width == other.Width && Height == other.Height;
///
public readonly RDPointE ToRDPointE() => new(Width, Height);
///
public override readonly bool Equals([NotNullWhen(true)] object? obj) => obj is RDSize e && Equals(e);
///
public static RDSizeE operator +(RDSizeE sz1, RDSizeI sz2) => Add(sz1, sz2);
///
public static RDSizeE operator +(RDSizeE sz1, RDSize sz2) => Add(sz1, sz2);
///
public static RDSizeE operator +(RDSizeE sz1, RDSizeE sz2) => Add(sz1, sz2);
///
public static RDSizeE operator -(RDSizeE sz1, RDSizeI sz2) => Subtract(sz1, sz2);
///
public static RDSizeE operator -(RDSizeE sz1, RDSize sz2) => Subtract(sz1, sz2);
///
public static RDSizeE operator -(RDSizeE sz1, RDSizeE sz2) => Subtract(sz1, sz2);
///
public static RDSizeE operator *(int left, RDSizeE right) => new(left * right.Width, left * right.Height);
///
public static RDSizeE operator *(RDSizeE left, int right) => new(left.Width * right, left.Height * right);
///
public static RDSizeE operator *(float left, RDSizeE right) => new(left * right.Width, left * right.Height);
///
public static RDSizeE operator *(RDSizeE left, float right) => new(left.Width * right, left.Height * right);
///
public static RDSizeE operator *(RDExpression left, RDSizeE right) => new(left * right.Width, left * right.Height);
///
public static RDSizeE operator *(RDSizeE left, RDExpression right) => new(left.Width * right, left.Height * right);
///
public static RDSizeE operator /(RDSizeE left, float right) => new(left.Width / right, left.Height / right);
///
public static RDSizeE operator /(RDSizeE left, RDExpression right) => new(left.Width / right, left.Height / right);
///
public static bool operator ==(RDSizeE sz1, RDSizeE sz2) => sz1.Equals(sz2);
///
public static bool operator !=(RDSizeE sz1, RDSizeE sz2) => !sz1.Equals(sz2);
///
/// Converts an instance to an instance explicitly.
///
/// The instance to convert.
/// An instance with the same width and height as the instance.
public static explicit operator RDPointE(RDSizeE size) => new(size.Width, size.Height);
private readonly string GetDebuggerDisplay() => ToString();
}
}