/*
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

package org.apache.royale.compiler.internal.codegen.js.jx;

import org.apache.royale.compiler.codegen.ISubEmitter;
import org.apache.royale.compiler.codegen.js.IJSEmitter;
import org.apache.royale.compiler.definitions.IDefinition;
import org.apache.royale.compiler.definitions.IFunctionDefinition;
import org.apache.royale.compiler.definitions.IFunctionDefinition.FunctionClassification;
import org.apache.royale.compiler.definitions.ITypeDefinition;
import org.apache.royale.compiler.definitions.IVariableDefinition;
import org.apache.royale.compiler.definitions.IVariableDefinition.VariableClassification;
import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
import org.apache.royale.compiler.internal.codegen.js.JSEmitterTokens;
import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter;
import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitter;
import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleEmitterTokens;
import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
import org.apache.royale.compiler.internal.definitions.AccessorDefinition;
import org.apache.royale.compiler.internal.definitions.AppliedVectorDefinition;
import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
import org.apache.royale.compiler.internal.semantics.SemanticUtils;
import org.apache.royale.compiler.internal.tree.as.*;
import org.apache.royale.compiler.tree.ASTNodeID;
import org.apache.royale.compiler.tree.as.IASNode;
import org.apache.royale.compiler.tree.as.IBinaryOperatorNode;
import org.apache.royale.compiler.tree.as.IClassNode;
import org.apache.royale.compiler.tree.as.IExpressionNode;
import org.apache.royale.compiler.tree.as.IIdentifierNode;
import org.apache.royale.compiler.utils.ASNodeUtils;

public class BinaryOperatorEmitter extends JSSubEmitter implements
        ISubEmitter<IBinaryOperatorNode>
{

    public BinaryOperatorEmitter(IJSEmitter emitter)
    {
        super(emitter);
    }

    @Override
    public void emit(IBinaryOperatorNode node)
    {
        // TODO (mschmalle) will remove this cast as more things get abstracted
        JSRoyaleEmitter fjs = (JSRoyaleEmitter) getEmitter();

        String op = node.getOperator().getOperatorText();
        boolean isAssignment = op.contains("=")
                && !op.contains("==")
                && !(op.startsWith("<") || op.startsWith(">") || op
                        .startsWith("!"));
        ASTNodeID id = node.getNodeID();
        /*
        if (id == ASTNodeID.Op_InID
                || id == ASTNodeID.Op_LogicalAndAssignID
                || id == ASTNodeID.Op_LogicalOrAssignID)
        {
            super.emitBinaryOperator(node);
        }
        else */if (id == ASTNodeID.Op_IsID || id == ASTNodeID.Op_AsID)
        {
            fjs.emitIsAs(node, node.getLeftOperandNode(), node.getRightOperandNode(),
                    id, false);
        }
        else if (id == ASTNodeID.Op_InstanceOfID)
        {
            getWalker().walk(node.getLeftOperandNode());

            startMapping(node, node.getLeftOperandNode());
            write(ASEmitterTokens.SPACE);
            writeToken(ASEmitterTokens.INSTANCEOF);
            endMapping(node);

            IDefinition dnode = (node.getRightOperandNode())
                    .resolve(getProject());
			if (dnode != null)
			{
				String dnodeQname = dnode.getQualifiedName();
                boolean isPackageOrFileMember = false;
                if (dnode instanceof IVariableDefinition)
                {
                    IVariableDefinition variable = (IVariableDefinition) dnode;
                    VariableClassification classification = variable.getVariableClassification();
                    if (classification == VariableClassification.PACKAGE_MEMBER ||
                            classification == VariableClassification.FILE_MEMBER)
                    {
                        isPackageOrFileMember = true;
                    }
                }
                else if (dnode instanceof IFunctionDefinition)
                {
                    IFunctionDefinition func = (IFunctionDefinition) dnode;
                    FunctionClassification classification = func.getFunctionClassification();
                    if (classification == FunctionClassification.PACKAGE_MEMBER ||
                            classification == FunctionClassification.FILE_MEMBER)
                    {
                        isPackageOrFileMember = true;
                    }
                }
				else if(dnode instanceof ITypeDefinition)
				{
					isPackageOrFileMember = true;
				}
				if(isPackageOrFileMember)
				{
					dnodeQname = getEmitter().formatQualifiedName(dnodeQname);
				}
                write(dnodeQname);
			}
			else
			{
				getWalker().walk(node.getRightOperandNode());
			}
        }
        else
        {
            IExpressionNode leftSide = node.getLeftOperandNode();
            IDefinition leftDef = leftSide.resolveType(getWalker().getProject());
            if (leftSide.getNodeID() == ASTNodeID.MemberAccessExpressionID)
            {
                IASNode lnode = leftSide.getChild(0);
                IASNode rnode = leftSide.getChild(1);
                IDefinition rnodeDef = (rnode instanceof IIdentifierNode) ?
                		((IIdentifierNode) rnode).resolve(getWalker().getProject()) :
                		null;
                boolean isDynamicAccess = rnode instanceof DynamicAccessNode;
                if (lnode.getNodeID() == ASTNodeID.SuperID
                        && rnodeDef instanceof AccessorDefinition)
                {
                    if (isAssignment)
                    {
                        IClassNode cnode = (IClassNode) node
                                .getAncestorOfType(IClassNode.class);
                        if (cnode != null)
                        	write(getEmitter().formatQualifiedName(
                                cnode.getQualifiedName()));
                        else
                        	write(getEmitter().formatQualifiedName(
                        		getModel().getCurrentClass().getQualifiedName()));
                        		
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(JSGoogEmitterTokens.SUPERCLASS);
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(JSRoyaleEmitterTokens.SETTER_PREFIX);
                        write(rnodeDef.getBaseName());
                        write(ASEmitterTokens.MEMBER_ACCESS);
                        write(JSEmitterTokens.APPLY);
                        write(ASEmitterTokens.PAREN_OPEN);
                        write(ASEmitterTokens.THIS);
                        writeToken(ASEmitterTokens.COMMA);
                        writeToken(ASEmitterTokens.SQUARE_OPEN);
                        if (op.length() > 1) // += and things like that
                        {
                            write(getEmitter().formatQualifiedName(
                                    cnode.getQualifiedName()));
                            write(ASEmitterTokens.MEMBER_ACCESS);
                            write(JSGoogEmitterTokens.SUPERCLASS);
                            write(ASEmitterTokens.MEMBER_ACCESS);
                            write(JSRoyaleEmitterTokens.GETTER_PREFIX);
                            write(rnodeDef.getBaseName());
                            write(ASEmitterTokens.MEMBER_ACCESS);
                            write(JSEmitterTokens.APPLY);
                            write(ASEmitterTokens.PAREN_OPEN);
                            write(ASEmitterTokens.THIS);
                            write(ASEmitterTokens.PAREN_CLOSE);
                            write(op.substring(0, 1));
                        }

                        getWalker().walk(node.getRightOperandNode());
                        writeToken(ASEmitterTokens.SQUARE_CLOSE);
                        write(ASEmitterTokens.PAREN_CLOSE);
                        return;
                    }
                }
                else if (((JSRoyaleEmitter)getEmitter()).isXMLList((MemberAccessExpressionNode)leftSide))
                {
                	MemberAccessExpressionNode xmlNode = (MemberAccessExpressionNode)leftSide;
                	if (node.getNodeID() == ASTNodeID.Op_AssignId)
                	{
	                    getWalker().walk(xmlNode.getLeftOperandNode());
	                    IExpressionNode rightSide = xmlNode.getRightOperandNode();
	                    if (rightSide instanceof UnaryOperatorAtNode)
	                    {
		                    write(".setAttribute('");
		                    getWalker().walk(((UnaryOperatorAtNode)rightSide).getChild(0));
	                    }
	                    else
	                    {
		                    write(".setChild('");
		                    getWalker().walk(rightSide);
	                    }
	                    write("', ");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                	else if (node.getNodeID() == ASTNodeID.Op_AddAssignID)
                	{
	                    getWalker().walk(xmlNode.getLeftOperandNode());
	                    IExpressionNode rightSide = xmlNode.getRightOperandNode();
	                    if (rightSide instanceof UnaryOperatorAtNode)
	                    {
		                    write(".setAttribute('");
		                    getWalker().walk(((UnaryOperatorAtNode)rightSide).getChild(0));
	                    }
	                    else
	                    {
		                    write(".setChild('");
		                    getWalker().walk(rightSide);
	                    }
	                    write("', ");
                        getWalker().walk(node.getLeftOperandNode());
	                    write(".plus(");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                	else if (node.getNodeID() == ASTNodeID.Op_AddID)
                	{
	                    getWalker().walk(xmlNode);
	                    write(".plus(");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                }
                else if (isDynamicAccess && ((JSRoyaleEmitter)getEmitter()).isXML((IExpressionNode)lnode))
                {
                	DynamicAccessNode dyn = (DynamicAccessNode)rnode;
                	ITypeDefinition type = dyn.getRightOperandNode().resolveType(getProject());
                	if (type.isInstanceOf("String", getProject()) || type.isInstanceOf("Object", getProject()))
        			{
                		String field;
                    	if (node.getNodeID() == ASTNodeID.Op_AssignId)
                    	{
    	                    getWalker().walk(lnode);
    	                    IExpressionNode dynLeft = dyn.getLeftOperandNode();
    	                    IExpressionNode dynRight = dyn.getRightOperandNode();
    	                    if (dynLeft instanceof UnaryOperatorAtNode)
    	                    {
    		                    write(".setAttribute(");
    							field = fjs.stringifyNode(dyn.getRightOperandNode());
    	                    }
    	                    else if (dynRight instanceof UnaryOperatorAtNode)
    	                    {
    		                    write(".setAttribute(");
    							field = fjs.stringifyNode(dynRight.getChild(0));
    	                    }
    	                    else
    	                    {
    		                    write(".setChild(");
    							field = fjs.stringifyNode(dynLeft);
    	                    }
    	                    write(field + ", ");
    	                    getWalker().walk(node.getRightOperandNode());
    	                    write(ASEmitterTokens.PAREN_CLOSE);
    	                    return;
                    	}
                    	else if (node.getNodeID() == ASTNodeID.Op_AddAssignID)
                    	{
    	                    getWalker().walk(lnode);
    	                    IExpressionNode rightSide = dyn.getRightOperandNode();
    	                    if (rightSide instanceof UnaryOperatorAtNode)
    	                    {
    		                    write(".setAttribute('");
    							field = fjs.stringifyNode(((UnaryOperatorAtNode)rightSide).getChild(0));
    							field = field.replace("\"", ""); // remove wrapping double-quotes
    	                    }
    	                    else
    	                    {
    		                    write(".setChild('");
    							field = fjs.stringifyNode(rightSide);
    							field = field.replace("\"", ""); // remove wrapping double-quotes
    	                    }
    	                    write(field + "', ");
                            getWalker().walk(node.getLeftOperandNode());
    	                    write(".plus(");
    	                    getWalker().walk(node.getRightOperandNode());
    	                    write(ASEmitterTokens.PAREN_CLOSE);
    	                    write(ASEmitterTokens.PAREN_CLOSE);
    	                    return;
                    	}
                    	else if (node.getNodeID() == ASTNodeID.Op_AddID)
                    	{
    	                    getWalker().walk(dyn);
    	                    write(".plus(");
    	                    getWalker().walk(node.getRightOperandNode());
    	                    write(ASEmitterTokens.PAREN_CLOSE);
    	                    return;
                    	}
        			}
                }
                else if (((JSRoyaleEmitter)getEmitter()).isProxy(((MemberAccessExpressionNode)leftSide).getLeftOperandNode()) && leftDef == null)
                {
                	MemberAccessExpressionNode proxyNode = (MemberAccessExpressionNode)leftSide;
                	if (node.getNodeID() == ASTNodeID.Op_AssignId)
                	{
	                    getWalker().walk(proxyNode.getLeftOperandNode());
	                    IExpressionNode rightSide = proxyNode.getRightOperandNode();
	                    write(".setProperty('");
	                    getWalker().walk(rightSide);
	                    write("', ");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                	else if (node.getNodeID() == ASTNodeID.Op_AddAssignID)
                	{
	                    IExpressionNode rightSide = proxyNode.getRightOperandNode();
	                    getWalker().walk(proxyNode.getLeftOperandNode());
	                    write(".setProperty('");
	                    getWalker().walk(rightSide);
	                    write("', ");
	                    getWalker().walk(proxyNode.getLeftOperandNode());
	                    write(".getProperty(");
	                    write(ASEmitterTokens.SINGLE_QUOTE);
	                    getWalker().walk(rightSide);
	                    write(ASEmitterTokens.SINGLE_QUOTE);
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    write(" + ");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                }
                else if (((JSRoyaleEmitter)getEmitter()).isDateProperty((MemberAccessExpressionNode)leftSide, true))
                {
                	specialCaseDate(node, (MemberAccessExpressionNode)leftSide);
                    return;
                }
            }
            else if (leftSide.getNodeID() == ASTNodeID.IdentifierID)
            {
    			if ((leftDef != null)
    				&& SemanticUtils.isXMLish(leftDef, getWalker().getProject()))
    			{
                	if (node.getNodeID() == ASTNodeID.Op_AddAssignID)
                	{
	                    getWalker().walk(leftSide);
	                    write(" = ");
	                    getWalker().walk(leftSide);
	                    write(".plus(");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                }
            }
            else if (leftSide.getNodeID() == ASTNodeID.ArrayIndexExpressionID) // dynamic access
            {
            	DynamicAccessNode dyn = (DynamicAccessNode)leftSide;
            	IExpressionNode dynLeft = dyn.getLeftOperandNode();
            	ITypeDefinition type = dyn.getRightOperandNode().resolveType(getProject());
            	if (((JSRoyaleEmitter)getEmitter()).isXML(dynLeft) && type.isInstanceOf("String", getProject()))
    			{
            		String field;
                	if (node.getNodeID() == ASTNodeID.Op_AssignId)
                	{
	                    getWalker().walk(dynLeft);
	                    IExpressionNode rightSide = dyn.getRightOperandNode();
	                    if (rightSide instanceof UnaryOperatorAtNode)
	                    {
		                    write(".setAttribute('");
							field = fjs.stringifyNode(((UnaryOperatorAtNode)rightSide).getChild(0));
							field = field.replace("\"", ""); // remove wrapping double-quotes
	                    }
	                    else
	                    {
		                    write(".setChild('");
							field = fjs.stringifyNode(rightSide);
							field = field.replace("\"", ""); // remove wrapping double-quotes
	                    }
	                    write(field + "', ");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                	else if (node.getNodeID() == ASTNodeID.Op_AddAssignID)
                	{
	                    getWalker().walk(dynLeft);
	                    IExpressionNode rightSide = dyn.getRightOperandNode();
	                    if (rightSide instanceof UnaryOperatorAtNode)
	                    {
		                    write(".setAttribute('");
							field = fjs.stringifyNode(((UnaryOperatorAtNode)rightSide).getChild(0));
							field = field.replace("\"", ""); // remove wrapping double-quotes
	                    }
	                    else
	                    {
		                    write(".setChild('");
							field = fjs.stringifyNode(rightSide);
							field = field.replace("\"", ""); // remove wrapping double-quotes
	                    }
	                    write(field + "', ");
                        getWalker().walk(node.getLeftOperandNode());
	                    write(".plus(");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}
                	else if (node.getNodeID() == ASTNodeID.Op_AddID)
                	{
	                    getWalker().walk(dyn);
	                    write(".plus(");
	                    getWalker().walk(node.getRightOperandNode());
	                    write(ASEmitterTokens.PAREN_CLOSE);
	                    return;
                	}

    			}
            }
		
			super_emitBinaryOperator(node, isAssignment);
        }
    }
    

    private void super_emitBinaryOperator(IBinaryOperatorNode node, boolean isAssignment)
    {
        if (ASNodeUtils.hasParenOpen(node))
            write(ASEmitterTokens.PAREN_OPEN);

        ASTNodeID id = node.getNodeID();

        if (id == ASTNodeID.Op_IsID)
        {
            write(ASEmitterTokens.IS);
            write(ASEmitterTokens.PAREN_OPEN);
            getWalker().walk(node.getLeftOperandNode());
            writeToken(ASEmitterTokens.COMMA);
            getWalker().walk(node.getRightOperandNode());
            write(ASEmitterTokens.PAREN_CLOSE);
        }
        else if (id == ASTNodeID.Op_AsID)
        {
            // (is(a, b) ? a : null)
            write(ASEmitterTokens.PAREN_OPEN);
            write(ASEmitterTokens.IS);
            write(ASEmitterTokens.PAREN_OPEN);
            getWalker().walk(node.getLeftOperandNode());
            writeToken(ASEmitterTokens.COMMA);
            getWalker().walk(node.getRightOperandNode());
            writeToken(ASEmitterTokens.PAREN_CLOSE);
            writeToken(ASEmitterTokens.TERNARY);
            getWalker().walk(node.getLeftOperandNode());
            write(ASEmitterTokens.SPACE);
            writeToken(ASEmitterTokens.COLON);
            write(ASEmitterTokens.NULL);
            write(ASEmitterTokens.PAREN_CLOSE);
        }
        else
        {
			if (isAssignment
					&& (getProject() instanceof RoyaleJSProject && ((RoyaleJSProject) getProject()).config != null && ((RoyaleJSProject) getProject()).config.getJsVectorEmulationClass() == null)
					&& node.getLeftOperandNode() instanceof MemberAccessExpressionNode
					&& ((MemberAccessExpressionNode) node.getLeftOperandNode()).getRightOperandNode() instanceof IdentifierNode
					&& ((IdentifierNode) ((MemberAccessExpressionNode) node.getLeftOperandNode()).getRightOperandNode()).getName().equals("length")
					&& ((MemberAccessExpressionNode) node.getLeftOperandNode()).getLeftOperandNode().resolveType(getProject()) instanceof AppliedVectorDefinition)
			{
				//for default Vector implementation, when setting length, we need to set it on the associated 'synthType' instance which tags the native
				//Array representation of the Vector. This allows running 'setter' code because it is not possible to override the native length setter on Array
				//unless using a different approach, like es6 Proxy.
				//this code inserts the extra access name for setting length, e.g. myVectInstance['_synthType'].length = assignedValue
				//the dynamic access field name is a constant on Language, so it can be different/shorter in release build
				getWalker().walk(((MemberAccessExpressionNode) node.getLeftOperandNode()).getLeftOperandNode());
				write(ASEmitterTokens.SQUARE_OPEN);
				write(JSRoyaleEmitterTokens.LANGUAGE_QNAME.getToken());
				write(ASEmitterTokens.MEMBER_ACCESS);
				write(JSRoyaleEmitterTokens.ROYALE_SYNTH_TAG_FIELD_NAME);
				write(ASEmitterTokens.SQUARE_CLOSE);
				write(ASEmitterTokens.MEMBER_ACCESS);
				getWalker().walk(((MemberAccessExpressionNode) node.getLeftOperandNode()).getRightOperandNode());
			}
            else getWalker().walk(node.getLeftOperandNode());
            startMapping(node, node.getLeftOperandNode());
            
            if (id != ASTNodeID.Op_CommaID)
                write(ASEmitterTokens.SPACE);

            // (erikdebruin) rewrite 'a &&= b' to 'a = a && b'
            if (id == ASTNodeID.Op_LogicalAndAssignID
                    || id == ASTNodeID.Op_LogicalOrAssignID)
            {
                IExpressionNode lnode = node
                        .getLeftOperandNode();

                writeToken(ASEmitterTokens.EQUAL);
                endMapping(node);

                getWalker().walk(lnode);

                startMapping(node, node.getLeftOperandNode());
                write(ASEmitterTokens.SPACE);
                write((id == ASTNodeID.Op_LogicalAndAssignID) ? ASEmitterTokens.LOGICAL_AND
                        : ASEmitterTokens.LOGICAL_OR);
            }
            else
            {
                write(node.getOperator().getOperatorText());
            }

            write(ASEmitterTokens.SPACE);
            endMapping(node);

			if (isAssignment)
			{
				getEmitter().emitAssignmentCoercion(node.getRightOperandNode(), node.getLeftOperandNode().resolveType(getProject()));
			}
			else
			{
				
				getWalker().walk(node.getRightOperandNode());
				
				if (node.getNodeID() == ASTNodeID.Op_InID &&
						((JSRoyaleEmitter)getEmitter()).isXML(node.getRightOperandNode()))
				{
					write(".elementNames()");
				}
				else if (node.getNodeID() == ASTNodeID.Op_InID &&
						((JSRoyaleEmitter)getEmitter()).isProxy(node.getRightOperandNode()))
				{
					write(".propertyNames()");
				}
			}
        }

        if (ASNodeUtils.hasParenOpen(node))
            write(ASEmitterTokens.PAREN_CLOSE);
    }
    
    public static enum DatePropertiesGetters
    {
    	TIME("time", "getTime"),
    	FULLYEAR("fullYear", "getFullYear"),
    	MONTH("month", "getMonth"),
    	DATE("date", "getDate"),
    	DAY("day", "getDay"),
    	FULLYEARUTC("fullYearUTC", "getUTCFullYear"),
    	MONTHUTC("monthUTC", "getUTCMonth"),
    	DATEUTC("dateUTC", "getUTCDate"),
    	DAYUTC("dayUTC", "getUTCDay"),
    	HOURS("hours", "getHours"),
    	MINUTES("minutes", "getMinutes"),
    	SECONDS("seconds", "getSeconds"),
    	MILLISECONDS("milliseconds", "getMilliseconds"),
    	HOURSUTC("hoursUTC", "getUTCHours"),
    	MINUTESUTC("minutesUTC", "getUTCMinutes"),
    	SECONDSUTC("secondsUTC", "getUTCSeconds"),
    	MILLISECONDSUTC("millisecondsUTC", "getUTCMilliseconds"),
    	TIMEZONEOFFSET("timezoneOffset", "getTimezoneOffset");
    	
    	DatePropertiesGetters(String value, String functionName)
    	{
    		this.value = value;
    		this.functionName = functionName;
    	}
    	
    	private String value;
    	private String functionName;
    	
    	public String getFunctionName()
    	{
    		return functionName;
    	}
    	
    	public String getValue()
    	{
    		return value;
    	}
    }
    
    public static enum DatePropertiesSetters
    {
    	TIME("time", "setTime"),
    	FULLYEAR("fullYear", "setFullYear"),
    	MONTH("month", "setMonth"),
    	DATE("date", "setDate"),
    	DAY("day", "setDay"),
    	FULLYEARUTC("fullYearUTC", "setUTCFullYear"),
    	MONTHUTC("monthUTC", "setUTCMonth"),
    	DATEUTC("dateUTC", "setUTCDate"),
    	DAYUTC("day", "setUTCDay"),
    	HOURS("hours", "setHours"),
    	MINUTES("minutes", "setMinutes"),
    	SECONDS("seconds", "setSeconds"),
    	MILLISECONDS("milliseconds", "setMilliseconds"),
    	HOURSUTC("hoursUTC", "setUTCHours"),
    	MINUTESUTC("minutesUTC", "setUTCMinutes"),
    	SECONDSUTC("secondsUTC", "setUTCSeconds"),
    	MILLISECONDSUTC("millisecondsUTC", "setUTCMilliseconds");
    	
    	DatePropertiesSetters(String value, String functionName)
    	{
    		this.value = value;
    		this.functionName = functionName;
    	}
    	
    	private String value;
    	private String functionName;
    	
    	public String getFunctionName()
    	{
    		return functionName;
    	}
    	
    	public String getValue()
    	{
    		return value;
    	}
    }
    
    void specialCaseDate(IBinaryOperatorNode node, MemberAccessExpressionNode leftSide)
    {
    	MemberAccessExpressionNode dateNode = (MemberAccessExpressionNode)leftSide;
        IIdentifierNode rightSide = (IIdentifierNode)dateNode.getRightOperandNode();
        String op = node.getOperator().getOperatorText();
        boolean isAssignment = op.contains("=")
                && !op.contains("==")
                && !(op.startsWith("<") || op.startsWith(">") || op
                        .startsWith("!"));
        getWalker().walk(dateNode.getLeftOperandNode());
        String rightName = rightSide.getName();
        if (isAssignment)
        {
            DatePropertiesSetters prop = DatePropertiesSetters.valueOf(rightName.toUpperCase());
            write(ASEmitterTokens.MEMBER_ACCESS);
            write(prop.getFunctionName());
	        write(ASEmitterTokens.PAREN_OPEN);
	        if (op.length() > 1)
	        {
	            DatePropertiesGetters propGetter = DatePropertiesGetters.valueOf(rightName.toUpperCase());
	            getWalker().walk(dateNode.getLeftOperandNode());
	            write(ASEmitterTokens.MEMBER_ACCESS);
	            write(propGetter.getFunctionName());
		        write(ASEmitterTokens.PAREN_OPEN);
		        write(ASEmitterTokens.PAREN_CLOSE);
	        	write(ASEmitterTokens.SPACE);
	        	write(op.substring(0, 1));
	        	write(ASEmitterTokens.SPACE);
	        }
	        getWalker().walk(node.getRightOperandNode());
	        write(ASEmitterTokens.PAREN_CLOSE);
        }
        else
        {
            DatePropertiesGetters propGetter = DatePropertiesGetters.valueOf(rightName.toUpperCase());
            write(ASEmitterTokens.MEMBER_ACCESS);
            write(propGetter.getFunctionName());
	        write(ASEmitterTokens.PAREN_OPEN);
	        write(ASEmitterTokens.PAREN_CLOSE);
        	write(ASEmitterTokens.SPACE);
        	write(op);
        	write(ASEmitterTokens.SPACE);
	        getWalker().walk(node.getRightOperandNode());
        }
    }
}
