/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.ide.core.ui.nature;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.osbp.ide.core.api.i18n.CoreUtil;
import org.eclipse.osbp.ide.core.ui.builder.OSBPI18nBuilder;
import org.eclipse.osbp.ide.core.ui.builder.OSBPModelEnhancingBuilder;

public class OSBPNature implements IProjectNature {

	public static String NATURE_ID = CoreUtil.NATURE_ID;

	private IProject project;

	public void configure() throws CoreException {
		IProjectDescription desc = project.getDescription();
		ICommand[] commands = desc.getBuildSpec();

		List<ICommand> temp = new ArrayList<ICommand>(Arrays.asList(commands));
		if (!contains(temp, OSBPModelEnhancingBuilder.BUILDER_ID)) {
			ICommand command = desc.newCommand();
			command.setBuilderName(OSBPModelEnhancingBuilder.BUILDER_ID);
			temp.add(command);
		}

		if (!contains(temp, OSBPI18nBuilder.BUILDER_ID)) {
			ICommand command = desc.newCommand();
			command.setBuilderName(OSBPI18nBuilder.BUILDER_ID);
			temp.add(command);
		}

		temp.sort(new Comparator<ICommand>() {
			@Override
			public int compare(ICommand o1, ICommand o2) {
				return getIndex(o1.getBuilderName())
						- getIndex(o2.getBuilderName());
			}

			private int getIndex(String bsn) {
				if (bsn.equals("org.eclipse.xtext.ui.shared.xtextBuilder")) {
					return 0;
				} else if (bsn.startsWith("org.eclipse.osbp")) {
					return 1;
				} else if (bsn.equals("org.eclipse.jdt.core.javabuilder")) {
					return 2;
				}
				return 3;
			}

		});

		desc.setBuildSpec(temp.toArray(new ICommand[temp.size()]));
		project.setDescription(desc, null);
	}

	private boolean contains(List<ICommand> temp, String builderId) {
		for (ICommand cmd : temp) {
			if (cmd.getBuilderName().equals(builderId)) {
				return true;
			}
		}
		return false;
	}

	private void remove(List<ICommand> temp, String builderId) {
		for (Iterator<ICommand> iterator = temp.iterator(); iterator.hasNext();) {
			ICommand iCommand = iterator.next();
			if (iCommand.getBuilderName().equals(builderId)) {
				iterator.remove();
				return;
			}
		}
	}

	public void deconfigure() throws CoreException {
		IProjectDescription description = getProject().getDescription();
		ICommand[] commands = description.getBuildSpec();
		List<ICommand> temp = new ArrayList<ICommand>(Arrays.asList(commands));

		remove(temp, OSBPModelEnhancingBuilder.BUILDER_ID);
		remove(temp, OSBPI18nBuilder.BUILDER_ID);

		description.setBuildSpec(temp.toArray(new ICommand[temp.size()]));
		project.setDescription(description, null);
	}

	public IProject getProject() {
		return project;
	}

	public void setProject(IProject project) {
		this.project = project;
	}

}
