/*
 *
 *  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 java.util.List;

import org.apache.royale.compiler.asdoc.royale.ASDocComment;
import org.apache.royale.compiler.codegen.ISubEmitter;
import org.apache.royale.compiler.codegen.js.IJSEmitter;
import org.apache.royale.compiler.definitions.IClassDefinition;
import org.apache.royale.compiler.definitions.IDefinition;
import org.apache.royale.compiler.definitions.IFunctionDefinition;
import org.apache.royale.compiler.internal.codegen.as.ASEmitterTokens;
import org.apache.royale.compiler.internal.codegen.js.JSSubEmitter;
import org.apache.royale.compiler.internal.codegen.js.royale.JSRoyaleDocEmitter;
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.utils.DocEmitterUtils;
import org.apache.royale.compiler.internal.codegen.js.utils.EmitterUtils;
import org.apache.royale.compiler.internal.projects.RoyaleJSProject;
import org.apache.royale.compiler.internal.tree.as.IdentifierNode;
import org.apache.royale.compiler.tree.ASTNodeID;
import org.apache.royale.compiler.tree.as.IASNode;
import org.apache.royale.compiler.tree.as.IAccessorNode;
import org.apache.royale.compiler.tree.as.IClassNode;
import org.apache.royale.compiler.tree.as.IDefinitionNode;
import org.apache.royale.compiler.tree.as.IExpressionNode;
import org.apache.royale.compiler.tree.as.IFunctionNode;
import org.apache.royale.compiler.tree.as.IVariableNode;

public class ClassEmitter extends JSSubEmitter implements
        ISubEmitter<IClassNode>
{

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

    @Override
    public void emit(IClassNode node)
    {
        boolean keepASDoc = false;
        boolean verbose = false;
        RoyaleJSProject project = (RoyaleJSProject)getEmitter().getWalker().getProject();
        keepASDoc = project.config != null && project.config.getKeepASDoc();
        verbose = project.config != null && project.config.isVerbose();
    	
        getModel().pushClass(node.getDefinition());

        // TODO (mschmalle) will remove this cast as more things get abstracted
        JSRoyaleEmitter fjs = (JSRoyaleEmitter) getEmitter();
        
        ASDocComment asDoc = (ASDocComment) node.getASDocComment();
        if (asDoc != null && keepASDoc)
        {
            List<String> ignoreList = DocEmitterUtils.loadImportIgnores(fjs, asDoc.commentNoEnd());
            if(verbose)
            {
                for(String ignorable : ignoreList)
                {
                    System.out.println("Found ignorable: " + ignorable);
                }
            }
        }
        
        boolean suppressExport = (asDoc != null && DocEmitterUtils.hasSuppressExport(fjs, asDoc.commentNoEnd()));

        getModel().suppressExports = suppressExport;

        IClassDefinition definition = node.getDefinition();

        IFunctionDefinition ctorDefinition = definition.getConstructor();

        // look for force-linking pattern in scope block node
        int childNodeCount = node.getChildCount();
        for (int i = 0; i < childNodeCount; i++)
        {
        	IASNode child = node.getChild(i);
        	if (child.getNodeID() == ASTNodeID.BlockID)
        	{
        		int blockNodeCount = child.getChildCount();
        		for (int j = 0; j < blockNodeCount - 1; j++)
        		{
        			IASNode blockChild = child.getChild(j);
        			if (blockChild.getNodeID() == ASTNodeID.ImportID)
        			{
        				IASNode afterChild = child.getChild(j + 1);
        				if (afterChild.getNodeID() == ASTNodeID.IdentifierID)
        				{
        					IDefinition def = ((IdentifierNode)afterChild).resolve(project);
        					if (def instanceof IClassDefinition)
        					{
        						fjs.usedNames.add(def.getQualifiedName());
        					}
        				}
        			}
        		}
        		break;
        	}        	
        }
        
        // Static-only (Singleton) classes may not have a constructor
        if (ctorDefinition != null)
        {
            IFunctionNode ctorNode = (IFunctionNode) ctorDefinition.getNode();
            if (ctorNode != null)
            {
                // constructor
                getEmitter().emitMethod(ctorNode);
                write(ASEmitterTokens.SEMICOLON);
            }
            else
            {
                String qname = definition.getQualifiedName();
                if (qname != null && !qname.equals(""))
                {
                    write(getEmitter().formatQualifiedName(qname));
                    write(ASEmitterTokens.SPACE);
                    writeToken(ASEmitterTokens.EQUAL);
                    write(ASEmitterTokens.FUNCTION);
                    write(ASEmitterTokens.PAREN_OPEN);
                    write(ASEmitterTokens.PAREN_CLOSE);
                    write(ASEmitterTokens.SPACE);
                    write(ASEmitterTokens.BLOCK_OPEN);
                    writeNewline();
                    fjs.emitComplexInitializers(node);
                    write(ASEmitterTokens.BLOCK_CLOSE);
                    write(ASEmitterTokens.SEMICOLON);
                }
            }
        }

  	    if (!getEmitter().getModel().isExterns && !suppressExport)
  	    {
  	        JSRoyaleDocEmitter doc = (JSRoyaleDocEmitter) getEmitter()
  	        .getDocEmitter();
  		    writeNewline();
  		    writeNewline();
  		    writeNewline();
  		    doc.begin();
  		    writeNewline(" * Prevent renaming of class. Needed for reflection.");
  		    doc.end();
  		    write(JSRoyaleEmitterTokens.GOOG_EXPORT_SYMBOL);
  		    write(ASEmitterTokens.PAREN_OPEN);
  		    write(ASEmitterTokens.SINGLE_QUOTE);
  		    write(getEmitter().formatQualifiedName(node.getQualifiedName()));
  		    write(ASEmitterTokens.SINGLE_QUOTE);
  		    write(ASEmitterTokens.COMMA);
  		    write(ASEmitterTokens.SPACE);
  		    write(getEmitter().formatQualifiedName(node.getQualifiedName()));
  		    write(ASEmitterTokens.PAREN_CLOSE);
  		    write(ASEmitterTokens.SEMICOLON);
  	    }

        IDefinitionNode[] dnodes = node.getAllMemberNodes();
        for (IDefinitionNode dnode : dnodes)
        {
            if (dnode.getNodeID() == ASTNodeID.VariableID)
            {
                writeNewline();
                writeNewline();
                writeNewline();
                getEmitter().emitField((IVariableNode) dnode);
                startMapping(dnode, dnode);
                write(ASEmitterTokens.SEMICOLON);
                endMapping(dnode);
            }
            else if (dnode.getNodeID() == ASTNodeID.FunctionID)
            {
                if (!((IFunctionNode) dnode).isConstructor())
                {
                    writeNewline();
                    writeNewline();
                    writeNewline();
                    getEmitter().emitMethod((IFunctionNode) dnode);
                    write(ASEmitterTokens.SEMICOLON);
                }
            }
            else if (dnode.getNodeID() == ASTNodeID.GetterID
                    || dnode.getNodeID() == ASTNodeID.SetterID)
            {
                //writeNewline();
                //writeNewline();
                //writeNewline();
                fjs.emitAccessors((IAccessorNode) dnode);
                //this shouldn't write anything, just set up
                //a data structure for emitASGettersAndSetters
                //write(ASEmitterTokens.SEMICOLON);
            }
            else if (dnode.getNodeID() == ASTNodeID.BindableVariableID)
            {
                writeNewline();
                writeNewline();
                writeNewline();
                getEmitter().emitField((IVariableNode) dnode);
                startMapping(dnode, dnode);
                write(ASEmitterTokens.SEMICOLON);
                endMapping(dnode);
            }
        }

        fjs.getBindableEmitter().emit(definition);
        fjs.getAccessorEmitter().emit(definition);
        
        if (fjs.getFieldEmitter().hasComplexStaticInitializers)
        {
            writeNewline();
            boolean complexInitOutput = false;
	        for (IDefinitionNode dnode : dnodes)
	        {
	            if (dnode.getNodeID() == ASTNodeID.VariableID)
	            {
                    complexInitOutput = fjs.getFieldEmitter().emitFieldInitializer((IVariableNode) dnode) || complexInitOutput;
	            }
	            else if (dnode.getNodeID() == ASTNodeID.BindableVariableID)
	            {
                    complexInitOutput = fjs.getFieldEmitter().emitFieldInitializer((IVariableNode) dnode) || complexInitOutput;
	            }
	        }
	        if (complexInitOutput) {
                writeNewline();
                writeNewline();
            }
        }
        
        fjs.getPackageFooterEmitter().emitClassInfo(node);

        getModel().popClass();
    }
    
    public void emitComplexInitializers(IClassNode node)
    {
    	boolean wroteOne = false;
        IDefinitionNode[] dnodes = node.getAllMemberNodes();
        for (IDefinitionNode dnode : dnodes)
        {
            if (dnode.getNodeID() == ASTNodeID.VariableID || dnode.getNodeID() == ASTNodeID.BindableVariableID)
            {
            	IVariableNode varnode = ((IVariableNode)dnode);
                IExpressionNode vnode = varnode.getAssignedValueNode();
                if (vnode != null && (!(dnode.getDefinition().isStatic() || EmitterUtils.isScalar(vnode))))
                {
                    writeNewline();
                    write(ASEmitterTokens.THIS);
                    write(ASEmitterTokens.MEMBER_ACCESS);
                    String dname = dnode.getName();
                    IDefinition dDef = dnode.getDefinition();
                		if (dDef != null && dDef.isPrivate() && getProject().getAllowPrivateNameConflicts())
                			dname = getEmitter().formatPrivateName(dDef.getParent().getQualifiedName(), dname);
                    write(dname);
                    if (dnode.getNodeID() == ASTNodeID.BindableVariableID)
                    {
                    	write("_");
                    }
                    write(ASEmitterTokens.SPACE);
                    writeToken(ASEmitterTokens.EQUAL);
                    getEmitter().emitAssignmentCoercion(vnode, varnode.getVariableTypeNode().resolve(getProject()));
                    write(ASEmitterTokens.SEMICOLON);
                    wroteOne = true;
                }
            }
        }    
        if (wroteOne)
        	writeNewline();
    }
}
