/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.compare.examples.xml;

import java.util.*;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;

import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.*;
import org.eclipse.jface.window.Window;

import org.eclipse.ui.*;

/**
 * The XMLComparePreferencePage is the page used to set ID Mappings for XML Compare
 */
public class XMLComparePreferencePage	extends PreferencePage implements IWorkbenchPreferencePage, Listener {

	private Table fIdMapsTable;
	private Button fAddIdMapButton;
	private Button fRenameIdMapButton;
	private Button fRemoveIdMapButton;
	private Button fEditIdMapButton;

	private Table fMappingsTable;
	private Button fNewMappingsButton;
	private Button fEditMappingsButton;
	private Button fRemoveMappingsButton;

	private Table fOrderedTable;
	private Button fNewOrderedButton;
	private Button fEditOrderedButton;
	private Button fRemoveOrderedButton;

	private HashMap fIdMapsInternal;
	private HashMap fIdMaps;// HashMap ( idname -> HashMap (signature -> id) )
	private HashMap fIdExtensionToName;
	
	//fOrderedElements contains signature of xml element whose children must be compared in ordered fashion
	private HashMap fOrderedElements;// HashMap ( idname -> ArrayList (signature) )
	private HashMap fOrderedElementsInternal;
	
	protected static char[] invalidCharacters;
	protected static final char SIGN_SEPARATOR = XMLStructureCreator.SIGN_SEPARATOR;

	public static String IDTYPE_ATTRIBUTE= XMLCompareMessages.getString("XMLComparePreference.idtype.attribute"); //$NON-NLS-1$
	public static String IDTYPE_CHILDBODY= XMLCompareMessages.getString("XMLComparePreference.idtype.child_body"); //$NON-NLS-1$

	
	static {
		invalidCharacters = new char[] {XMLPlugin.IDMAP_SEPARATOR,XMLPlugin.IDMAP_FIELDS_SEPARATOR,XMLStructureCreator.SIGN_ENCLOSING};
	}

	
	public XMLComparePreferencePage() {
		super();
		
		fIdMaps = new HashMap();
		XMLPlugin plugin= XMLPlugin.getDefault();
		HashMap PluginIdMaps = plugin.getIdMaps();
		Set keySet = PluginIdMaps.keySet();
		for (Iterator iter = keySet.iterator(); iter.hasNext(); ) {
			String key = (String) iter.next();
			fIdMaps.put(key, ((HashMap)PluginIdMaps.get(key)).clone() );
		}
		fIdMapsInternal = plugin.getIdMapsInternal();
		
		fIdExtensionToName= new HashMap();
		HashMap PluginIdExtensionToName= plugin.getIdExtensionToName();
		keySet= PluginIdExtensionToName.keySet();
		for (Iterator iter= keySet.iterator(); iter.hasNext(); ) {
			String key= (String) iter.next();
			fIdExtensionToName.put(key, PluginIdExtensionToName.get(key));
		}
		
		fOrderedElements= new HashMap();
		HashMap PluginOrderedElements= plugin.getOrderedElements();
		keySet= PluginOrderedElements.keySet();
		for (Iterator iter= keySet.iterator(); iter.hasNext();) {
			String key= (String) iter.next();
			fOrderedElements.put(key, ((ArrayList)PluginOrderedElements.get(key)).clone());
		}
		
		fOrderedElementsInternal= plugin.getOrderedElementsInternal();
	}

	/**
	 * @see PreferencePage#createContents(Composite)
	 */
	protected Control createContents(Composite ancestor) {
		Composite parent= new Composite(ancestor, SWT.NULL);
		GridLayout layout= new GridLayout();
		layout.numColumns= 2;
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		parent.setLayout(layout);				
		
		//layout the top table & its buttons
		Label label = new Label(parent, SWT.LEFT);
		label.setText(XMLCompareMessages.getString("XMLComparePreference.topTableLabel")); //$NON-NLS-1$
		GridData data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.horizontalSpan = 2;
		label.setLayoutData(data);
	
		fIdMapsTable = new Table(parent, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);
		fIdMapsTable.setHeaderVisible(true);	
		data = new GridData(GridData.FILL_BOTH);
		data.heightHint = fIdMapsTable.getItemHeight()*4;
		fIdMapsTable.setLayoutData(data);
		fIdMapsTable.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				selectionChanged();
			}
		});

		String column2Text= XMLCompareMessages.getString("XMLComparePreference.topTableColumn2"); //$NON-NLS-1$
		String column3Text= XMLCompareMessages.getString("XMLComparePreference.topTableColumn3"); //$NON-NLS-1$
		ColumnLayoutData columnLayouts[]= {
			new ColumnWeightData(1),
			new ColumnPixelData(convertWidthInCharsToPixels(column2Text.length()+2), true),
			new ColumnPixelData(convertWidthInCharsToPixels(column3Text.length()+5), true)};
		TableLayout tablelayout = new TableLayout();
		fIdMapsTable.setLayout(tablelayout);
		for (int i=0; i<3; i++)
			tablelayout.addColumnData(columnLayouts[i]);
		TableColumn column = new TableColumn(fIdMapsTable, SWT.NONE);
		column.setText(XMLCompareMessages.getString("XMLComparePreference.topTableColumn1")); //$NON-NLS-1$
		column = new TableColumn(fIdMapsTable, SWT.NONE);
		column.setText(column2Text); //$NON-NLS-1$
		column = new TableColumn(fIdMapsTable, SWT.NONE);
		column.setText(column3Text); //$NON-NLS-1$
		
		fillIdMapsTable();

		Composite buttons= new Composite(parent, SWT.NULL);
		buttons.setLayout(new GridLayout());
		data = new GridData();
		data.verticalAlignment = GridData.FILL;
		data.horizontalAlignment = GridData.FILL;
		buttons.setLayoutData(data);

		fAddIdMapButton = new Button(buttons, SWT.PUSH);
		fAddIdMapButton.setText(XMLCompareMessages.getString("XMLComparePreference.topAdd")); //$NON-NLS-1$
		fAddIdMapButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				addIdMap(fAddIdMapButton.getShell());
			}
		});
		data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.heightHint = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
		int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
		data.widthHint = Math.max(widthHint, fAddIdMapButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
		fAddIdMapButton.setLayoutData(data);
	
		fRenameIdMapButton = new Button(buttons, SWT.PUSH);
		fRenameIdMapButton.setText(XMLCompareMessages.getString("XMLComparePreference.topRename")); //$NON-NLS-1$
		fRenameIdMapButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				renameIdMap(fRenameIdMapButton.getShell());
			}
		});
		data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.heightHint = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
		widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
		data.widthHint = Math.max(widthHint, fAddIdMapButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
		fRenameIdMapButton.setLayoutData(data);

		fRemoveIdMapButton = new Button(buttons, SWT.PUSH);
		fRemoveIdMapButton.setText(XMLCompareMessages.getString("XMLComparePreference.topRemove")); //$NON-NLS-1$
		fRemoveIdMapButton.addSelectionListener(new SelectionAdapter() {
		public void widgetSelected(SelectionEvent e) {
				removeIdMap(fRemoveIdMapButton.getShell());
			}
		});
		data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.heightHint = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
			widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
		data.widthHint = Math.max(widthHint, fRemoveIdMapButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
		fRemoveIdMapButton.setLayoutData(data);

		createSpacer(buttons);

		fEditIdMapButton = new Button(buttons, SWT.PUSH);
		fEditIdMapButton.setText(XMLCompareMessages.getString("XMLComparePreference.topEdit")); //$NON-NLS-1$
		fEditIdMapButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				editIdMap(fEditIdMapButton.getShell());
			}
		});
		data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.heightHint = convertVerticalDLUsToPixels(IDialogConstants.BUTTON_HEIGHT);
		widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
		data.widthHint = Math.max(widthHint, fEditIdMapButton.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
		fEditIdMapButton.setLayoutData(data);
	
		//Spacer
		label = new Label(parent, SWT.LEFT);
		data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.horizontalSpan = 2;
		label.setLayoutData(data);

		//layout the middle table & its buttons
		label = new Label(parent, SWT.LEFT);
		label.setText(XMLCompareMessages.getString("XMLComparePreference.middleTableLabel")); //$NON-NLS-1$
		data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.horizontalSpan = 2;
		label.setLayoutData(data);

		fMappingsTable = new Table(parent, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);
		fMappingsTable.setHeaderVisible(true);	
		data = new GridData(GridData.FILL_BOTH);
		data.heightHint = fMappingsTable.getItemHeight()*4;
		data.widthHint= convertWidthInCharsToPixels(70);
		fMappingsTable.setLayoutData(data);
		
		column3Text= XMLCompareMessages.getString("XMLComparePreference.middleTableColumn3"); //$NON-NLS-1$
		String column4Text= XMLCompareMessages.getString("XMLComparePreference.middleTableColumn4"); //$NON-NLS-1$
		columnLayouts= new ColumnLayoutData[] {
			new ColumnWeightData(10),
			new ColumnWeightData(18),
			new ColumnPixelData(convertWidthInCharsToPixels(column3Text.length()+1), true),
			new ColumnPixelData(convertWidthInCharsToPixels(column4Text.length()+3), true)};
		tablelayout = new TableLayout();
		fMappingsTable.setLayout(tablelayout);
		for (int i=0; i<4; i++)
			tablelayout.addColumnData(columnLayouts[i]);
		column = new TableColumn(fMappingsTable, SWT.NONE);
		column.setText(XMLCompareMessages.getString("XMLComparePreference.middleTableColumn1")); //$NON-NLS-1$
		column = new TableColumn(fMappingsTable, SWT.NONE);
		column.setText(XMLCompareMessages.getString("XMLComparePreference.middleTableColumn2")); //$NON-NLS-1$
		column = new TableColumn(fMappingsTable, SWT.NONE);
		column.setText(column3Text); //$NON-NLS-1$
		column = new TableColumn(fMappingsTable, SWT.NONE);
		column.setText(column4Text); //$NON-NLS-1$
	
		buttons= new Composite(parent, SWT.NULL);
		buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
		layout= new GridLayout();
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		buttons.setLayout(layout);
		
		fNewMappingsButton= new Button(buttons, SWT.PUSH);
		fNewMappingsButton.setLayoutData(getButtonGridData(fNewMappingsButton));
		fNewMappingsButton.setText(XMLCompareMessages.getString("XMLComparePreference.middleNew")); //$NON-NLS-1$
		fNewMappingsButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				addMapping(fAddIdMapButton.getShell());
			}
		});

		fEditMappingsButton= new Button(buttons, SWT.PUSH);
		fEditMappingsButton.setLayoutData(getButtonGridData(fEditMappingsButton));
		fEditMappingsButton.setText(XMLCompareMessages.getString("XMLComparePreference.middleEdit")); //$NON-NLS-1$
		fEditMappingsButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				editMapping(fEditMappingsButton.getShell());
			}
		});

		fRemoveMappingsButton= new Button(buttons, SWT.PUSH);
		fRemoveMappingsButton.setLayoutData(getButtonGridData(fRemoveMappingsButton));
		fRemoveMappingsButton.setText(XMLCompareMessages.getString("XMLComparePreference.middleRemove")); //$NON-NLS-1$
		fRemoveMappingsButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				removeMapping(fRemoveMappingsButton.getShell());
			}
		});

		createSpacer(buttons);

		//layout the botton table & its buttons
		label = new Label(parent, SWT.LEFT);
		label.setText(XMLCompareMessages.getString("XMLComparePreference.bottomTableLabel")); //$NON-NLS-1$
		data = new GridData();
		data.horizontalAlignment = GridData.FILL;
		data.horizontalSpan = 2;
		label.setLayoutData(data);

		fOrderedTable = new Table(parent, SWT.SINGLE | SWT.BORDER | SWT.FULL_SELECTION);
		fOrderedTable.setHeaderVisible(true);	
		data = new GridData(GridData.FILL_BOTH);
		data.heightHint = fOrderedTable.getItemHeight()*2;
		data.widthHint= convertWidthInCharsToPixels(70);
		fOrderedTable.setLayoutData(data);
		
		columnLayouts= new ColumnLayoutData[] {
			new ColumnWeightData(1),
			new ColumnWeightData(1)};
		tablelayout = new TableLayout();
		fOrderedTable.setLayout(tablelayout);
		for (int i=0; i<2; i++)
			tablelayout.addColumnData(columnLayouts[i]);
		column = new TableColumn(fOrderedTable, SWT.NONE);
		column.setText(XMLCompareMessages.getString("XMLComparePreference.bottomTableColumn1")); //$NON-NLS-1$
		column = new TableColumn(fOrderedTable, SWT.NONE);
		column.setText(XMLCompareMessages.getString("XMLComparePreference.bottomTableColumn2")); //$NON-NLS-1$
	
		buttons= new Composite(parent, SWT.NULL);
		buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
		layout= new GridLayout();
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		buttons.setLayout(layout);
		
		fNewOrderedButton= new Button(buttons, SWT.PUSH);
		fNewOrderedButton.setLayoutData(getButtonGridData(fNewOrderedButton));
		fNewOrderedButton.setText(XMLCompareMessages.getString("XMLComparePreference.bottomNew")); //$NON-NLS-1$
		fNewOrderedButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				addOrdered(fNewOrderedButton.getShell());
			}
		});

		fEditOrderedButton= new Button(buttons, SWT.PUSH);
		fEditOrderedButton.setLayoutData(getButtonGridData(fEditOrderedButton));
		fEditOrderedButton.setText(XMLCompareMessages.getString("XMLComparePreference.bottomEdit")); //$NON-NLS-1$
		fEditOrderedButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				editOrdered(fEditOrderedButton.getShell());
			}
		});

		fRemoveOrderedButton= new Button(buttons, SWT.PUSH);
		fRemoveOrderedButton.setLayoutData(getButtonGridData(fRemoveOrderedButton));
		fRemoveOrderedButton.setText(XMLCompareMessages.getString("XMLComparePreference.bottomRemove")); //$NON-NLS-1$
		fRemoveOrderedButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				removeOrdered(fRemoveOrderedButton.getShell());
			}
		});

		createSpacer(buttons);



		fIdMapsTable.setSelection(0);
		fIdMapsTable.setFocus();
		selectionChanged();
		
		return parent;
	}
	
	protected void createSpacer(Composite parent) {
		Label spacer= new Label(parent, SWT.NONE);
		GridData data= new GridData();
		data.horizontalAlignment= GridData.FILL;
		data.verticalAlignment= GridData.BEGINNING;
		data.heightHint= 4;		
		spacer.setLayoutData(data);
	}
	
	private static GridData getButtonGridData(Button button) {
		GridData data= new GridData(GridData.FILL_HORIZONTAL);
		data.widthHint= SWTUtil.getButtonWidthHint(button);
		data.heightHint= SWTUtil.getButtonHeigthHint(button);
	
		return data;
	}
	
	public void init(IWorkbench workbench) {
		noDefaultAndApplyButton();
	}

	public void handleEvent(Event event) {
	}

	private void addIdMap(Shell shell) {
		IdMap idmap = new IdMap(false);
		XMLCompareAddIdMapDialog dialog= new XMLCompareAddIdMapDialog(shell,idmap,fIdMaps,fIdMapsInternal,fIdExtensionToName,false);
		if (dialog.open() == Window.OK) {
			if (!fIdMaps.containsKey(idmap.getName())) {
				fIdMaps.put(idmap.getName(),new HashMap());
				if (!idmap.getExtension().equals("")) //$NON-NLS-1$
					fIdExtensionToName.put(idmap.getExtension(),idmap.getName());
				newIdMapsTableItem(idmap,true);
			}
		}
	}

	private void renameIdMap(Shell shell) {
		TableItem[] itemsIdMaps = fIdMapsTable.getSelection();
		if (itemsIdMaps.length > 0) {
			IdMap idmap = (IdMap) itemsIdMaps[0].getData();
			String old_name = idmap.getName();
			String old_extension= idmap.getExtension();
			HashMap idmapHS = (HashMap) fIdMaps.get(old_name);
			XMLCompareAddIdMapDialog dialog= new XMLCompareAddIdMapDialog(shell,idmap,fIdMaps,fIdMapsInternal,fIdExtensionToName,true);
			if (dialog.open() == Window.OK) {
				fIdMaps.remove(old_name);
				fIdExtensionToName.remove(old_extension);
				fIdMaps.put(idmap.getName(),idmapHS);
				if (!idmap.getExtension().equals("")) //$NON-NLS-1$
					fIdExtensionToName.put(idmap.getExtension(),idmap.getName());
				fIdMapsTable.remove(fIdMapsTable.indexOf(itemsIdMaps[0]));
				newIdMapsTableItem(idmap,true);
			}
		}
	}

	private void removeIdMap(Shell shell) {
		TableItem[] itemsIdMap = fIdMapsTable.getSelection();
		if (itemsIdMap.length > 0) {
//			fIdMaps.remove(itemsIdMap[0].getText());
			String IdMapName= ((IdMap)itemsIdMap[0].getData()).getName();
			fIdMaps.remove( IdMapName );
			fOrderedElements.remove( IdMapName );
			//All the corresponding ID Mappings must be removed as well
			TableItem[] itemsMappings = fMappingsTable.getItems();
			for (int i=0; i<itemsMappings.length; i++) {
				itemsMappings[i].dispose();
			}
			//All the corresponding Ordered entries must be removed as well
			TableItem[] itemsOrdered= fOrderedTable.getItems();
			for (int i= 0; i < itemsOrdered.length; i++) {
				itemsOrdered[i].dispose();
			}
			//Remove extension
			if (!itemsIdMap[0].getText(2).equals("")) { //$NON-NLS-1$
				fIdExtensionToName.remove(itemsIdMap[0].getText(2));
			}
			itemsIdMap[0].dispose();  //Table is single selection
		}
	}
	
	private void editIdMap(Shell shell) {
		TableItem[] items = fIdMapsTable.getSelection();
		if (items.length > 0) {
			IdMap idmap = (IdMap) items[0].getData();
			XMLCompareEditCopyIdMapDialog dialog= new XMLCompareEditCopyIdMapDialog(shell,idmap,fIdMaps,fIdMapsInternal);
			if (dialog.open() == Window.OK) {
				String new_idmapName = dialog.getResult();
				if (!fIdMaps.containsKey(new_idmapName)) {
					//copy over id mappings
					Vector newMappings = new Vector();
					IdMap newIdMap = new IdMap(new_idmapName, false, newMappings);
					HashMap newIdmapHM = new HashMap();
					fIdMaps.put(newIdMap.getName(),newIdmapHM);
					Vector Mappings = idmap.getMappings();
					for (Enumeration enum= Mappings.elements(); enum.hasMoreElements(); ) {
						Mapping mapping = (Mapping) enum.nextElement();
						Mapping newMapping = new Mapping(mapping.getElement(), mapping.getSignature(), mapping.getIdAttribute());
						newMappings.add(newMapping);
						newIdmapHM.put(newMapping.getKey(), newMapping.getIdAttribute());
					}
					//copy over ordered entries
					ArrayList orderedAL= idmap.getOrdered();
					if (orderedAL != null && orderedAL.size() > 0) {
						ArrayList newOrderedAL= new ArrayList();
						newIdMap.setOrdered(newOrderedAL);
						ArrayList idmapOrdered= new ArrayList();
						fOrderedElements.put(newIdMap.getName(),idmapOrdered);
						for (Iterator iter= orderedAL.iterator(); iter.hasNext();) {
							Mapping ordered= (Mapping) iter.next();
							Mapping newOrdered= new Mapping(ordered.getElement(), ordered.getSignature());
							newOrderedAL.add(newOrdered);
							idmapOrdered.add(newOrdered.getKey());
						}
					}
					
					newIdMapsTableItem(newIdMap,true);
					selectionChanged();
				}
			}
		}
	}

	private void addMapping(Shell shell) {
		TableItem[] items = fIdMapsTable.getSelection();
		if (items.length > 0) {
			IdMap idmap = (IdMap) items[0].getData();
			Mapping mapping = new Mapping();
			HashMap idmapHM = (HashMap) fIdMaps.get(idmap.getName());
			XMLCompareEditMappingDialog dialog= new XMLCompareEditMappingDialog(shell,mapping,idmapHM,false);
			if (dialog.open() == Window.OK) {
				String idmapHMKey = mapping.getKey();
				if (idmapHM == null)
					idmapHM= new HashMap();
				if (!idmapHM.containsKey(idmapHMKey)) {
					idmapHM.put(idmapHMKey, mapping.getIdAttribute());
					newMappingsTableItem(mapping, true);
					Vector mappings = idmap.getMappings();
					mappings.add(mapping);
				}
			}
		}
	}

	private void editMapping(Shell shell) {
		TableItem[] itemsIdMaps = fIdMapsTable.getSelection();		
		TableItem[] itemsMappings = fMappingsTable.getSelection();
		if (itemsMappings.length > 0) {
			IdMap idmap = (IdMap) itemsIdMaps[0].getData();
			HashMap idmapHM = (HashMap) fIdMaps.get(idmap.getName());
			Mapping mapping = (Mapping)itemsMappings[0].getData();
			String idmapHMKey = mapping.getKey();
			idmapHM.remove(idmapHMKey);
			XMLCompareEditMappingDialog dialog= new XMLCompareEditMappingDialog(shell,mapping,null,true);
			if (dialog.open() == Window.OK) {
				idmapHMKey = mapping.getKey();
				idmapHM.put(idmapHMKey, mapping.getIdAttribute());
				fMappingsTable.remove(fMappingsTable.indexOf(itemsMappings[0]));
				newMappingsTableItem(mapping, true);
			}
		}
	}

	private void removeMapping(Shell shell) {
		TableItem[] itemsIdMaps = fIdMapsTable.getSelection();
		TableItem[] itemsMappings = fMappingsTable.getSelection();
		
		if (itemsMappings.length > 0 && itemsIdMaps.length > 0) {
			Mapping mapping = (Mapping)itemsMappings[0].getData();
			IdMap idmap = (IdMap) itemsIdMaps[0].getData();
			HashMap idmapHS = (HashMap) fIdMaps.get( idmap.getName() );
			idmapHS.remove(mapping.getKey());
			Vector mappings= idmap.getMappings();
			mappings.remove(mapping);
			itemsMappings[0].dispose();  //Table is single selection
		}
	}

	private void addOrdered(Shell shell) {
		TableItem[] items = fIdMapsTable.getSelection();
		if (items.length > 0) {
//			Set orderedSet= fOrderedElements.keySet();
//			for (Iterator iter= orderedSet.iterator(); iter.hasNext(); ) {
//				String IdMapName= (String) iter.next();
//				ArrayList ordered= (ArrayList) fOrderedElements.get(IdMapName);
//				for (Iterator iter2= ordered.iterator(); iter2.hasNext(); ) {
//					System.out.println(IdMapName + ": " + iter2.next()); //$NON-NLS-1$
//				}
//			}
			IdMap idmap = (IdMap) items[0].getData();
			Mapping mapping = new Mapping();
			ArrayList idmapAL= (ArrayList) fOrderedElements.get(idmap.getName());
			if (idmapAL == null)
				idmapAL= new ArrayList();
			XMLCompareEditOrderedDialog dialog= new XMLCompareEditOrderedDialog(shell,mapping,idmapAL,false);
			if (dialog.open() == Window.OK) {
				String idmapALKey = mapping.getKey();
				if (!idmapAL.contains(idmapALKey)) {
					idmapAL.add(idmapALKey);
					newOrderedTableItem(mapping, true);
					ArrayList ordered= idmap.getOrdered();
					if (ordered == null) {
						ordered= new ArrayList();
						ordered.add(mapping);
						idmap.setOrdered(ordered);
					} else {
						ordered.add(mapping);
					}
					if (!fOrderedElements.containsKey(idmap.getName()))
						fOrderedElements.put(idmap.getName(), idmapAL);
				}
			}
		}
	}
	
	private void editOrdered(Shell shell) {
		TableItem[] itemsIdMaps = fIdMapsTable.getSelection();		
		TableItem[] itemsOrdered = fOrderedTable.getSelection();
		if (itemsOrdered.length > 0) {
			IdMap idmap = (IdMap) itemsIdMaps[0].getData();
			ArrayList idmapAL = (ArrayList) fOrderedElements.get(idmap.getName());
			Mapping mapping = (Mapping)itemsOrdered[0].getData();
			String idmapALKey = mapping.getKey();
			idmapAL.remove(idmapALKey);
			XMLCompareEditOrderedDialog dialog= new XMLCompareEditOrderedDialog(shell,mapping,null,true);
			if (dialog.open() == Window.OK) {
				idmapALKey = mapping.getKey();
				idmapAL.add(idmapALKey);
				fOrderedTable.remove(fOrderedTable.indexOf(itemsOrdered[0]));
				newOrderedTableItem(mapping, true);
			}
		}
		
	}
	
	private void removeOrdered(Shell shell) {
		TableItem[] itemsIdMaps = fIdMapsTable.getSelection();
		TableItem[] itemsOrdered = fOrderedTable.getSelection();
		if (itemsOrdered.length > 0 && itemsIdMaps.length > 0) {
			Mapping mapping = (Mapping)itemsOrdered[0].getData();
			IdMap idmap = (IdMap) itemsIdMaps[0].getData();
			ArrayList idmapAL = (ArrayList) fOrderedElements.get( idmap.getName() );
			idmapAL.remove(mapping.getKey());
			if (idmapAL.size() <= 0)
				fOrderedElements.remove(idmap.getName());
			ArrayList ordered= idmap.getOrdered();
			ordered.remove(mapping);
			if (ordered.size() <= 0)
				idmap.setOrdered(null);
			itemsOrdered[0].dispose();  //Table is single selection
		}		
	}

	protected TableItem newIdMapsTableItem(IdMap idmap, boolean selected) {
		//find index where to insert table entry
		TableItem[] items = fIdMapsTable.getItems();
		int i;
		for (i=0; i<items.length && idmap.getName().compareToIgnoreCase(items[i].getText(0)) > 0; i++);
		TableItem item = new TableItem(fIdMapsTable, SWT.NULL, i);
		String[] values = new String[] {idmap.getName(), (idmap.isInternal())?XMLCompareMessages.getString("XMLComparePreference.topTableColumn2internal"):XMLCompareMessages.getString("XMLComparePreference.topTableColumn2user"),idmap.getExtension()}; //$NON-NLS-2$ //$NON-NLS-1$
		item.setText(values);
		item.setData(idmap);
		if (selected) {
			fIdMapsTable.setSelection(i);
			fIdMapsTable.setFocus();
			selectionChanged();
		}
		return item;
	}
	
	protected TableItem newMappingsTableItem(Mapping mapping, boolean selected) {
		TableItem[] items = fMappingsTable.getItems();
		int i;
		for (i=0; i<items.length && mapping.getElement().compareToIgnoreCase(items[i].getText(0)) > 0; i++);

		TableItem item = new TableItem(fMappingsTable, SWT.NULL, i);
		String idtext = mapping.getIdAttribute();
		String idtype;
		if (idtext.charAt(0)==XMLStructureCreator.ID_TYPE_BODY) {
			idtext = idtext.substring(1,idtext.length());
			idtype = IDTYPE_CHILDBODY;
		} else
			idtype = IDTYPE_ATTRIBUTE;
		
		String[] values = new String[] {mapping.getElement(), mapping.getSignature(), idtext, idtype};
		item.setText(values);
		item.setData(mapping);
		if (selected)
			fMappingsTable.setSelection(i);
	
		return item;
	}

	protected TableItem newOrderedTableItem(Mapping mapping, boolean selected) {
		TableItem[] items = fOrderedTable.getItems();
		int i;
		for (i=0; i<items.length && mapping.getElement().compareToIgnoreCase(items[i].getText(0)) > 0; i++);

		TableItem item = new TableItem(fOrderedTable, SWT.NULL, i);
		
		String[] values = new String[] {mapping.getElement(), mapping.getSignature()};
		item.setText(values);
		item.setData(mapping);
		if (selected)
			fOrderedTable.setSelection(i);
	
		return item;
	}

	
	protected void fillIdMapsTable() {
		//fill user idmaps from plugin.xml
		fillIdMaps(true);
		
		//fill user idmaps from Preference Store
		fillIdMaps(false);
				
		//add user idmaps that have ordered entries but no id mappings
		//they do not appear in the preference store with name IDMAP_PREFERENCE_NAME
		Set OrderedKeys= fOrderedElements.keySet();
		Set IdMapKeys= fIdMaps.keySet();
		for (Iterator iter_orderedElements= OrderedKeys.iterator(); iter_orderedElements.hasNext();) {
			String IdMapName= (String) iter_orderedElements.next();
			if (!IdMapKeys.contains(IdMapName)) {
				IdMap idmap= new IdMap(IdMapName, false);
				ArrayList idmapOrdered= (ArrayList) fOrderedElements.get(IdMapName);
				setOrdered(idmap, idmapOrdered);
				newIdMapsTableItem(idmap, false);
			}
		}
	}

	private void fillIdMaps(boolean internal) {
		HashMap IdMaps= (internal)?fIdMapsInternal:fIdMaps;
		HashMap OrderedElements= (internal)?fOrderedElementsInternal:fOrderedElements;
		Set IdMapKeys = IdMaps.keySet();
		for (Iterator iter_internal = IdMapKeys.iterator(); iter_internal.hasNext(); ) {
			String IdMapName = (String) iter_internal.next();
			Vector Mappings = new Vector();
			IdMap idmap = new IdMap(IdMapName, internal, Mappings);
			//create mappings of internal idmaps
			HashMap idmapHM = (HashMap) IdMaps.get(IdMapName);
			Set idmapKeys = idmapHM.keySet();
			for (Iterator iter_idmap = idmapKeys.iterator(); iter_idmap.hasNext(); ) {
				Mapping mapping = new Mapping();
				String signature = (String) iter_idmap.next();
				int end_of_signature = signature.lastIndexOf(SIGN_SEPARATOR,signature.length()-2);
				if (end_of_signature < XMLStructureCreator.ROOT_ID.length() + 1)
					mapping.setSignature(""); //$NON-NLS-1$
				else
					mapping.setSignature(signature.substring(XMLStructureCreator.ROOT_ID.length() + 1,end_of_signature));
				mapping.setElement(signature.substring(end_of_signature+1,signature.length()-1));
				mapping.setIdAttribute((String)idmapHM.get(signature));
				Mappings.add(mapping);
			}
			//create ordered mappings
			ArrayList idmapOrdered= (ArrayList) OrderedElements.get(IdMapName);
			if (idmapOrdered != null) {
				setOrdered(idmap, idmapOrdered);
			}
			//set extension
			if (fIdExtensionToName.containsValue(IdMapName)) {
				Set keySet= fIdExtensionToName.keySet();
				String extension= new String();
				for (Iterator iter= keySet.iterator(); iter.hasNext(); ) {
					extension= (String)iter.next();
					if ( ((String)fIdExtensionToName.get(extension)).equals(IdMapName) )
						break;
				}
				idmap.setExtension(extension);
			}
			newIdMapsTableItem(idmap, false);
		}
	}

	protected static void setOrdered(IdMap idmap, ArrayList idmapOrdered) {
		ArrayList Ordered= new ArrayList();
		for (Iterator iter_ordered= idmapOrdered.iterator(); iter_ordered.hasNext();) {
			Mapping mapping= new Mapping();
			String signature= (String) iter_ordered.next();
			int end_of_signature = signature.lastIndexOf(SIGN_SEPARATOR,signature.length()-2);
			if (end_of_signature < XMLStructureCreator.ROOT_ID.length() + 1)
				mapping.setSignature(""); //$NON-NLS-1$
			else
				mapping.setSignature(signature.substring(XMLStructureCreator.ROOT_ID.length() + 1,end_of_signature));
			mapping.setElement(signature.substring(end_of_signature+1,signature.length()-1));
			Ordered.add(mapping);
		}				
		idmap.setOrdered(Ordered);
	}

	/**
	 * @see IWorkbenchPreferencePage#performDefaults
	 */	
	public boolean performOk() {
		XMLPlugin plugin= XMLPlugin.getDefault();
		if (!plugin.getIdMaps().equals(fIdMaps)
			|| !plugin.getIdExtensionToName().equals(fIdExtensionToName)
			|| !plugin.getOrderedElements().equals(fOrderedElements) )
			plugin.setIdMaps(fIdMaps,fIdExtensionToName,fOrderedElements,true);
			//XMLPlugin.getDefault().setIdMaps(fIdMaps,fIdExtensionToName,null);
		return super.performOk();
	}	
	
	public boolean performCancel() {
		fIdMaps = (HashMap) XMLPlugin.getDefault().getIdMaps().clone();
		return super.performCancel();
	}
	
	protected void selectionChanged() {
		TableItem[] items = fIdMapsTable.getSelection();
		if (items.length > 0) {
			//Refresh Mappings Table
			fMappingsTable.removeAll();
			Vector Mappings = ((IdMap)items[0].getData()).getMappings();
			for (Enumeration enum = Mappings.elements(); enum.hasMoreElements(); ) {
				newMappingsTableItem((Mapping)enum.nextElement(), false);
			}
			//Refresh Ordered Table
			fOrderedTable.removeAll();
			ArrayList Ordered= ((IdMap)items[0].getData()).getOrdered();
			if (Ordered != null) {
				for (Iterator iter_ordered= Ordered.iterator(); iter_ordered.hasNext();) {
					newOrderedTableItem((Mapping)iter_ordered.next(), false);
				}
			}
		}
		updateEnabledState();
	}

	/**
	 * Updates the state (enabled, not enabled) of the buttons
	 */
	private void updateEnabledState() {
		TableItem[] itemsIdMaps = fIdMapsTable.getSelection();
		if (itemsIdMaps.length > 0) {
			IdMap idmap = (IdMap) itemsIdMaps[0].getData();
			if (idmap.isInternal()) {
				fRenameIdMapButton.setEnabled(false);
				fRemoveIdMapButton.setEnabled(false);
				fEditIdMapButton.setEnabled(true);
				
				fNewMappingsButton.setEnabled(false);
				fEditMappingsButton.setEnabled(false);
				fRemoveMappingsButton.setEnabled(false);
				
				fNewOrderedButton.setEnabled(false);
				fEditOrderedButton.setEnabled(false);
				fRemoveOrderedButton.setEnabled(false);
			} else {
				fRenameIdMapButton.setEnabled(true);
				fRemoveIdMapButton.setEnabled(true);
				fEditIdMapButton.setEnabled(false);
				
				fNewMappingsButton.setEnabled(true);
				fEditMappingsButton.setEnabled(true);
				fRemoveMappingsButton.setEnabled(true);
				
				fNewOrderedButton.setEnabled(true);
				fEditOrderedButton.setEnabled(true);
				fRemoveOrderedButton.setEnabled(true);
			}
		}
	}

	static protected boolean containsInvalidCharacters(String text) {
		for (int i=0; i<invalidCharacters.length; i++) {
			if (text.indexOf(invalidCharacters[i]) > -1)
				return true;
		}
		return false;
	}
}
