using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace FormulaEditor
{
    /// <summary>
    /// Acceptor of inequality opreation
    /// </summary>
    public class EqualityAcceptor : IBinaryAcceptor
    {
        /// <summary>
        /// The singleton
        /// </summary>
        public static readonly EqualityAcceptor Object = new EqualityAcceptor();

        /// <summary>
        /// Constructor
        /// </summary>
        private EqualityAcceptor()
        {
        }

        /// <summary>
        /// Accepts operation
        /// </summary>
        /// <param name="typeA">Type of left part</param>
        /// <param name="typeB">Type of right part</param>
        /// <returns>Accepted operation</returns>
        public IObjectOperation Accept(object typeA, object typeB)
        {
            if ((typeA is object[]) & (typeB is object[]))
            {
                object[] oa = typeA as object[];
                object[] ob = typeB as object[];
                Type tA = oa[0].GetType();
                Type tB = ob[0].GetType();
                string pA = oa[1] as string;
                string pB = ob[1] as string;
                PropertyInfo iA = tA.GetProperty(pA);
                PropertyInfo iB = tB.GetProperty(pB);
                if (iA.GetValue(oa[0], null).GetType() == iA.GetValue(ob[0], null).GetType())
                {
                    return EqualityOperation.Object;
                }
            }
            if ((typeA is object[]))
            {
                object[] oa = typeA as object[];
                Type tA = oa[0].GetType();
                string pA = oa[1] as string;
                PropertyInfo iA = tA.GetProperty(pA);
                if (iA.GetValue(oa[0], null).GetType() == typeB.GetType())
                {
                    return EqualityOperation.Object;
                }
            }
            if ((typeB is object[]))
            {
                object[] ob = typeB as object[];
                Type tB = ob[0].GetType();
                string pB = ob[1] as string;
                PropertyInfo iB = tB.GetProperty(pB);
                if (iB.GetValue(ob[0], null).GetType() == typeA.GetType())
                {
                    return EqualityOperation.Object;
                }
            }
            if (!typeA.Equals(typeB))
            {
                throw new Exception("Different types in equality");
            }
            return EqualityOperation.Object;
        }
    }
}
