/**
 * This file is part of the Harmony package.
 *
 * (c) Mickael Gaillard <mickael.gaillard@tactfactory.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
package com.tactfactory.harmony;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.regex.Pattern;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import com.google.common.base.Strings;
import com.tactfactory.harmony.command.questionnary.Question;
import com.tactfactory.harmony.command.questionnary.Questionnary;
import com.tactfactory.harmony.meta.ApplicationMetadata;
import com.tactfactory.harmony.plateforme.BaseAdapter;
import com.tactfactory.harmony.plateforme.TargetPlatform;
import com.tactfactory.harmony.plateforme.android.AndroidAdapter;
import com.tactfactory.harmony.plateforme.ios.IosAdapter;
import com.tactfactory.harmony.plateforme.winphone.WinphoneAdapter;
import com.tactfactory.harmony.utils.ConsoleUtils;

/**
 * The project context is the specific configuration of your project.
 * 
 * You can find :
 * <ul><li>Project name;</li>
 * <li>Global name space;</li>
 * <li>SDK version</li>
 * </ul>
 */
public final class ProjectContext {
	// DEMO/TEST MODE
	/** Default project name. */
	private final static String PRJ_NAME = "demact";

    /** Default project NameSpace. */
	private final static String PRJ_NS =
			"com.tactfactory.harmony.test.demact";

	/**
	 * Constructor.
	 */
	public ProjectContext() { }

	/**
	 * Extract Project NameSpace from AndroidManifest file.
	 *
	 * @param manifest Manifest File
	 * @return Project Name Space
	 */
	public static void loadNameSpaceFromManifest(final File manifest) {
		String result = null;
		SAXBuilder builder;
		Document doc;

		if (manifest.exists()) {
			// Make engine
			builder = new SAXBuilder();
			try {
				// Load XML File
				doc = builder.build(manifest);

				// Load Root element
				final Element rootNode = doc.getRootElement();

				// Get Name Space from package declaration
				result = rootNode.getAttributeValue("package");
				result = result.replaceAll("\\.", HarmonyContext.DELIMITER);
			} catch (final JDOMException e) {
				ConsoleUtils.displayError(e);
			} catch (final IOException e) {
				ConsoleUtils.displayError(e);
			}
		}

		if (result != null) {
			ApplicationMetadata.INSTANCE.setName(result.trim());
		}
	}

	/**
	 * Extract Project Name from configuration file.
	 *
	 * @param config Configuration file
	 * @return Project Name Space
	 */
	public static void loadProjectNameFromConfig(final File config) {
		String result = null;
		SAXBuilder builder;
		Document doc;

		if (config.exists()) {
			// Make engine
			builder = new SAXBuilder();
			try {
				// Load XML File
				doc = builder.build(config);
				// Load Root element
				final Element rootNode = doc.getRootElement();
				result = rootNode.getAttribute("name").getValue();
			} catch (final JDOMException e) {
				ConsoleUtils.displayError(e);
			} catch (final IOException e) {
				ConsoleUtils.displayError(e);
			}
		}

		if (result != null) {
			ApplicationMetadata.INSTANCE.setName(result.trim());
		}
	}

	private HashMap<TargetPlatform, BaseAdapter> adapters = 
	        new HashMap<TargetPlatform, BaseAdapter>();
	
	public ArrayList<BaseAdapter> getAdapters() {
	    return new ArrayList<>(this.adapters.values());
	}
	
	public BaseAdapter getAdapter(TargetPlatform platform) {
	    return this.adapters.get(platform);
	}

	public void detectPlatforms() {
	    final File dir = new File(Harmony.getProjectPath());
        final String[] files = dir.list(new FilenameFilter() {
            @Override
            public boolean accept(File current, String name) {
              return new File(current, name).isDirectory();
            }
          });
        final ArrayList<String> directories =
                new ArrayList<String>(Arrays.asList(files));
        Collections.sort(directories);

        for (final String directory : directories) {
            switch (TargetPlatform.parse(directory)) {
            case ANDROID:
                this.adapters.put(
                        TargetPlatform.ANDROID,
                        new AndroidAdapter());
                break;
            case IPHONE :
            case IPAD:
                this.adapters.put(
                        TargetPlatform.IPHONE,
                        new IosAdapter());
                break;
            case RIM:
                //this.adapters.put(TargetPlatform.RIM, new RimAdapter());
                break;
            case WEB:
                //this.adapters.put(TargetPlatform.WEB, new WebAdapter());
                break;
            case WINPHONE:
                this.adapters.put(
                        TargetPlatform.WINPHONE,
                        new WinphoneAdapter());
                break;
            default:
                break;
            }
        }
	}
	
   /**
     * Prompt Project Name to the user.
     * 
     * @param arguments The console arguments passed by the user
     */
    public static void initProjectName(HashMap<String, String> arguments) {
        if (Strings.isNullOrEmpty(ApplicationMetadata.INSTANCE.getName())) {
            final String KEY =  "name";

            Question question = new Question();
            question.setParamName(KEY, "n");
            question.setQuestion("Please enter your Project Name [%s]:", 
                    PRJ_NAME);
            question.setDefaultValue(PRJ_NAME);

            Questionnary questionnary = new Questionnary(arguments);
            questionnary.addQuestion(KEY, question);
            questionnary.launchQuestionnary();
            ApplicationMetadata.INSTANCE.setName(questionnary.getAnswer(KEY));
        }
    }

    /**
     * Prompt Project Name Space to the user.
     * 
     * @param arguments The console arguments passed by the user
     */
    public static void initProjectNameSpace(HashMap<String, String> arguments) {
        if (Strings.isNullOrEmpty(
                ApplicationMetadata.INSTANCE.getProjectNameSpace())) {
            final String KEY =  "namespace";
            String result = null;
            
            Question question = new Question();
            question.setParamName(KEY, "ns");
            question.setQuestion("Please enter your Project NameSpace [%s]:",
                    PRJ_NS);
            question.setDefaultValue(PRJ_NS);
            
            Questionnary questionnary = new Questionnary(arguments);
            questionnary.addQuestion(KEY, question);
            
            boolean good = false;

            while (!good) {
                questionnary.launchQuestionnary();
                String nameSpace = questionnary.getAnswer(KEY);

                if (Strings.isNullOrEmpty(nameSpace)) {
                    good = true;
                } else {

                    final String namespaceForm =
                            "^(((([a-z0-9_]+)\\.)*)([a-z0-9_]+))$";

                    if (Pattern.matches(namespaceForm, nameSpace)) {
                        result = nameSpace.trim();
                        good = true;
                    } else {
                        ConsoleUtils.display(
                                "You can't use special characters "
                                + "except '.' in the NameSpace.");
                        question.setParamName(null);
                        question.setShortParamName(null);
                    }
                }
            }

            if (result != null) {
                ApplicationMetadata.INSTANCE.setProjectNameSpace(
                        result.replaceAll("\\.", HarmonyContext.DELIMITER).trim());
            }
        }
    }
}

@@ -3545,16 +3545,27 @@
 rayList%3C
+BaseAdapter
 %3E(this.a

Fix hudson error