/***************************************************************************************************
 * 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
 **************************************************************************************************/
package org.eclipse.wst.common.frameworks.internal.datamodel;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.commands.operations.IUndoableOperation;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.wst.common.frameworks.datamodel.DataModelEvent;
import org.eclipse.wst.common.frameworks.datamodel.DataModelPropertyDescriptor;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelListener;
import org.eclipse.wst.common.frameworks.datamodel.IDataModelProvider;
import org.eclipse.wst.common.frameworks.internal.WTPResourceHandler;

public final class DataModelImpl implements IDataModel, IDataModelListener {

	private static final String PROPERTY_NOT_LOCATED_ = WTPResourceHandler.getString("20"); //$NON-NLS-1$
	private static final String NESTED_MODEL_NOT_LOCATED = WTPResourceHandler.getString("21"); //$NON-NLS-1$

	private Collection basePropertyNames;
	private Collection allPropertyNames;
	private Collection nestedPropertyNames; // lazily initialzed when nested models added
	private Map propertyValues = new Hashtable();
	private Map nestedModels;
	private Set nestingModels;
	private List listeners;

	private IDataModelProvider provider;

	public DataModelImpl(IDataModelProvider dataModelProvider) {
		init(dataModelProvider);
	}

	private void init(IDataModelProvider dataModelProvider) {
		this.provider = dataModelProvider;
		dataModelProvider.setDataModel(this);
		String[] propertyNames = dataModelProvider.getPropertyNames();
		HashSet properties = new HashSet();
		for (int i = 0; null != propertyNames && i < propertyNames.length; i++) {
			properties.add(propertyNames[i]);
		}
		basePropertyNames = Collections.unmodifiableCollection(properties);
		allPropertyNames = new HashSet();
		allPropertyNames.addAll(basePropertyNames);
		dataModelProvider.init();
	}

	public boolean isBaseProperty(String propertyName) {
		return basePropertyNames.contains(propertyName);
	}

	public Collection getBaseProperties() {
		return Collections.unmodifiableCollection(basePropertyNames);
	}

	public boolean isProperty(String propertyName) {
		return allPropertyNames.contains(propertyName);
	}

	public Collection getAllProperties() {
		return Collections.unmodifiableCollection(allPropertyNames);
	}

	public boolean isNestedProperty(String propertyName) {
		return null != nestedPropertyNames && nestedPropertyNames.contains(propertyName);
	}

	public Collection getNestedProperties() {
		return Collections.unmodifiableCollection(nestedPropertyNames);
	}

	private void checkValidPropertyName(String propertyName) {
		if (!isProperty(propertyName)) {
			throw new RuntimeException(PROPERTY_NOT_LOCATED_ + propertyName);
		}
	}

	private DataModelImpl getOwningDataModel(String propertyName) {
		checkValidPropertyName(propertyName);
		return searchNestedModels(propertyName);
	}

	private DataModelImpl searchNestedModels(String propertyName) {
		if (isBaseProperty(propertyName)) {
			return this;
		} else if (nestedModels != null) {
			DataModelImpl dataModel = null;
			Object[] keys = nestedModels.keySet().toArray();
			for (int i = 0; i < keys.length; i++) {
				dataModel = (DataModelImpl) nestedModels.get(keys[i]);
				if (dataModel.isProperty(propertyName)) {
					return dataModel.searchNestedModels(propertyName);
				}
			}
		}
		throw new RuntimeException(PROPERTY_NOT_LOCATED_ + propertyName);
	}

	public Object getProperty(String propertyName) {
		DataModelImpl dataModel = getOwningDataModel(propertyName);
		if (dataModel.propertyValues.containsKey(propertyName)) {
			return dataModel.propertyValues.get(propertyName);
		}
		return dataModel.provider.getDefaultProperty(propertyName);
	}

	public Object getDefaultProperty(String propertyName) {
		DataModelImpl dataModel = getOwningDataModel(propertyName);
		return dataModel.provider.getDefaultProperty(propertyName);
	}

	public int getIntProperty(String propertyName) {
		Object prop = getProperty(propertyName);
		if (prop == null)
			return -1;
		return ((Integer) prop).intValue();
	}

	public boolean getBooleanProperty(String propertyName) {
		Object prop = getProperty(propertyName);
		if (prop == null)
			return false;
		return ((Boolean) prop).booleanValue();
	}

	public String getStringProperty(String propertyName) {
		Object prop = getProperty(propertyName);
		if (prop == null)
			return ""; //$NON-NLS-1$
		return (String) prop;
	}

	public boolean isPropertySet(String propertyName) {
		DataModelImpl dataModel = getOwningDataModel(propertyName);
		return dataModel.propertyValues.containsKey(propertyName);
	}

	public boolean isPropertyEnabled(String propertyName) {
		DataModelImpl dataModel = getOwningDataModel(propertyName);
		return dataModel.provider.isPropertyEnabled(propertyName);
	}


	public void setProperty(String propertyName, Object propertyValue) {
		DataModelImpl dataModel = getOwningDataModel(propertyName);
		dataModel.internalSetProperty(propertyName, propertyValue);
	}

	private void internalSetProperty(String propertyName, Object propertyValue) {
		Object oldValue = propertyValues.get(propertyName);
		if (valueChanged(propertyValue, oldValue)) {
			if (null != propertyValue)
				propertyValues.put(propertyName, propertyValue);
			else if (propertyValues.containsKey(propertyName))
				propertyValues.remove(propertyName);
			if (provider.propertySet(propertyName, propertyValue)) {
				notifyPropertyChange(propertyName, DataModelEvent.VALUE_CHG);
			}
		}
	}

	private boolean valueChanged(Object o1, Object o2) {
		return o1 != o2 && ((o1 != null && !o1.equals(o2)) || !o2.equals(o1));
	}

	public void setIntProperty(String propertyName, int value) {
		setProperty(propertyName, new Integer(value));
	}

	public void setBooleanProperty(String propertyName, boolean value) {
		setProperty(propertyName, (value) ? Boolean.TRUE : Boolean.FALSE);
	}

	public void setStringProperty(String propertyName, String value) {
		setProperty(propertyName, value);
	}

	public boolean addNestedModel(String modelName, IDataModel dataModel) {
		if (this == dataModel) {
			return false;
		}
		if (null == nestedModels) {
			nestedModels = new Hashtable();
			nestedPropertyNames = new HashSet();
		}
		DataModelImpl nestedDataModel = (DataModelImpl) dataModel;
		if (null == nestedDataModel.nestingModels) {
			nestedDataModel.nestingModels = new HashSet();
		}
		if (nestedDataModel.nestingModels.contains(this)) {
			return false;
		}
		nestedDataModel.nestingModels.add(this);

		nestedModels.put(modelName, nestedDataModel);

		addNestedProperties(nestedDataModel.allPropertyNames);
		nestedDataModel.addListener(this);
		return true;
	}

	private void addNestedProperties(Collection nestedProperties) {
		boolean propertiesAdded = allPropertyNames.addAll(nestedProperties);
		propertiesAdded = nestedPropertyNames.addAll(nestedProperties) || propertiesAdded;
		// Pass the new properties up the nesting chain
		if (propertiesAdded && nestingModels != null) {
			Iterator iterator = nestingModels.iterator();
			while (iterator.hasNext()) {
				((DataModelImpl) iterator.next()).addNestedProperties(nestedProperties);
			}
		}
	}

	public Collection getNestedModels() {
		return nestedModels != null ? Collections.unmodifiableCollection(nestedModels.values()) : Collections.EMPTY_SET;
	}

	public Collection getNestedModelNames() {
		return nestedModels != null ? Collections.unmodifiableCollection(nestedModels.keySet()) : Collections.EMPTY_SET;
	}

	public Collection getNestingModels() {
		return nestingModels != null ? Collections.unmodifiableCollection(nestingModels) : Collections.EMPTY_SET;
	}

	public IDataModel removeNestedModel(String modelName) {
		if (!isNestedModel(modelName)) {
			return null;
		}
		DataModelImpl model = (DataModelImpl) nestedModels.remove(modelName);
		model.nestingModels.remove(this);
		removeNestedProperties(model.allPropertyNames);
		model.removeListener(this);
		if (nestedModels.isEmpty()) {
			nestedModels = null;
		}
		return model;
	}

	private void removeNestedProperties(Collection nestedProperties) {
		Iterator iterator = nestedProperties.iterator();
		String property = null;
		boolean keepProperty = false;
		Set nestedPropertiesToRemove = null;
		while (iterator.hasNext()) {
			keepProperty = false;
			property = (String) iterator.next();
			if (basePropertyNames.contains(property)) {
				keepProperty = true;
			}
			if (!keepProperty && nestedModels != null) {
				Iterator nestedModelsIterator = nestedModels.values().iterator();
				while (!keepProperty && nestedModelsIterator.hasNext()) {
					DataModelImpl nestedModel = (DataModelImpl) nestedModelsIterator.next();
					if (nestedModel.isProperty(property)) {
						keepProperty = true;
					}
				}
			}
			if (!keepProperty) {
				if (null == nestedPropertiesToRemove) {
					nestedPropertiesToRemove = new HashSet();
				}
				nestedPropertiesToRemove.add(property);
			}
		}

		if (null != nestedPropertiesToRemove) {
			allPropertyNames.removeAll(nestedPropertiesToRemove);
			nestedPropertyNames.removeAll(nestedPropertiesToRemove);
			if (nestingModels != null) {
				Iterator nestingModelsIterator = nestingModels.iterator();
				while (nestingModelsIterator.hasNext()) {
					((DataModelImpl) nestingModelsIterator.next()).removeNestedProperties(nestedPropertiesToRemove);
				}
			}
		}
	}

	public boolean isNestedModel(String modelName) {
		return modelName != null && null != nestedModels && nestedModels.containsKey(modelName);
	}

	public IDataModel getNestedModel(String modelName) {
		IDataModel dataModel = (null != nestedModels && null != modelName) ? (IDataModel) nestedModels.get(modelName) : null;
		if (null == dataModel) {
			throw new RuntimeException(NESTED_MODEL_NOT_LOCATED + modelName);
		}
		return dataModel;
	}

	public DataModelPropertyDescriptor[] getValidPropertyDescriptors(String propertyName) {
		DataModelImpl dataModel = getOwningDataModel(propertyName);
		DataModelPropertyDescriptor[] descriptors = dataModel.provider.getValidPropertyDescriptors(propertyName);
		return descriptors == null ? new DataModelPropertyDescriptor[0] : descriptors;
	}

	public DataModelPropertyDescriptor getPropertyDescriptor(String propertyName) {
		DataModelImpl dataModel = getOwningDataModel(propertyName);
		DataModelPropertyDescriptor descriptor = dataModel.provider.getPropertyDescriptor(propertyName);
		return descriptor == null ? new DataModelPropertyDescriptor(getProperty(propertyName)) : descriptor;
	}

	public void notifyPropertyChange(String propertyName, int flag) {
		if (flag == DEFAULT_CHG) {
			if (isPropertySet(propertyName)) {
				return;
			} else
				flag = VALUE_CHG;
		}
		notifyListeners(new DataModelEvent(this, propertyName, flag));
	}

	private void notifyListeners(DataModelEvent event) {
		if (listeners != null && !listeners.isEmpty()) {
			IDataModelListener listener;
			for (int i = 0; i < listeners.size(); i++) {
				listener = (IDataModelListener) listeners.get(i);
				if (listener != event.getDataModel()) {
					listener.propertyChanged(event);
				}
			}
		}
	}

	public void propertyChanged(DataModelEvent event) {
		notifyListeners(event);
	}

	public IStatus validate() {
		return validate(true);
	}

	public IStatus validate(boolean stopOnFirstFailure) {
		IStatus status = null;
		IStatus propStatus;
		String propName;
		Iterator it;
		for (int i = 0; i < 2; i++) {
			switch (i) {
				case 0 :
					it = basePropertyNames.iterator();
					break;
				case 1 :
				default :
					it = getNestedModelNames().iterator();
			}
			while (it.hasNext()) {
				propName = (String) it.next();
				propStatus = provider.validate(propName);
				if (status == null || status.isOK())
					status = propStatus;
				else {
					if (status.isMultiStatus())
						((MultiStatus) status).merge(propStatus);
					else {
						MultiStatus multi = new MultiStatus("org.eclipse.wst.common.frameworks.internal", 0, "", null); //$NON-NLS-1$ //$NON-NLS-2$
						multi.merge(status);
						multi.merge(propStatus);
						status = multi;
					}
				}
				if (stopOnFirstFailure && status != null && !status.isOK() && status.getSeverity() == IStatus.ERROR)
					return status;
			}
		}

		if (status == null)
			return IDataModelProvider.OK_STATUS;
		return status;
	}

	public void addListener(IDataModelListener listener) {
		if (listener != null) {
			if (listeners == null) {
				listeners = new ArrayList();
				listeners.add(listener);
			} else if (!listeners.contains(listener))
				listeners.add(listener);
		}
	}

	public void removeListener(IDataModelListener listener) {
		if (listeners != null && listener != null)
			listeners.remove(listener);
	}

	/**
	 * Return true if the model doesn't have any errors.
	 * 
	 * @return boolean
	 */
	public boolean isValid() {
		return validate(true).getSeverity() != IStatus.ERROR;
	}

	public boolean isPropertyValid(String propertyName) {
		return validateProperty(propertyName).getSeverity() != IStatus.ERROR;
	}

	public IStatus validateProperty(String propertyName) {
		DataModelImpl dataModel = getOwningDataModel(propertyName);
		IStatus status = dataModel.provider.validate(propertyName);
		return status == null ? IDataModelProvider.OK_STATUS : status;
	}

	public List getExtendedContext() {
		List extendedContext = provider.getExtendedContext();
		return extendedContext == null ? Collections.EMPTY_LIST : extendedContext;
	}

	public void dispose() {
		provider.dispose();
	}

	public IUndoableOperation getDefaultOperation() {
		return new ExtendableOperationImpl(provider.getDefaultOperation());
	}

	public String toString() {
		return "IDataModel, provider=" + provider.toString();
	}

	public String getID() {
		String id = provider.getID();
		return null != id ? id : "";
	}
}