using System;
using System.Configuration;
using skyscraper5.Dvb;
using skyscraper5.Skyscraper;

namespace skyscraper5.Mpeg2
{
    public abstract class TsDescriptor : Validatable
    {
	    public virtual byte GetDescriptorId()
	    {
		    Type type = this.GetType();
		    object[] customAttributes = type.GetCustomAttributes(false);
		    foreach (object customAttribute in customAttributes)
		    {
			    string name = customAttribute.GetType().Name;
			    switch (name)
			    {
					case "NullableContextAttribute": continue;
					case "NullableAttribute": continue;
					case "SkyscraperPluginAttribute": continue;
					case "UserDefinedDescriptorAttribute":
						UserDefinedDescriptorAttribute udda = (UserDefinedDescriptorAttribute)customAttribute;
						return udda.DescriptorId;
					case "TsDescriptorAttribute":
						TsDescriptorAttribute tda = (TsDescriptorAttribute)customAttribute;
						return tda.DescriptorId;
					default:
					    throw new NotImplementedException(name);
			    }
		    }
		    throw new NotImplementedException(String.Format("{0} does not reveal it's Descriptor ID"));
	    }

	    public virtual byte[] Serialize()
	    {
		    throw new NotImplementedException(String.Format("{0} does not implement Serialize()", this.GetType().Name));
	    }

		public virtual int GetDescriptorHashCode()
		{
			string err = String.Format("{0} does not reveal a custom hash code.", this.GetType().Name);
			throw new NotImplementedException(err);
		}

		/// <summary>
		/// Tests if a descriptor is FUNCTIONALLY equivalent with another descriptor.
		/// </summary>
		/// <param name="thatDescriptorId">The other TS Descriptor to compare against</param>
		/// <returns></returns>
		/// <exception cref="NotImplementedException">Is thrown when a descriptor does not implement this method.</exception>
		public virtual bool DescriptorEquals(TsDescriptor thatDescriptor)
		{
			string err = String.Format("{0} does not know wheter it is functionally equivalent to {1}.", this.GetType().Name, thatDescriptor.GetType().Name);
			throw new NotImplementedException(err);
		}
	}
}
