/*******************************************************************************
 * Copyright (c) 2000, 2005 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.debug.internal.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.Map.Entry;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.Platform;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILogicalStructureType;
import org.eclipse.debug.core.model.IValue;

/**
 * Manages logical structure extensions
 * 
 * @since 3.0
 */
public class LogicalStructureManager {

	private static LogicalStructureManager fgDefault;
	private List fTypes = null;
	private List fTypeProviders;

    /**
     * Map containing the user's selection for each combination of logical
     * structure types.
     * key: String - Comma-separated list of ints representing a combination of structure types.
     *               These integers are indeces into the fStructureTypeIds array.
     * value: Integer - One of the ints from the combo key (the one chosen by the user) or -1 if
     *                  the user has chosen not to display any structures for this combination
     */
    private Map fStructureTypeSelections= null;
    /**
     * List of known type identifiers. An identifier's index in this list is used as
     * its ID number. This list is maintained as a space-saving measure so that the various
     * combinations of structure types can be persisted using indeces instead of storing the
     * full index strings.
     */
    private List fStructureTypeIds= null;
    
    /**
     * Preference key used for storing the user's selected structure for each combination
     * or structures. The preference value is stored in the form:
     * int,int,...,int|int,int,...int|...
     * Where int is an integer index of a structure in the array of known structures.
     */
    public static final String PREF_STRUCTURE_SELECTIONS= "selectedStructures"; //$NON-NLS-1$
    /**
     * Preference key used for storing the array of known structures. The preference
     * value is in the form:
     * string,string,string,...,string,
     * Where string is an identifier of a logical structure.
     */
    public static final String PREF_STRUCTURE_IDS= "allStructures"; //$NON-NLS-1$
	
	public static LogicalStructureManager getDefault() {
		if (fgDefault == null) {
			fgDefault = new LogicalStructureManager();
		}
		return fgDefault;
	}
	
    /**
     * Returns the logical structure types that are applicable to the given value.
     * @param value the value
     * @return the logical structure types that are applicable to the given value
     */
	public ILogicalStructureType[] getLogicalStructureTypes(IValue value) {
		initialize();
		// looks in the logical structure types
		Iterator iterator = fTypes.iterator();
		List select = new ArrayList();
		while (iterator.hasNext()) {
			ILogicalStructureType type = (ILogicalStructureType)iterator.next();
			if (type.providesLogicalStructure(value)) {
				select.add(type);
			}
		}
		// asks the logical structure providers
		for (Iterator iter= fTypeProviders.iterator(); iter.hasNext();) {
			ILogicalStructureType[] logicalStructures= ((LogicalStructureProvider) iter.next()).getLogicalStructures(value);
			for (int i= 0; i < logicalStructures.length; i++) {
				select.add(logicalStructures[i]);
			}
		}
		return (ILogicalStructureType[]) select.toArray(new ILogicalStructureType[select.size()]);
	}
    
    /**
     * Loads the map of structure selections from the preference store.
     */
    private void loadStructureTypeSelections() {
        fStructureTypeSelections= new HashMap();
        String selections= DebugPlugin.getDefault().getPluginPreferences().getString(PREF_STRUCTURE_SELECTIONS);
    	// selections are stored in the form:
    	// selection|selection|...selection|
        StringTokenizer tokenizer= new StringTokenizer(selections, "|"); //$NON-NLS-1$
        while (tokenizer.hasMoreTokens()) {
            String selection = tokenizer.nextToken();
            // selection string is of the form:
            // id,id,...,selectedid
            int i = selection.lastIndexOf(',');
            if (i > 0 && i < selection.length() - 1) {
                String comboKey= selection.substring(0, i + 1);
                String selected= selection.substring(i + 1, selection.length());
                fStructureTypeSelections.put(comboKey, new Integer(Integer.parseInt(selected)));
            }
        }
    }
    
    /**
     * Stores the map of structure selections to the preference store
     */
    private void storeStructureTypeSelections() {
        StringBuffer buffer= new StringBuffer();
        Iterator iter = fStructureTypeSelections.entrySet().iterator();
        while (iter.hasNext()) {
            Map.Entry entry = (Entry) iter.next();
            buffer.append(entry.getKey());
            buffer.append(entry.getValue());
            buffer.append('|');
        }
        DebugPlugin.getDefault().getPluginPreferences().setValue(PREF_STRUCTURE_SELECTIONS, buffer.toString());
    }
    
    /**
     * Loads the collection of known structures identifiers from the preference store
     */
    private void loadStructureTypeIds() {
        fStructureTypeIds= new ArrayList();
    	// Types are stored as a comma-separated, ordered list.
        String types= DebugPlugin.getDefault().getPluginPreferences().getString(PREF_STRUCTURE_IDS);
        StringTokenizer tokenizer= new StringTokenizer(types, ","); //$NON-NLS-1$
        while (tokenizer.hasMoreTokens()) {
            String id= tokenizer.nextToken();
            if (id.length() > 0) {
                fStructureTypeIds.add(id);
            }
        }
    }
    
    /**
     * Stores the collection of known structure identifiers to the preference store
     */
    private void storeStructureTypeIds() {
        StringBuffer buffer= new StringBuffer();
        Iterator iter = fStructureTypeIds.iterator();
        while (iter.hasNext()) {
            buffer.append(iter.next()).append(',');
        }
        DebugPlugin.getDefault().getPluginPreferences().setValue(PREF_STRUCTURE_IDS, buffer.toString());
    }
    
    /**
     * Returns the structure that the user has chosen from among the given
     * collection of structures or <code>null</code> if the user has chosen
     * to display none.
     * @param structures the collection of structures available
     * @return the structure that the user has chosen from among the given collection
     *  or <code>null</code> if the user has chosen to display none
     */
    public ILogicalStructureType getSelectedStructureType(ILogicalStructureType[] structureTypes) {
        if (structureTypes.length == 0) {
            return null;
        }
        String combo= getComboString(structureTypes);
        // Lookup the combo
        Integer index = (Integer) fStructureTypeSelections.get(combo);
        if (index == null) {
            // If the user hasn't explicitly chosen anything for this
            // combo yet, just return the first type.
            return structureTypes[0];
        } else if (index.intValue() == -1) {
            // An index of -1 means the user has deselected all structures for this combo
            return null;
        }
        // If an index is stored for this combo, retrieve the id at the index
        String id= (String) fStructureTypeIds.get(index.intValue());
        for (int i = 0; i < structureTypes.length; i++) {
            // Return the type with the retrieved id
            ILogicalStructureType type = structureTypes[i];
            if (type.getId().equals(id)) {
                return type;
            }
        }
        return structureTypes[0];
    }
    
    /**
     * 
     * @param types
     * @param selected the type that is selected for the given combo or <code>null</code>
     *  if the user has deselected any structure for the given combo
     */
    public void setEnabledType(ILogicalStructureType[] types, ILogicalStructureType selected) {
        String combo= getComboString(types);
        int index= -1; // Initialize to "none selected"
        if (selected != null) {
            index= fStructureTypeIds.indexOf(selected.getId());
        }
        Integer integer= new Integer(index);
        fStructureTypeSelections.put(combo, integer);
        storeStructureTypeSelections();
        storeStructureTypeIds();
        DebugPlugin.getDefault().savePluginPreferences();
    }
    
    /**
     * Returns the string representing the given combination of logical
     * structure types. This string will be a series of comma-separated
     * indeces representing the various types. If any of the given types
     * don't have indeces associated with them, this method will create
     * the appropriate index.
     * @param types the logical structure types
     * @return the string representing the given combination of logical
     *  structure types
     */
    protected String getComboString(ILogicalStructureType[] types) {
        StringBuffer comboKey= new StringBuffer();
        for (int i = 0; i < types.length; i++) {
            ILogicalStructureType type = types[i];
            int typeIndex = fStructureTypeIds.indexOf(type.getId());
            if (typeIndex == -1) {
                typeIndex= fStructureTypeIds.size();
                fStructureTypeIds.add(type.getId());
            }
            comboKey.append(typeIndex).append(',');
        }
        return comboKey.toString();
    }
	
	private void initialize() {
		if (fTypes == null) {
			//get the logical structure types from the extension points
			IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), DebugPlugin.EXTENSION_POINT_LOGICAL_STRUCTURE_TYPES);
			IConfigurationElement[] extensions = point.getConfigurationElements();
			fTypes = new ArrayList(extensions.length);
			for (int i = 0; i < extensions.length; i++) {
				IConfigurationElement extension = extensions[i];
				LogicalStructureType type;
				try {
					type = new LogicalStructureType(extension);
					fTypes.add(type);
				} catch (CoreException e) {
					DebugPlugin.log(e);
				}
			}
			// get the logical structure providers from the extension point
			point= Platform.getExtensionRegistry().getExtensionPoint(DebugPlugin.getUniqueIdentifier(), DebugPlugin.EXTENSION_POINT_LOGICAL_STRUCTURE_PROVIDERS);
			extensions= point.getConfigurationElements();
			fTypeProviders= new ArrayList(extensions.length);
			for (int i= 0; i < extensions.length; i++) {
				try {
					fTypeProviders.add(new LogicalStructureProvider(extensions[i]));
				} catch (CoreException e) {
					DebugPlugin.log(e);
				}
			}
		}
        if (fStructureTypeSelections == null) {
            loadStructureTypeSelections();
        }
        if (fStructureTypeIds == null) {
            loadStructureTypeIds();
        }
	}
}
