/*******************************************************************************
 * Copyright (c) 2003, 2004 IBM Corporation and others.
 * 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:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
/*
 * Created on Feb 10, 2004
 * 
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package org.eclispe.wst.internal.common.framework.enablement;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclispe.wst.common.framework.enablement.EnablementIdentifierEvent;
import org.eclispe.wst.common.framework.enablement.FunctionGroup;
import org.eclispe.wst.common.framework.enablement.FunctionGroupRegistry;
import org.eclispe.wst.common.framework.enablement.IEnablementIdentifier;
import org.eclispe.wst.common.framework.enablement.IEnablementIdentifierListener;
import org.eclispe.wst.common.framework.enablement.Util;


/**
 * @author schacher
 * 
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
public class EnablementIdentifier implements IEnablementIdentifier {

	private final static int HASH_FACTOR = 89;

	private final static int HASH_INITIAL = EnablementIdentifier.class.getName().hashCode();

	private final static Set strongReferences = new HashSet();

	private Set functionGroupIds;

	private transient String[] functionGroupIdsAsArray;

	private boolean enabled;

	private transient int hashCode;

	private transient boolean hashCodeComputed;

	private String id;

	private List identifierListeners;

	private transient String string;

	private IProject project;

	protected EnablementIdentifier(String id) {
		this(id, null);
	}

	protected EnablementIdentifier(String id, IProject project) {
		if (id == null)
			throw new NullPointerException();
		this.id = id;
		this.project = project;
	}

	public void addIdentifierListener(IEnablementIdentifierListener identifierListener) {
		if (identifierListener == null)
			throw new NullPointerException();

		if (identifierListeners == null)
			identifierListeners = new ArrayList();

		if (!identifierListeners.contains(identifierListener))
			identifierListeners.add(identifierListener);

		strongReferences.add(this);
	}

	public int compareTo(Object object) {
		EnablementIdentifier castedObject = (EnablementIdentifier) object;
		return Util.compare(id, castedObject.id);

	}

	public boolean equals(Object object) {
		if (!(object instanceof EnablementIdentifier))
			return false;

		EnablementIdentifier castedObject = (EnablementIdentifier) object;
		boolean equals = Util.equals(id, castedObject.id);
		return equals;
	}

	protected void fireIdentifierChanged(EnablementIdentifierEvent functionIdentifierEvent) {
		if (functionIdentifierEvent == null)
			throw new NullPointerException();

		if (identifierListeners != null) {
			synchronized (identifierListeners) {
				for (int i = 0; i < identifierListeners.size(); i++)
					((IEnablementIdentifierListener) identifierListeners.get(i)).identifierChanged(functionIdentifierEvent);
			}
		}
	}

	public Set getFunctionGroupIds() {
		return functionGroupIds;
	}

	public String getId() {
		return id;
	}

	public int hashCode() {
		if (!hashCodeComputed) {
			hashCode = HASH_INITIAL;
			hashCode = hashCode * HASH_FACTOR + Util.hashCode(id);
			hashCodeComputed = true;
		}

		return hashCode;
	}

	public boolean isEnabled() {
		return enabled;
	}

	public void removeIdentifierListener(IEnablementIdentifierListener identifierListener) {
		if (identifierListener == null)
			throw new NullPointerException();

		if (identifierListeners != null)
			identifierListeners.remove(identifierListener);

		if (identifierListeners.isEmpty())
			strongReferences.remove(this);
	}

	protected boolean setFunctionGroupIds(Set functionGroupIds) {
		functionGroupIds = Util.safeCopy(functionGroupIds, String.class);

		if (!Util.equals(functionGroupIds, this.functionGroupIds)) {
			this.functionGroupIds = functionGroupIds;
			this.functionGroupIdsAsArray = (String[]) this.functionGroupIds.toArray(new String[this.functionGroupIds.size()]);

			hashCodeComputed = false;
			hashCode = 0;
			string = null;
			return true;
		}

		return false;
	}

	protected boolean setEnabled(boolean enabled) {
		if (enabled != this.enabled) {
			this.enabled = enabled;
			hashCodeComputed = false;
			hashCode = 0;
			string = null;
			return true;
		}

		return false;
	}

	/**
	 * Recompute the enabled state and return whether the state changed
	 */
	protected boolean resetEnabled() {
		return setEnabled(getNewEnabled());
	}

	protected boolean getNewEnabled() {
		if (project == null)
			return true;
		if (functionGroupIdsAsArray.length == 0)
			return true;
		for (int i = 0; i < functionGroupIdsAsArray.length; i++) {
			FunctionGroup group = FunctionGroupRegistry.getInstance().getGroupByID(functionGroupIdsAsArray[i]);
			if (group != null && group.isEnabled(project))
				return true;
		}
		return false;
	}

	public String toString() {
		if (string == null) {
			final StringBuffer stringBuffer = new StringBuffer();
			stringBuffer.append('[');
			stringBuffer.append(functionGroupIds);
			stringBuffer.append(',');
			stringBuffer.append(enabled);
			stringBuffer.append(',');
			stringBuffer.append(id);
			stringBuffer.append(']');
			string = stringBuffer.toString();
		}

		return string;
	}

	/**
	 * The associated Project may be null
	 * 
	 * @return Returns the project.
	 */
	public IProject getProject() {
		return project;
	}

	public String getPrimaryFunctionGroupId() {
		int selectedPriority = Integer.MAX_VALUE;
		int priority = 0;
		String selectedFunctionGroupId = null;
		String functionGroupId = null;
		for (Iterator iterator = getFunctionGroupIds().iterator(); iterator.hasNext();) {
			functionGroupId = iterator.next().toString();
			priority = FunctionGroupRegistry.getInstance().getGroupPriority(functionGroupId);
			if (priority < selectedPriority)
				selectedFunctionGroupId = functionGroupId;
			if (priority == 0)
				return selectedFunctionGroupId;
		}
		return selectedFunctionGroupId;
	}

}