#region --- License ---
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
* See license.txt for license info
*/
#endregion
using System;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Text;
namespace Bind.Structures
{
///
/// Represents an opengl constant in C# format. Both the constant name and value
/// can be retrieved or set. The value can be either a number, another constant
/// or an alias to a constant
///
class Constant : IComparable
{
#region PreviousName
string original_name;
// Gets the name prior to translation.
public string OriginalName
{
get { return original_name; }
private set { original_name = value; }
}
#endregion
#region public string Name
string _name;
///
/// Gets or sets the name of the opengl constant (eg. GL_LINES).
/// Undergoes processing unless the Settings.Legacy.NoAdvancedEnumProcessing flag is set.
///
public string Name
{
get { return _name; }
set
{
if (String.IsNullOrEmpty(value))
throw new ArgumentNullException("value");
if (OriginalName == null)
OriginalName = _name;
_name = value;
}
}
#endregion
#region public string Value
string _value;
///
/// Gets or sets the value of the opengl constant (eg. 0x00000001).
///
public string Value
{
get
{
return _value;
}
set
{
if (String.IsNullOrEmpty(value))
throw new ArgumentNullException("value");
_value = value;
}
}
#endregion
#region public string Reference
string _reference;
///
/// Gets or sets a string indicating the OpenGL enum reference by this constant.
/// Can be null.
///
public string Reference
{
get { return _reference; }
set
{
_reference = value;
}
}
#endregion
#region public bool Unchecked
public bool Unchecked
{
get
{
// Check if the value is a number larger than Int32.MaxValue.
ulong number;
string test = Value;
return UInt64.TryParse(test.ToLower().Replace("0x", String.Empty),
NumberStyles.AllowHexSpecifier, null, out number) &&
number > Int32.MaxValue;
}
}
#endregion
#region Constructors
///
/// Creates an empty Constant.
///
public Constant()
{
}
///
/// Creates a Constant with the given name and value.
///
/// The Name of the Constant.
/// The Type of the Constant.
public Constant(string name, string value)
{
Name = name;
Value = value;
}
#endregion
///
/// Replces the Value of the given constant with the value referenced by the [c.Reference, c.Value] pair.
///
/// The Constant to translate
/// The list of enums to check.
/// The list of auxilliary enums to check.
/// True if the reference was found; false otherwise.
public static bool TranslateConstantWithReference(Constant c, EnumCollection enums)
{
if (c == null)
throw new ArgumentNullException("c");
if (enums == null)
throw new ArgumentNullException("enums");
if (!String.IsNullOrEmpty(c.Reference))
{
// Resolve the referenced Constant. Be careful
// to avoid loops in the definitions.
Constant reference = c;
do
{
reference =
enums.ContainsKey(reference.Reference) &&
enums[reference.Reference].ConstantCollection.ContainsKey(reference.Value) ?
enums[reference.Reference].ConstantCollection[reference.Value] : null;
} while (reference != null && reference.Reference != null && reference.Reference != c.Reference);
// If we haven't managed to locate the reference, do
// a brute-force search through all enums.
if (reference == null || reference.Reference != null)
{
reference = enums.Values.Select(e =>
e.ConstantCollection.Values.FirstOrDefault(t =>
t.Reference == null && t.Name == c.Name))
.FirstOrDefault(t => t != null);
}
// Resolve the value for this Constant
if (reference != null)
{
c.Value = reference.Value;
c.Reference = null;
return true;
}
else
{
Trace.WriteLine(String.Format("[Warning] Failed to resolve token: {0}", c));
return false;
}
}
return true;
}
#region ToString
public override string ToString()
{
return
String.Format("{0} = {1}((int){2}{3})",
Name,
Unchecked ? "unchecked" : String.Empty,
!String.IsNullOrEmpty(Reference) ? Reference + "." : String.Empty,
Value);
}
#endregion
#region IComparable Members
public int CompareTo(Constant other)
{
int ret = Value.CompareTo(other.Value);
if (ret == 0)
return Name.CompareTo(other.Name);
return ret;
}
#endregion
}
}