/*
 *
 *  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;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Stack;

import org.apache.royale.compiler.definitions.IClassDefinition;
import org.apache.royale.compiler.definitions.ITypeDefinition;
import org.apache.royale.compiler.tree.as.IFunctionNode;
import org.apache.royale.compiler.tree.as.IGetterNode;
import org.apache.royale.compiler.tree.as.ISetterNode;
import org.apache.royale.compiler.tree.as.IVariableNode;
import org.apache.royale.compiler.tree.metadata.IMetaTagNode;

/**
 * @author Michael Schmalle
 */
public class JSSessionModel
{
    public static final String CONSTRUCTOR_EMPTY = "emptyConstructor";
    public static final String CONSTRUCTOR_FULL = "fullConstructor";
    public static final String SUPER_FUNCTION_CALL = "replaceSuperFunction";

    private IClassDefinition currentClass;

    public static class PropertyNodes
    {
        public IGetterNode getter;
        public ISetterNode setter;
        public ITypeDefinition type;
    }

    public static class BindableVarInfo
    {
        public String namespace;
        public Boolean isStatic;
        public String type;
        public IMetaTagNode[] metaTags;
    }


    public enum ImplicitBindableImplementation {
        NONE,
        EXTENDS,
        IMPLEMENTS
    }

    private static class Context
    {
        public LinkedHashMap<String, PropertyNodes> propertyMap;
        public List<String> interfacePropertyMap;
        public LinkedHashMap<String, PropertyNodes> staticPropertyMap;
        public HashMap<String, BindableVarInfo> bindableVars;
        public ArrayList<IVariableNode> vars;
        public ArrayList<IFunctionNode> methods;
        public IClassDefinition classDefinition;
        public ImplicitBindableImplementation bindableImplementation;
        public Boolean suppressExports;
    }
    
    public JSSessionModel()
    {
    	
    }
    
    private Stack<Context> stack = new Stack<Context>();

    public boolean needLanguage = false;
    
    public boolean isExterns = false;

    public boolean inE4xFilter = false;

    public boolean inStaticInitializer = false;
    
    public boolean suppressExports = false;
    
    private LinkedHashMap<String, PropertyNodes> propertyMap = new LinkedHashMap<String, PropertyNodes>();

    private List<String> interfacePropertyMap = new ArrayList<String>();

    private LinkedHashMap<String, PropertyNodes> staticPropertyMap = new LinkedHashMap<String, PropertyNodes>();

    private HashMap<String, BindableVarInfo> bindableVars = new HashMap<String, BindableVarInfo>();

    private ArrayList<IVariableNode> vars = new ArrayList<IVariableNode>();

    private ArrayList<IFunctionNode> methods = new ArrayList<IFunctionNode>();

    private HashMap<String, String> internalClasses;

    private int foreachLoopCount = 0;

    private HashMap<IClassDefinition,ImplicitBindableImplementation> implicitBindableImplementations = new HashMap<IClassDefinition, ImplicitBindableImplementation>(100);

    private ImplicitBindableImplementation implicitBindableImplementation = ImplicitBindableImplementation.NONE;

    public String primaryDefinitionQName;
    
    public IClassDefinition getCurrentClass()
    {
        return currentClass;
    }

    public void setCurrentClass(IClassDefinition currentClass)
    {
        this.currentClass = currentClass;
    }

    public ImplicitBindableImplementation getImplicitBindableImplementation() {
        return implicitBindableImplementation;
    }

    public void registerImplicitBindableImplementation(IClassDefinition classDefinition, ImplicitBindableImplementation type) {
        implicitBindableImplementations.put(classDefinition, type);
    }

    public void unregisterImplicitBindableImplementation(IClassDefinition classDefinition) {
        if (implicitBindableImplementations.keySet().contains(classDefinition)) {
            implicitBindableImplementations.remove(classDefinition);
        }
    }

    public void pushClass(IClassDefinition currentClass)
    {
        Context context = new Context();
        context.classDefinition = this.currentClass;
        context.bindableVars = bindableVars;
        context.interfacePropertyMap = interfacePropertyMap;
        context.propertyMap = propertyMap;
        context.staticPropertyMap = staticPropertyMap;
        context.vars = vars;
        context.methods = methods;
        context.bindableImplementation = implicitBindableImplementation;
        context.suppressExports = suppressExports;
        stack.push(context);
        suppressExports = false; //always defaults to false
        this.currentClass = currentClass;
        bindableVars = new HashMap<String, BindableVarInfo>();
        staticPropertyMap = new LinkedHashMap<String, PropertyNodes>();
        interfacePropertyMap = new ArrayList<String>();
        propertyMap = new LinkedHashMap<String, PropertyNodes>();
        vars = new ArrayList<IVariableNode>();
        methods = new ArrayList<IFunctionNode>();
        implicitBindableImplementation = implicitBindableImplementations.get(currentClass);
        if (implicitBindableImplementation == null)
            implicitBindableImplementation = ImplicitBindableImplementation.NONE;
    }

    public void popClass()
    {
        Context context = stack.pop();
        this.currentClass = context.classDefinition;
        bindableVars = context.bindableVars;
        interfacePropertyMap = context.interfacePropertyMap;
        propertyMap = context.propertyMap;
        staticPropertyMap = context.staticPropertyMap;
        vars = context.vars;
        methods = context.methods;
        implicitBindableImplementation = context.bindableImplementation;
        suppressExports = context.suppressExports;
    }

    public HashMap<String, PropertyNodes> getPropertyMap()
    {
        return propertyMap;
    }

    public List<String> getInterfacePropertyMap()
    {
        return interfacePropertyMap;
    }

    public HashMap<String, PropertyNodes> getStaticPropertyMap()
    {
        return staticPropertyMap;
    }

    public boolean hasBindableVars()
    {
        return bindableVars.size() > 0;
    }

    public boolean hasStaticBindableVars()
    {
        for (BindableVarInfo var : bindableVars.values())
        {
            if (var.isStatic) return true;
        }
        return false;
    }

    public HashMap<String, BindableVarInfo> getBindableVars()  { return bindableVars;  }

    public List<IVariableNode> getVars()
    {
        return vars;
    }

    public List<IFunctionNode> getMethods()
    {
        return methods;
    }

    public HashMap<String, String> getInternalClasses()
    {
        if (internalClasses == null)
            internalClasses = new HashMap<String, String>();
        return internalClasses;
    }

    public boolean isInternalClass(String className)
    {
        if (internalClasses == null) return false;

        return internalClasses.containsKey(className);
    }

    public final void incForeachLoopCount()
    {
        foreachLoopCount++;
    }

    public String getCurrentForeachName()
    {
        return "foreachiter" + Integer.toString(foreachLoopCount);
    }



}
