/*
 *
 *  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.driver.js.royale;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.apache.royale.compiler.constants.IASLanguageConstants;
import org.apache.royale.compiler.css.ICSSDocument;
import org.apache.royale.compiler.css.ICSSMediaQueryCondition;
import org.apache.royale.compiler.css.ICSSProperty;
import org.apache.royale.compiler.css.ICSSPropertyValue;
import org.apache.royale.compiler.css.ICSSRule;
import org.apache.royale.compiler.css.ICSSSelector;
import org.apache.royale.compiler.css.ICSSSelectorCondition;
import org.apache.royale.compiler.internal.codegen.js.goog.JSGoogEmitterTokens;
import org.apache.royale.compiler.internal.css.*;
import org.apache.royale.compiler.internal.css.codegen.CSSCompilationSession;

import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;

public class JSCSSCompilationSession extends CSSCompilationSession
{
	private List<String> otherCSSFunctions = Arrays.asList(
			 "-moz-linear-gradient",
	         "-webkit-linear-gradient",
	         "linear-gradient",
	         "progid:DXImageTransform.Microsoft.gradient",
	         "translateX",
	         "translateY",
	         "translate",
             "blur",
             "brightness",
             "contrast",
             "drop-shadow",
             "hue-rotate",
             "invert",
             "saturate",
             "sepia"
    );
    //  this two conflicts with other css functions with the same name - comment for now
    //  "grayscale",
    //  "opacity",

    private ArrayList<String> requires;
    
    public String getEncodedCSS()
    {
        final ICSSDocument css = synthesisNormalizedCSS(false);
        StringBuilder sb = new StringBuilder();
        requires = new ArrayList<String>();
        encodeCSS(css, sb);
        if (sb.length() == 0)
        	return null;
        sb.append("];\n");
        for (String r : requires)
        {
            sb.append(JSGoogEmitterTokens.GOOG_REQUIRE.getToken() + "('" + formatQualifiedName(r) + "');\n");
        }

        return sb.toString();        
    }
    
    public String emitCSS()
    {
        final ICSSDocument css = synthesisNormalizedCSS(false);
        StringBuilder sb = new StringBuilder();
        sb.append("/* Generated by Apache Royale Compiler */\n");
        walkCSS(css, sb);
        return sb.toString();
    }

    /**
     * used to minify the CSS for release mode
     */
    public static String minifyCSSString(String cssString)
    {
        //Remove empty selectors
        cssString = cssString.replaceAll("\\S+\\s?\\{[\\s\\n]+}", "");
        // Remove comments
        cssString = cssString.replaceAll("/\\*[\\d\\D]*?\\*/", "");
        cssString = cssString.replace(";}", "}");
        cssString = cssString.replaceAll("[\\n\\r]+\\s*", "");
        cssString = cssString.replaceAll("\\s+", " ");
        cssString = cssString.replaceAll("\\s?([:,;{}])\\s?", "$1");
        cssString = cssString.replaceAll("([\\s:]0)(px|pt|em)", "$1");

        return cssString;
    }
    
    private String fontFaceToString(CSSFontFace fontFace)
    {
        final StringBuilder result = new StringBuilder();
        result.append("@font-face {\n");
        result.append("    ");
        result.append("font-family: ");
        result.append(fontFace.getFontFamily() + ";\n");
        result.append("    ");
        result.append("font-style: ");
        result.append(fontFace.getFontStyle() + ";\n");
        result.append("    ");
        result.append("font-weight: ");
        result.append(fontFace.getFontStyle() + ";\n");
        result.append("    ");
        ArrayList<ICSSPropertyValue> sources = fontFace.getSources();
        for (ICSSPropertyValue src : sources)
        {
        	result.append("src: ");
        	result.append(src.toString() + ";\n");
        }
       	result.append("}\n");
        return result.toString();
    }
    
    private String cssRuleToString(ICSSRule rule)
    {
        final StringBuilder result = new StringBuilder();

        ImmutableList<ICSSMediaQueryCondition> mqList = rule.getMediaQueryConditions();
        boolean hasMediaQuery = !mqList.isEmpty();
        if (hasMediaQuery)
        {
            result.append("@media ");
            result.append(Joiner.on(" and ").join(rule.getMediaQueryConditions()));
            result.append(" {\n");
            result.append("    ");
        }

        ImmutableList<ICSSSelector> selectors = rule.getSelectorGroup();
        boolean firstOne = true;
        for (ICSSSelector selector : selectors)
        {
        	String s = selector.toString();
	        // add "." to type selectors that don't map cleanly
	        // to CSS type selectors to convert them to class
	    	// selectors.
	        if (!s.startsWith(".") && !s.startsWith("*") && !s.startsWith("#") && !s.startsWith("::"))
	        {
	        	String condition = null;
        		int colon = s.indexOf(":");
	        	if (colon != -1)
	        	{
	        		condition = s.substring(colon);
	        		s = s.substring(0, colon);
	        	}
	        	else
	        	{
	        		int brace = s.indexOf("[");
	        		if (brace != -1)
	        		{
		        		condition = s.substring(brace);
		        		s = s.substring(0, brace);	        			
	        		}
	        		else
	        		{
	        			int child = s.indexOf(">");
	        			if (child != -1)
	        			{
			        		condition = s.substring(child);
			        		s = s.substring(0, child);	        			
	        			}
	        			else
	        			{
	        				int preceded = s.indexOf("+");
		        			if (preceded != -1)
		        			{
				        		condition = s.substring(preceded);
				        		s = s.substring(0, preceded);	        			
		        			}
	        			}
	        		}
	        	}
	        	if (!htmlElementNames.contains(s.toLowerCase()))
	        	{
	        		if (s.indexOf(" ") > 0)
	        		{
	        			String parts[] = s.split(" ");
	        			int n = parts.length;
	        			s = "";
	        			for (int i = 0; i < n; i++)
	        			{
	        				if (i != 0)
	        					s += " ";
	        				String part = parts[i];
	        				if (!part.startsWith(".") && !part.startsWith("*") && !part.startsWith("#") && !part.startsWith("::"))
	        				{
	        					int pipe = part.indexOf("|");
				        		if (pipe != -1)
				        			part = part.substring(pipe + 1);
				        		part = "." + part;
	        				}
			        		s += part;
	        			}
	        		}
	        		else
	        		{
		        		int pipe = s.indexOf("|");
		        		if (pipe != -1)
		        			s = s.substring(pipe + 1);
		        		s = "." + s;
	        		}
	        	}
	        	if (condition != null)
	        		s = s + condition;
	        }
	        if (!firstOne)
	        	result.append(",\n");
	        result.append(s);
        }

        result.append(" {\n");
        ArrayList<String> listOfProps = new ArrayList<String>();
        for (final ICSSProperty prop : rule.getProperties())
        {
            String propString = ((CSSProperty)prop).toCSSString();
            // skip class references since the won't work in CSS
            if (propString.contains("ClassReference"))
            	continue;
            listOfProps.add(propString);
        }
        Collections.sort(listOfProps);
        for (final String propString : listOfProps)
        {
            if (!hasMediaQuery)
                result.append("    ");

            result.append("    ").append(propString).append("\n");
        }
        if (hasMediaQuery)
            result.append("    }\n");

        result.append("}\n");

        return result.toString();
    }
    
    private void walkCSS(ICSSDocument css, StringBuilder sb)
    {
    	for (CSSFontFace fontFace : fontFaces)
    	{
    		sb.append(fontFaceToString(fontFace));
    	}
    	if (fontFaces.size() > 0)
    		sb.append("\n\n");
        ImmutableList<ICSSRule> rules = css.getRules();
        for (ICSSRule rule : rules)
        {
        	String s = cssRuleToString(rule);
        	if (s.startsWith("@media -royale-swf"))
        		continue;
            sb.append(s);
            sb.append("\n\n");
        }
    }
    
    private void encodeCSS(ICSSDocument css, StringBuilder sb)
    {
        ImmutableList<ICSSRule> rules = css.getRules();
        boolean skipcomma = true;
        for (ICSSRule rule : rules)
        {
            String s = encodeRule(rule);
            if (s != null)
            {
                if (skipcomma)
                    skipcomma = false;
                else
                    sb.append(",\n");
                sb.append(s);
            }
        }
    }
    
    List<String> htmlElementNames = Arrays.asList(
        "a",
        "aside",
        "b",
        "br",
        "body",
        "button",
        "caption",
        "code",
        "col",
        "colgroup",
        "dialog",
        "div",
        "em",
        "embed",
        "font",
        "form",
        "h1",
        "h2",
        "h3",
        "h4",
        "h5",
        "h6",
        "header",
        "hr",
        "html",
        "i",
        "img",
        "input",
        "label",
        "li",
        "main",
        /*"menu", not cross-browser, and we want to use it in Royale */
        "nav",
        "ol",
        "option",
        "p",
        "pre",
        "s",
        "select",
        "small",
        "span",
        "strong",
        "table",
        "tbody",
        "td",
        "textarea",
        "tfoot",
        "th",
        "thead",
        "tr",
        "u",
        "ul"
    );
    
    private String escapeDoubleQuotes(String s)
    {
        s = replaceUnicodeEncoded(s);
    	if (s.contains("\""))
    		s = s.replace("\"", "\\\"");
    	return s;
    }

    private String replaceUnicodeEncoded(String s)
    {
        //almost all escape sequences are converted to actual character sequences, except for some that don't have
        //a good result for Character.toChars (e.g. zero width space or non-breaking-space)
        //convert hex char values to unicode
        if (s.matches("\\\\[0-9a-fA-F]{1,4}")) {
            s = s.replaceAll("\\\\([0-9a-fA-F]{1,4})\\s?","\\\\u$1");
        }
        return s;
    }
    
    private String encodeRule(ICSSRule rule)
    {
        final StringBuilder result = new StringBuilder();

        ImmutableList<ICSSMediaQueryCondition> mqlist = rule.getMediaQueryConditions();
        int n = mqlist.size();
        if (n > 0)
        {
            if (mqlist.get(0).toString().equals("-royale-swf"))
                return null;
            
            result.append(n);
            
            for (ICSSMediaQueryCondition mqcond : mqlist)
            {
                result.append(",\n");
                result.append("\"" + mqcond.toString() + "\"");
            }
        }
        else
            result.append(n);

        result.append(",\n");

        ImmutableList<ICSSSelector> slist = rule.getSelectorGroup();
        result.append(slist.size());
        for (ICSSSelector sel : slist)
        {
            result.append(",\n");
            String selName = this.resolvedSelectors.get(sel);
            if (selName == null || selName.equals("null"))
                result.append("\"" + sel.toString() + "\"");
            else
            {
            	selName = formatQualifiedName(selName);
                ImmutableList<ICSSSelectorCondition> conds = sel.getConditions();
                for (ICSSSelectorCondition cond : conds)
                {
                	String condString = escapeDoubleQuotes(cond.toString());
                    selName += condString;
                }
                result.append("\"" + selName + "\"");
            }
        }
        result.append(",\n");
        result.append("function() {");
        
        ImmutableList<ICSSProperty> plist = rule.getProperties();
        ArrayList<String> listOfProps = new ArrayList<String>();
        for (final ICSSProperty prop : rule.getProperties())
        {
        	StringBuilder line = new StringBuilder();
            line.append("this[\"" + prop.getName() + "\"] = ");
            ICSSPropertyValue value = prop.getValue();
            if (value instanceof CSSArrayPropertyValue)
            {
                ImmutableList<? extends ICSSPropertyValue> values = ((CSSArrayPropertyValue)value).getElements();
                line.append("[");
                boolean firstone = true;
                for (ICSSPropertyValue val : values)
                {
                    if (firstone)
                        firstone = false;
                    else
                        line.append(", ");
                    if (val instanceof CSSStringPropertyValue)
                    {
                        line.append("\"" + escapeDoubleQuotes(((CSSStringPropertyValue)val).getValue()) + "\"");
                    }
                    else if (val instanceof CSSColorPropertyValue)
                    {
                        line.append(new Integer(((CSSColorPropertyValue)val).getColorAsInt()));
                    }
                    else if (val instanceof CSSRgbColorPropertyValue)
                    {
                        line.append(new Integer(((CSSRgbColorPropertyValue)val).getColorAsInt()));
                    }
                    else if (value instanceof CSSRgbaColorPropertyValue)
                    {
                        //todo: handle alpha in the RGBA ?
                        line.append(new Long(((CSSRgbaColorPropertyValue)value).getColorAsLong()));
                    }
                    else if (val instanceof CSSKeywordPropertyValue)
                    {
                        CSSKeywordPropertyValue keywordValue = (CSSKeywordPropertyValue)val;
                        String keywordString = keywordValue.getKeyword();
                        if (IASLanguageConstants.TRUE.equals(keywordString))
                            line.append("true");
                        else if (IASLanguageConstants.FALSE.equals(keywordString))
                            line.append("false");
                        else
                            line.append("\"" + ((CSSKeywordPropertyValue)val).getKeyword() + "\"");
                    }
                    else if (val instanceof CSSNumberPropertyValue)
                    {
                        line.append(new Double(((CSSNumberPropertyValue)val).getNumber().doubleValue()));
                    }
                    else if (val instanceof CSSURLAndFormatPropertyValue)
                    {
                        line.append("\"" + escapeDoubleQuotes(((CSSURLAndFormatPropertyValue)val).toString()) + "\"");
                    }
                    else if (val instanceof CSSMultiValuePropertyValue)
                    {
                        line.append("\"" + ((CSSMultiValuePropertyValue)val).toString() + "\"");
                    }
                    else
                    {
                        line.append("unexpected value type: " + val.toString());
                    }
                }
                line.append("]");
            }
            else if (value instanceof CSSMultiValuePropertyValue)
            {
                ImmutableList<? extends ICSSPropertyValue> values = ((CSSMultiValuePropertyValue)value).getElements();
                line.append("[");
                boolean firstone = true;
                for (ICSSPropertyValue val : values)
                {
                    if (firstone)
                        firstone = false;
                    else
                        line.append(", ");
                    if (val instanceof CSSStringPropertyValue)
                    {
                        line.append("\"" + escapeDoubleQuotes(((CSSStringPropertyValue)val).getValue()) + "\"");
                    }
                    else if (val instanceof CSSColorPropertyValue)
                    {
                        line.append(new Integer(((CSSColorPropertyValue)val).getColorAsInt()));
                    }
                    else if (val instanceof CSSRgbColorPropertyValue)
                    {
                        line.append(new Integer(((CSSRgbColorPropertyValue)val).getColorAsInt()));
                    }
                    else if (val instanceof CSSRgbaColorPropertyValue)
                    {
                        //todo: handle alpha in the RGBA ?
                        line.append(new Long(((CSSRgbaColorPropertyValue)val).getColorAsLong()));
                    }
                    else if (val instanceof CSSKeywordPropertyValue)
                    {
                        CSSKeywordPropertyValue keywordValue = (CSSKeywordPropertyValue)val;
                        String keywordString = keywordValue.getKeyword();
                        if (IASLanguageConstants.TRUE.equals(keywordString))
                            line.append("true");
                        else if (IASLanguageConstants.FALSE.equals(keywordString))
                            line.append("false");
                        else
                            line.append("\"" + ((CSSKeywordPropertyValue)val).getKeyword() + "\"");
                    }
                    else if (val instanceof CSSNumberPropertyValue)
                    {
                        line.append(new Double(((CSSNumberPropertyValue)val).getNumber().doubleValue()));
                    }
                    else if (val instanceof CSSURLAndFormatPropertyValue)
                    {
                        line.append("\"" + escapeDoubleQuotes(((CSSURLAndFormatPropertyValue)val).toString()) + "\"");
                    }
                    else if (val instanceof CSSMultiValuePropertyValue)
                    {
                        line.append("\"" + ((CSSMultiValuePropertyValue)val).toString() + "\"");
                    }
                    else
                    {
                        line.append("unexpected value type: " + val.toString());
                    }
                }
                line.append("]");
            }
            else if (value instanceof CSSStringPropertyValue)
            {
                line.append("\"" + replaceUnicodeEncoded(((CSSStringPropertyValue)value).getValue()) + "\"");
            }
            else if (value instanceof CSSColorPropertyValue)
            {
                line.append(new Integer(((CSSColorPropertyValue)value).getColorAsInt()));
            }
            else if (value instanceof CSSRgbColorPropertyValue)
            {
                line.append(new Integer(((CSSRgbColorPropertyValue)value).getColorAsInt()));
            }
            else if (value instanceof CSSRgbaColorPropertyValue)
            {
                //todo: handle alpha in the RGBA ?
                line.append(new Long(((CSSRgbaColorPropertyValue)value).getColorAsLong()));
            }
            else if (value instanceof CSSKeywordPropertyValue)
            {
                CSSKeywordPropertyValue keywordValue = (CSSKeywordPropertyValue)value;
                String keywordString = keywordValue.getKeyword();
                if (IASLanguageConstants.TRUE.equals(keywordString))
                    line.append("true");
                else if (IASLanguageConstants.FALSE.equals(keywordString))
                    line.append("false");
                else
                    line.append("\"" + ((CSSKeywordPropertyValue)value).getKeyword() + "\"");
            }
            else if (value instanceof CSSNumberPropertyValue)
            {
                line.append(new Double(((CSSNumberPropertyValue)value).getNumber().doubleValue()));
            }
            else if (value instanceof CSSFunctionCallPropertyValue)
            {
                final CSSFunctionCallPropertyValue functionCall = (CSSFunctionCallPropertyValue)value;
                if ("ClassReference".equals(functionCall.name))
                {
                    final String className = CSSFunctionCallPropertyValue.getSingleArgumentFromRaw(functionCall.rawArguments);
                    if ("null".equals(className))
                    {
                        // ClassReference(null) resets the property's class reference.
                        line.append("null");
                    }
                    else
                    {
                        line.append(formatQualifiedName(className));
                        requires.add(className);
                    }
                }
                else if ("url".equals(functionCall.name))
                {
                    final String urlString = CSSFunctionCallPropertyValue.getSingleArgumentFromRaw(functionCall.rawArguments);
                    line.append("\"" + urlString + "\"");
                }
                else if ("PropertyReference".equals(functionCall.name))
                {
                    // TODO: implement me
                }
                else if ("calc".equals(functionCall.name))
                {
                    // TODO: implement me
                	line.append("null");
                }
                else if ("Embed".equals(functionCall.name))
                {
                    // TODO: implement me
                    /*
                    final ICompilerProblem e = new CSSCodeGenProblem(
                            new IllegalStateException("Unable to find compilation unit for " + functionCall));
                    problems.add(e);
                    */
                }
                else if (otherCSSFunctions.contains(functionCall.name))
                {
                	// ignore for now?
                	line.append("null");
                }
                else
                {
                    assert false : "CSS parser bug: unexpected function call property value: " + functionCall;
                    throw new IllegalStateException("Unexpected function call property value: " + functionCall);
                }
            }
            listOfProps.add(line.toString());
        }
        Collections.sort(listOfProps);
        
        boolean firstProp = true;
        for (final String line2 : listOfProps)
        {
        	if (!firstProp)
        		result.append(";\n");
        	firstProp = false;
        	result.append(line2);
        }
        result.append("}");

        return result.toString();

    }
    
    @Override
    protected boolean keepRule(ICSSRule newRule)
    {
    	if (super.keepRule(newRule))
    		return true;
    	    	
    	// might need to loop over all selectors in selector group
    	if (newRule.getSelectorGroup().size() > 0)
    	{
    		ICSSSelector selector = newRule.getSelectorGroup().get(0);
	    	String elementName = selector.getElementName();
	    	if (elementName != null)
	    	{
	    		if (htmlElementNames.contains(elementName))
	    			return true;
	    	}
	    	else
	    	{
	    		return true;
	    	}
    	}
        return false;
    }

    private String formatQualifiedName(String name)
    {
    	/*
    	if (name.contains("goog.") || name.startsWith("Vector."))
    		return name;
    	if (name.startsWith("."))
    	{
    		return "." + name.substring(1).replaceAll("\\.", "_");
    	}
    	name = name.replaceAll("\\.", "_");
    	*/
    	return name;
    }

}
