/*
 *
 *  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.flex.compiler.internal.config;

import java.util.LinkedList;
import java.util.List;
import java.util.ArrayList;

import org.apache.flex.compiler.config.ConfigurationBuffer;
import org.apache.flex.compiler.exceptions.ConfigurationException;

/**
 * This class makes the default values go in through the configuration
 * buffer instead of just the value set on the actual object.  This is
 * useful for dependency checking and also for reporting the source
 * location of a particular configuration value when there is some
 * sort of a conflict between two values; i.e. "X (set in defaults)
 * must be disabled to use Y (set on command line)"
 *
 * The other (main) reason it is used is for the
 * FileConfigurator.formatBuffer - since getters aren't part of the
 * config system, the only values that can be printed are ones set via
 * the config setters.  Since its handy to be able to generate a full
 * config file based on current settings, having the default values
 * set here makes the defaults show up too.
 *
 * Although the decentralization of the various config objects is
 * somewhat broken by this class, if you consider it to be basically a
 * "baked in config file", then it might feel less strange.
 *
 * In the end, if it is too much of a pain, don't worry about it, just
 * set your local defaults inside your configuration object.  No big
 * deal.
 */
public class DefaultsConfigurator
{
    private static void set( ConfigurationBuffer cfgbuf, String var, String val ) throws ConfigurationException
    {
        LinkedList<String> args = new LinkedList<String>();
        args.add( val );
        cfgbuf.setVar( var, args, "defaults", -1 );
    }

    private static void set( ConfigurationBuffer cfgbuf, String[] vars, String val ) throws ConfigurationException
    {
        for (int i = 0; i < vars.length; ++i)
        {
            set( cfgbuf, vars[i], val );
        }
    }

	// load defaults for normal compile
    public static void loadDefaults( ConfigurationBuffer cfgbuf ) throws ConfigurationException
    {
	    loadCommonDefaults( cfgbuf );
    }

	// load defaults for compc
    public static void loadCompcDefaults( ConfigurationBuffer cfgbuf ) throws ConfigurationException
	{
		loadCommonDefaults( cfgbuf );
		set( cfgbuf, "compiler.debug", "true" );
		set (cfgbuf, "directory", "false" );
	}

    public static void loadASDocDefaults( ConfigurationBuffer cfgbuf ) throws ConfigurationException
	{
		loadCommonDefaults( cfgbuf );
		set( cfgbuf, "compiler.debug", "false" );	
		set( cfgbuf, "compiler.doc", "true" );
		set( cfgbuf, "output", "asdoc-output" );
		set( cfgbuf, "left-frameset-width", "-1" );
	}

    public static void loadOEMCompcDefaults( ConfigurationBuffer cfgbuf ) throws ConfigurationException
	{
		loadCommonDefaults( cfgbuf );
		set( cfgbuf, "compiler.debug", "true" );
	}

	private static void loadCommonDefaults( ConfigurationBuffer cfgbuf ) throws ConfigurationException
	{
        // specified in case people are using older flex-config.xml
        // also specified in flex-config.xml
        set( cfgbuf, "target-player", "11.1.0" );

	    set( cfgbuf,
	         new String[]
	         {
                 "compiler.accessible",
		         "compiler.es",
	             "compiler.verbose-stacktraces",
	             "compiler.show-dependency-warnings",
	             "compiler.allow-source-path-overlap",
	         }, "false" );

	    set( cfgbuf,
	         new String[]
	         {
                 "compiler.omit-trace-statements",
		         "compiler.optimize",
		         "compiler.strict",
		         "compiler.show-actionscript-warnings",
		         "compiler.as3",
	             "compiler.show-deprecation-warnings",
                 "compiler.show-shadowed-device-font-warnings",
	             "compiler.show-binding-warnings",
	             "compiler.show-multiple-definition-warnings",
			     "compiler.fonts.advanced-anti-aliasing",
		         "use-network",
	         }, "true" );

	    set( cfgbuf, "debug-password", "" );
	    //set( cfgbuf, "framework", "halo" );
        // The Flex 4 default theme.
        set( cfgbuf, "compiler.theme", "${flexlib}/themes/Spark/spark.css" );
	    set( cfgbuf, "compiler.locale", java.util.Locale.getDefault().toString());

	    set( cfgbuf, "default-frame-rate", "24" );
	    set( cfgbuf, "default-background-color", "0xFFFFFF" );

	    LinkedList<String> args = new LinkedList<String>();
	    args.add( "500" );
	    args.add( "375" );
	    cfgbuf.setVar( "default-size", args, "defaults", -1 );

	    args.clear();
	    args.add( "${flexlib}/${configname}-config.xml" );
        // we should probably have a dedicated subclass of DefaultsConfigurator for
        // each product (i.e. webtier doesn't use this var), but for now, this seems
        // like such a seductively easy workaround, lets see if this is adequate:
        if (cfgbuf.isValidVar( "load-config" ))
            cfgbuf.setVar("load-config", args, "defaults", -1, null, false);

        args.clear();
        
	    args.add( "1000" );
	    args.add( "60" );
	    cfgbuf.setVar( "default-script-limits", args, "defaults", -1 );

	    // Fonts
	    set( cfgbuf, "compiler.fonts.max-cached-fonts", "20" );
	    set( cfgbuf, "compiler.fonts.max-glyphs-per-face", "1000" );

	    List<String> fontManagers = new ArrayList<String>();
	    fontManagers.add( "flash.fonts.JREFontManager" );
	    fontManagers.add( "flash.fonts.BatikFontManager" );
	    cfgbuf.setVar( "compiler.fonts.managers", fontManagers, "defaults", -1 );

        String os = System.getProperty("os.name");
        if (os != null)
        {
            os = os.toLowerCase();
            if (os.startsWith( "windows xp") )
                set( cfgbuf, "compiler.fonts.local-fonts-snapshot", "${flexlib}/winFonts.ser" );
            else if (os.startsWith("mac os x"))
                set( cfgbuf, "compiler.fonts.local-fonts-snapshot", "${flexlib}/macFonts.ser" );
            else
                set( cfgbuf, "compiler.fonts.local-fonts-snapshot", "${flexlib}/localFonts.ser" );
	    }
        else
            set( cfgbuf, "compiler.fonts.local-fonts-snapshot", "${flexlib}/localFonts.ser" );
    }
}
