using System;
using System.Globalization;
using System.Reflection;

namespace Cryville.Common {
	public class BinderAttribute : Attribute {
		public BinderAttribute(Type type) {
			BinderType = type;
		}
		
		public Type BinderType;

		public static Binder CreateBinderOfType(Type type) {
			var l = type.GetCustomAttributes(typeof(BinderAttribute), true);
			if (l.Length > 0) {
				return (Binder)ReflectionHelper.InvokeEmptyConstructor(
					((BinderAttribute)l[0]).BinderType
				);
			}
			return new EmptyBinder();
		}
	}
	
	public class EmptyBinder : Binder {
		public override FieldInfo BindToField(BindingFlags bindingAttr, FieldInfo[] match, object value, CultureInfo culture) {
			throw new NotImplementedException();
		}
		
		public override MethodBase BindToMethod(BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] names, out object state) {
			throw new NotImplementedException();
		}

		public override object ChangeType(object value, Type type, CultureInfo culture) {
			if (value == null)
				return null;
			else if (type == value.GetType())
				return value;
			else if (type.IsEnum && value is string) {
				return Enum.Parse(type, (string)value);
			}
			throw new InvalidCastException();
		}
		
		public override void ReorderArgumentArray(ref object[] args, object state) {
			throw new NotImplementedException();
		}
		
		public override MethodBase SelectMethod(BindingFlags bindingAttr, MethodBase[] match, Type[] types, ParameterModifier[] modifiers) {
			throw new NotImplementedException();
		}
		
		public override PropertyInfo SelectProperty(BindingFlags bindingAttr, PropertyInfo[] match, Type returnType, Type[] indexes, ParameterModifier[] modifiers) {
			throw new NotImplementedException();
		}
	}
}
