/**
 * Licensed 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.
 *
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 */
package org.thingml.compilers.javascript.browser;

import org.thingml.compilers.Context;
import org.thingml.compilers.javascript.JSThingActionCompiler;
import org.thingml.xtext.helpers.AnnotatedElementHelper;
import org.thingml.xtext.thingML.Expression;
import org.thingml.xtext.thingML.FunctionCallExpression;
import org.thingml.xtext.thingML.PropertyReference;
import org.thingml.xtext.thingML.SendAction;

/**
 * Created by bmori on 01.12.2014.
 */
public class BrowserThingActionCompiler extends JSThingActionCompiler {
	
	private long counter = 0;

    @Override
    public void generate(SendAction action, StringBuilder builder, Context ctx) {
    	
    	StringBuilder builder1 = new StringBuilder();
    	StringBuilder builder2 = new StringBuilder();
    	StringBuilder builder3 = new StringBuilder();
    	
    	if(!AnnotatedElementHelper.isDefined(action.getPort(), "sync_send", "true")) {
    		for(Expression pa : action.getParameters()) {//FIXME: we might as well systematically store all expressions into const...
        		if (pa instanceof PropertyReference) {
        			PropertyReference pr = (PropertyReference)pa;
        			builder1.append("const " + pr.getProperty().getName() + "_const" + counter + " = ");        			
        			generate(pa, builder1, ctx);
        			builder1.append(";\n");
        		} else if (pa instanceof FunctionCallExpression) {
        			FunctionCallExpression fc = (FunctionCallExpression)pa;
        			builder1.append("const " + fc.getFunction().getName() + "_" + Math.abs(fc.getParameters().hashCode()) + "_const" + counter + " = ");
        			generate(pa, builder1, ctx);
        			builder1.append(";\n");
        		}
        		        		        		        		
        		builder3.append(", ");
                if(!AnnotatedElementHelper.isDefined(action.getPort(), "sync_send", "true")) {
                	if (pa instanceof PropertyReference) {
                		PropertyReference pr = (PropertyReference)pa;
                		builder3.append(pr.getProperty().getName() + "_const" + counter);
                	} else if (pa instanceof FunctionCallExpression) {
                		FunctionCallExpression fc = (FunctionCallExpression)pa;
                		builder3.append(fc.getFunction().getName() + "_" + Math.abs(fc.getParameters().hashCode()) + "_const" + counter);
                	} else {
                		generate(pa, builder3, ctx);
                	} 
                }
                else {
            		generate(pa, builder3, ctx);
            	}
                counter++;
        	}
    		builder2.append("setTimeout(() => ");
    	}
    	builder2.append(ctx.getContextAnnotation("thisRef"));
        builder2.append("bus.emit('" + action.getPort().getName() + "?" + action.getMessage().getName() + "'");
        builder2.append(builder3.toString());
        /*for (Expression pa : action.getParameters()) {
            builder3.append(", ");
            if(!AnnotatedElementHelper.isDefined(action.getPort(), "sync_send", "true")) {
            	if (pa instanceof PropertyReference) {
            		PropertyReference pr = (PropertyReference)pa;
            		builder3.append(pr.getProperty().getName() + "_const");
            	} else if (pa instanceof FunctionCallExpression) {
            		FunctionCallExpression fc = (FunctionCallExpression)pa;
            		builder3.append(fc.getFunction().getName() + "_" + Math.abs(fc.getParameters().hashCode()) + "_const");
            	} else {
            		generate(pa, builder3, ctx);
            	} 
            }
            else {
        		generate(pa, builder3, ctx);
        	}
        }*/
        builder2.append(")");
    	if(!AnnotatedElementHelper.isDefined(action.getPort(), "sync_send", "true")) {
            builder2.append(", 0)");
    	}
        builder2.append(";\n");
        
        builder.append(builder1.toString());
        builder.append(builder2.toString());
    }
}

@@ -876,24 +876,126 @@
 mentHelper;%0A
+import org.thingml.xtext.thingML.EnumLiteralRef;%0Aimport org.thingml.xtext.thingML.EnumerationLiteral;%0A
 import org.t
@@ -1327,16 +1327,300 @@
 r = 0;%0A%0A
+    @Override%0A    public void generate(EnumLiteralRef action, StringBuilder builder, Context ctx) %7B%0A    %09if (action.getLiteral().getInit() != null) %7B%0A    %09%09generate(action.getLiteral().getInit(), builder, ctx);%0A    %09%7D else %7B%0A    %09%09super.generate(action, builder, ctx);%0A    %09%7D%0A    %7D%0A%09%0A
     @Ove
@@ -3880,801 +3880,8 @@
 ));%0A
-        /*for (Expression pa : action.getParameters()) %7B%0A            builder3.append(%22, %22);%0A            if(!AnnotatedElementHelper.isDefined(action.getPort(), %22sync_send%22, %22true%22)) %7B%0A            %09if (pa instanceof PropertyReference) %7B%0A            %09%09PropertyReference pr = (PropertyReference)pa;%0A            %09%09builder3.append(pr.getProperty().getName() + %22_const%22);%0A            %09%7D else if (pa instanceof FunctionCallExpression) %7B%0A            %09%09FunctionCallExpression fc = (FunctionCallExpression)pa;%0A            %09%09builder3.append(fc.getFunction().getName() + %22_%22 + Math.abs(fc.getParameters().hashCode()) + %22_const%22);%0A            %09%7D else %7B%0A            %09%09generate(pa, builder3, ctx);%0A            %09%7D %0A            %7D%0A            else %7B%0A        %09%09generate(pa, builder3, ctx);%0A        %09%7D%0A        %7D*/%0A
     

fix bug with enum in browser compiler