using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
namespace MAX.Core.Helpers;
///
/// This is a generic parameters base class used for Dialog Parameters and Navigation Parameters.
///
public abstract class ParametersBase : IEnumerable>
{
private readonly List> _entries = [];
///
/// Default constructor.
///
protected ParametersBase()
{
}
///
/// Constructs a list of parameters.
///
/// Query string to be parsed.
protected ParametersBase(string query)
{
if (!string.IsNullOrWhiteSpace(query))
{
int num = query.Length;
for (int i = ((query.Length > 0) && (query[0] == '?')) ? 1 : 0; i < num; i++)
{
int startIndex = i;
int num4 = -1;
while (i < num)
{
char ch = query[i];
if (ch == '=')
{
if (num4 < 0)
{
num4 = i;
}
}
else if (ch == '&')
{
break;
}
i++;
}
string key = null;
string value;
if (num4 >= 0)
{
key = query.Substring(startIndex, num4 - startIndex);
value = query.Substring(num4 + 1, i - num4 - 1);
}
else
{
value = query.Substring(startIndex, i - startIndex);
}
if (key != null)
{
Add(Uri.UnescapeDataString(key), Uri.UnescapeDataString(value));
}
}
}
}
///
/// Searches Parameter collection and returns value if Collection contains key.
/// Otherwise returns null.
///
/// The key for the value to be returned.
/// The value of the parameter referenced by the key; otherwise null.
public object this[string key]
{
get
{
foreach (KeyValuePair entry in _entries)
{
if (string.Compare(entry.Key, key, StringComparison.Ordinal) == 0)
{
return entry.Value;
}
}
return null;
}
}
///
/// The count, or number, of parameters in collection.
///
public int Count => _entries.Count;
///
/// Returns an IEnumerable of the Keys in the collection.
///
public IEnumerable Keys =>
_entries.Select(x => x.Key);
///
/// Adds the key and value to the parameters collection.
///
/// The key to reference this value in the parameters collection.
/// The value of the parameter to store.
public void Add(string key, object value) =>
_entries.Add(new KeyValuePair(key, value));
public void Remove(string key)
{
_entries.RemoveAll(x => x.Key == key);
}
public void Update(string key, object value)
{
_entries.RemoveAll(x => x.Key == key);
Add(key, value);
}
///
/// Checks collection for presence of key.
///
/// The key to check in the collection.
/// true if key exists; else returns false.
public bool ContainsKey(string key)
{
return _entries.Any(x => string.Compare(x.Key, key, StringComparison.Ordinal) == 0);
}
///
/// Gets an enumerator for the KeyValuePairs in parameter collection.
///
/// Enumerator.
public IEnumerator> GetEnumerator() =>
_entries.GetEnumerator();
///
/// Returns the value of the member referenced by key.
///
/// The type of object to be returned.
/// The key for the value to be returned.
/// Returns a matching parameter of if one exists in the Collection.
public T GetValue(string key) =>
_entries.GetValue(key);
///
/// Returns an IEnumerable of all parameters.
///
/// The type for the values to be returned.
/// The key for the values to be returned.
///Returns a IEnumerable of all the instances of type .
public IEnumerable GetValues(string key) =>
_entries.GetValues(key);
///
/// Checks to see if the parameter collection contains the value.
///
/// The type for the values to be returned.
/// The key for the value to be returned.
/// Value of the returned parameter if it exists.
public bool TryGetValue(string key, out T value) =>
_entries.TryGetValue(key, out value);
IEnumerator IEnumerable.GetEnumerator() =>
GetEnumerator();
///
/// Converts parameter collection to a parameter string.
///
/// A string representation of the parameters.
public override string ToString()
{
StringBuilder queryBuilder = new();
if (_entries.Count > 0)
{
queryBuilder.Append('?');
bool first = true;
foreach (KeyValuePair kvp in _entries)
{
if (!first)
{
queryBuilder.Append('&');
}
else
{
first = false;
}
queryBuilder.Append(Uri.EscapeDataString(kvp.Key));
queryBuilder.Append('=');
queryBuilder.Append(Uri.EscapeDataString(kvp.Value != null ? kvp.Value.ToString() : ""));
}
}
return queryBuilder.ToString();
}
///
/// Adds a collection of parameters to the local parameter list.
///
/// An IEnumerable of KeyValuePairs to add to the current parameter list.
public void FromParameters(IEnumerable> parameters) =>
_entries.AddRange(parameters);
}
public static class ParametersExtensions
{
///
/// Searches for
///
/// The type of the parameter to return
/// A collection of parameters to search
/// The key of the parameter to find
/// A matching value of if it exists
[EditorBrowsable(EditorBrowsableState.Never)]
public static T GetValue(this IEnumerable> parameters, string key) =>
(T)GetValue(parameters, key, typeof(T));
///
/// Searches for value referenced by
///
/// A collection of parameters to search
/// The key of the parameter to find
/// The type of the parameter to return
/// A matching value of if it exists
/// Unable to convert the value of Type
[EditorBrowsable(EditorBrowsableState.Never)]
public static object GetValue(this IEnumerable> parameters, string key, Type type)
{
foreach (KeyValuePair kvp in parameters)
{
if (string.Compare(kvp.Key, key, StringComparison.Ordinal) == 0)
{
if (TryGetValueInternal(kvp, type, out object value))
{
return value;
}
throw new InvalidCastException($"Unable to convert the value of Type '{kvp.Value.GetType().FullName}' to '{type.FullName}' for the key '{key}' ");
}
}
return GetDefault(type);
}
///
/// Searches for value referenced by
///
/// The type of the parameter to return
/// A collection of parameters to search
/// The key of the parameter to find
/// The value of parameter to return
/// Success if value is found; otherwise returns false
[EditorBrowsable(EditorBrowsableState.Never)]
public static bool TryGetValue(this IEnumerable> parameters, string key, out T value)
{
Type type = typeof(T);
foreach (KeyValuePair kvp in parameters)
{
if (string.Compare(kvp.Key, key, StringComparison.Ordinal) == 0)
{
bool success = TryGetValueInternal(kvp, typeof(T), out object valueAsObject);
value = (T)valueAsObject;
return success;
}
}
value = default;
return false;
}
///
/// Searches for value referenced by
///
/// The type of the parameter to return
/// A collection of parameters to search
/// The key of the parameter to find
/// An IEnumerable{T} of all the values referenced by key
[EditorBrowsable(EditorBrowsableState.Never)]
public static IEnumerable GetValues(this IEnumerable> parameters, string key)
{
List values = [];
Type type = typeof(T);
foreach (KeyValuePair kvp in parameters)
{
if (string.Compare(kvp.Key, key, StringComparison.Ordinal) == 0)
{
TryGetValueInternal(kvp, type, out object value);
values.Add((T)value);
}
}
return values.AsEnumerable();
}
private static bool TryGetValueInternal(KeyValuePair kvp, Type type, out object value)
{
value = GetDefault(type);
bool success = false;
if (kvp.Value == null)
{
success = true;
}
else if (kvp.Value.GetType() == type)
{
success = true;
value = kvp.Value;
}
else if (type.IsAssignableFrom(kvp.Value.GetType()))
{
success = true;
value = kvp.Value;
}
else if (type.IsEnum)
{
string valueAsString = kvp.Value.ToString();
if (Enum.IsDefined(type, valueAsString))
{
success = true;
value = Enum.Parse(type, valueAsString);
}
else if (int.TryParse(valueAsString, out int numericValue))
{
success = true;
value = Enum.ToObject(type, numericValue);
}
}
if (!success && type.GetInterface("System.IConvertible") != null)
{
success = true;
value = System.Convert.ChangeType(kvp.Value, type);
}
return success;
}
///
/// Checks to see if key exists in parameter collection
///
/// IEnumerable to search
/// The key to search the for existence
/// true if key exists; false otherwise
[EditorBrowsable(EditorBrowsableState.Never)]
public static bool ContainsKey(this IEnumerable> parameters, string key) =>
parameters.Any(x => string.Compare(x.Key, key, StringComparison.Ordinal) == 0);
private static object GetDefault(Type type)
{
if (type.IsValueType)
{
return Activator.CreateInstance(type);
}
return null;
}
}