#region COPYRIGHT
//
//     THIS IS GENERATED BY TEMPLATE
//     
//     AUTHOR  :     ROYE
//     DATE       :     2010
//
//     COPYRIGHT (C) 2010, TIANXIAHOTEL TECHNOLOGIES CO., LTD. ALL RIGHTS RESERVED.
//
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;

namespace System.Text.Template
{
    public class AssignmentExpression : BinaryExpression
    {
        public AssignmentExpression(Expression left, Expression right)
            : base(left, right)
        {
        }

        public override ValueExpression Evaluate(ITemplateContext context)
        {
            ValueExpression valueRight = Right.Evaluate(context);

            if (Left is VariableExpression)
            {
                if ((context.AssignmentPermissions & AssignmentPermissions.Variable) == AssignmentPermissions.None)
                    throw new IllegalAssignmentException("Assignment to variable not allowed");

                VariableExpression varExpr = (VariableExpression)Left;

                bool exists = context.ContainsKey(varExpr.Variable);

                if (exists && (context.AssignmentPermissions & AssignmentPermissions.ExistingVariable) == AssignmentPermissions.None)
                    throw new IllegalAssignmentException("Assignment to existing variable not allowed");

                if (!exists && (context.AssignmentPermissions & AssignmentPermissions.NewVariable) == AssignmentPermissions.None)
                    throw new IllegalAssignmentException("Assignment to new variable not allowed");

                context.Add(varExpr.Variable, new ValueTypePair(valueRight.Value, valueRight.Type));

                return valueRight;
            }

            if (Left is FieldExpression)
            {
                if ((context.AssignmentPermissions & AssignmentPermissions.Property) == AssignmentPermissions.None)
                    throw new IllegalAssignmentException("Assignment to property not allowed");

                return ((FieldExpression)Left).Assign(context, valueRight.Value);
            }

            throw new IllegalAssignmentException();
        }
    }

    public class IllegalAssignmentException : Exception
    {
        public IllegalAssignmentException(string message)
            : base(message)
        {
        }

        public IllegalAssignmentException()
        {
        }

        public IllegalAssignmentException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
        }

        public IllegalAssignmentException(string message, Exception innerException)
            : base(message, innerException)
        {
        }
    }
}
