/*
 * Copyright (c) 2002 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 - Initial API and implementation
 *   Jens Lukowski/Innoopract - initial renaming/restructuring
 * 
 */
package org.eclipse.wst.xml.ui.internal.catalog;

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

import org.eclipse.core.resources.IFile;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.part.PageBook;
import org.eclipse.wst.common.ui.internal.dialogs.SelectSingleFileDialog;
import org.eclipse.wst.common.uriresolver.internal.util.URIHelper;
import org.eclipse.wst.xml.core.internal.catalog.provisional.ICatalog;
import org.eclipse.wst.xml.core.internal.catalog.provisional.ICatalogElement;
import org.eclipse.wst.xml.core.internal.catalog.provisional.ICatalogEntry;
import org.eclipse.wst.xml.core.internal.catalog.provisional.INextCatalog;
import org.eclipse.wst.xml.ui.internal.XMLUIPlugin;
 
public class EditCatalogEntryDialog extends Dialog
{
	 protected static Image borwseImage = ImageFactory.INSTANCE.getImage("icons/obj16/file_expand.gif");
	 protected static Image catalogEntryToolBarImage = ImageFactory.INSTANCE.getImage("icons/etool50/catalogEntry.gif");
	 protected static Image nextCatalogToolBarImage = ImageFactory.INSTANCE.getImage("icons/etool50/nextCatalog.gif");
	  
	protected class CatalogEntryPage extends CatalogElementPage
	{

		protected Button browseButton;

		protected ICatalogEntry catalogEntry;

		protected Button checkboxButton;
		
		protected Label errorMessageLabel;

		protected Text keyField;

		protected Combo keyTypeCombo;

		protected Text resourceLocationField;

		protected Combo resourceTypeCombo;

		protected Text webAddressField;

		protected void computeErrorMessage()
		{
			errorMessage = null;

			if (errorMessage == null)
			{
				String fileName = resourceLocationField.getText();
				if (fileName.trim().length() > 0)
				{
					if (fileName.indexOf("..") != -1
							|| fileName.indexOf("./") != -1
							|| fileName.indexOf("/.") != -1
							|| fileName.indexOf(".\\") != -1
							|| fileName.indexOf("\\.") != -1)
					{
						errorMessage = XMLCatalogMessages.UI_WARNING_URI_MUST_NOT_HAVE_DOTS;
					}

					String uri = fileName;
					if (!URIHelper.hasProtocol(uri))
					{
						uri = URIHelper.isAbsolute(uri) ? URIHelper
								.prependFileProtocol(uri) : URIHelper
								.prependPlatformResourceProtocol(uri);
					}

					if (errorMessage == null
							&& !URIHelper.isReadableURI(uri, false))
					{
						errorMessage = XMLCatalogMessages.UI_WARNING_URI_NOT_FOUND_COLON
								+ fileName;
					}
				} else
				{
					errorMessage = ""; // this an error that is not actaully
					// reported ... OK is just disabled
				}
			}

			if (errorMessage == null && checkboxButton.getSelection()
					&& webAddressField.getText().trim().length() == 0)
			{
				errorMessage = ""; // this an error that is not actually
				// reported
				// ... OK is just disabled
			}

			if (errorMessage == null && keyField.getText().trim().length() == 0)
			{
				errorMessage = ""; // this an error that is not actually
				// reported
				// ... OK is just disabled
			}
		}

		protected Control createCatalogEntryPanel(Composite parent)
		{

			ModifyListener modifyListener = new ModifyListener()
			{
				public void modifyText(ModifyEvent e)
				{
					if (e.widget == resourceLocationField)
					{
						if (keyField.getText().length() == 0)
						{
							String uri = resourceLocationField.getText();
							if (uri.endsWith("xsd")
									&& !URIHelper.hasProtocol(uri))
							{
								uri = URIHelper.isAbsolute(uri) ? URIHelper
										.prependFileProtocol(uri) : URIHelper
										.prependPlatformResourceProtocol(uri);
								String namespaceURI = XMLQuickScan
										.getTargetNamespaceURIForSchema(uri);
								if (namespaceURI != null)
								{
									keyField.setText(namespaceURI);
								}
							}
						}
					}
					updateWidgets(e.widget);
				}
			};
			

			Composite composite = new Composite(parent, SWT.NONE);
			GridData gd = new GridData(GridData.FILL_BOTH);
			composite.setLayoutData(gd);
	
			GridLayout layout = new GridLayout();
			composite.setLayout(layout);
			
			Composite group = new Composite(composite, SWT.NONE);
			gd = new GridData(GridData.FILL_HORIZONTAL);
			group.setLayoutData(gd);
			
			layout = new GridLayout(3, false);
			group.setLayout(layout);
			
    		Label resourceLocationLabel = new Label(group, SWT.NONE);
			resourceLocationLabel.setText(XMLCatalogMessages.UI_LABEL_URI_COLON);

			resourceLocationField = new Text(group, SWT.SINGLE | SWT.BORDER);
			gd = new GridData();
			gd.horizontalAlignment = SWT.FILL;
			gd.grabExcessHorizontalSpace = true;
			resourceLocationField.setLayoutData(gd);
			resourceLocationField.setText(getDisplayValue(getEntry().getURI()));
			// WorkbenchHelp.setHelp(resourceLocationField,
			// XMLBuilderContextIds.XMLP_ENTRY_URI);
			resourceLocationField.addModifyListener(modifyListener);

			
			browseButton = createBrowseButton(group);
			// WorkbenchHelp.setHelp(browseButton, XMLBuilderContextIds.XMLP_ENTRY_BROWSE);
			browseButton.addSelectionListener(new DropDownSelectionListener(resourceLocationField));

			// Key Type
			//
			Label keyTypeLabel = new Label(group, SWT.NONE);
			keyTypeLabel.setText(XMLCatalogMessages
					.UI_KEY_TYPE_COLON);

			keyTypeCombo = new Combo(group, SWT.NONE);
			gd = new GridData();
			gd.horizontalAlignment = SWT.FILL;
			gd.grabExcessHorizontalSpace = true;
			keyTypeCombo.setLayoutData(gd);
			updateKeyTypeCombo(getEntry().getEntryType());
			keyTypeCombo.addModifyListener(modifyListener);
			// WorkbenchHelp.setHelp(keyTypeCombo,
			// XMLBuilderContextIds.XMLP_ENTRY_KEY_TYPE);

			// a placeholder to fill the 3rd column
			Button placeHolder = new Button(group, SWT.NONE);
			placeHolder.setVisible(false);

			// Key
			// 
			Label keyValueLabel = new Label(group, SWT.NONE);
			keyValueLabel.setText(XMLCatalogMessages.UI_LABEL_KEY_COLON);
			keyField = new Text(group, SWT.SINGLE | SWT.BORDER);
			// WorkbenchHelp.setHelp(keyField,
			// XMLBuilderContextIds.XMLP_ENTRY_KEY);
			keyField.setLayoutData(gd);
			keyField.setText(getDisplayValue(getEntry().getKey()));
			keyField.addModifyListener(modifyListener);
			
			Composite group2 = new Composite(composite, SWT.NONE);
			gd = new GridData(GridData.FILL_HORIZONTAL);
			group2.setLayoutData(gd);
		
			layout = new GridLayout();
			group2.setLayout(layout);

			// checkbox -- note parent is dialogArea
			//
			checkboxButton = new Button(group2, SWT.CHECK);
			// WorkbenchHelp.setHelp(checkboxButton,
			// XMLBuilderContextIds.XMLP_ENTRY_SPECIFY_ALTERNATIVE);
			checkboxButton.setText(XMLCatalogMessages
					.UI_LABEL_SPECIFY_ALTERNATIVE_WEB_URL);
			checkboxButton
					.setLayoutData(new GridData());
			checkboxButton.setSelection(getEntry().getAttributeValue(
					ICatalogEntry.ATTR_WEB_URL) != null);
			SelectionListener buttonListener = new SelectionListener(){
				public void widgetDefaultSelected(SelectionEvent event)
				{
				}

				public void widgetSelected(SelectionEvent event)
				{
					if (event.widget == checkboxButton)
					{
						updateWidgets(checkboxButton);
					}
				}
			};
			checkboxButton.addSelectionListener(buttonListener);

			// Web Address field
			//

			ModifyListener webAddressFieldListener = new ModifyListener()
			{
				public void modifyText(ModifyEvent e)
				{
					computeErrorMessage();
					updateErrorMessageLabel(errorMessageLabel);
					updateOKButtonState();
				}
			};

			webAddressField = new Text(group2, SWT.SINGLE | SWT.BORDER);
			// WorkbenchHelp.setHelp(webAddressField,
			// XMLBuilderContextIds.XMLP_ENTRY_WEB_ADDRESS);
			webAddressField
					.setLayoutData(gd);
			webAddressField.setText(getDisplayValue(getEntry()
					.getAttributeValue(ICatalogEntry.ATTR_WEB_URL)));
			webAddressField.setEnabled(false);
			webAddressField.addModifyListener(webAddressFieldListener);
			
			
			errorMessageLabel = new Label(group2, SWT.NONE);
			Color color = new Color(errorMessageLabel.getDisplay(), 200, 0, 0);
			errorMessageLabel.setForeground(color);
			errorMessageLabel.setLayoutData(new GridData(
					GridData.FILL_HORIZONTAL));
			
			updateWidgets(null);

			return composite;
		}

		public Control createControl(Composite parent)
		{
			
			fControl = createCatalogEntryPanel(parent);
			
			return fControl;
		}
	

		public ICatalogElement getData()
		{
			return getEntry();
		}

		protected ICatalogEntry getEntry()
		{
			if(catalogEntry == null)
			{
				if (catalogElement != null
						&& catalogElement.getType() == ICatalogElement.TYPE_ENTRY)
				{
					catalogEntry = (ICatalogEntry) catalogElement;
				} else
				{
					if (catalog != null)
					{
						catalogEntry = (ICatalogEntry) catalog
						.createCatalogElement(ICatalogElement.TYPE_ENTRY);
					}
				}
			}
			return catalogEntry;
		}

		protected int getKeyType()
		{
			switch (keyTypeCombo.getSelectionIndex()) {
			case 0:
				if("schema".equals(keyTypeCombo.getData("keyType")))
				{
					return ICatalogEntry.ENTRY_TYPE_URI;
				}
				if(keyTypeCombo.getItemCount() == 1) //only uri entry
				{
					return ICatalogEntry.ENTRY_TYPE_URI;
				}
				else{
					return ICatalogEntry.ENTRY_TYPE_PUBLIC;
				}
			case 1:
				return ICatalogEntry.ENTRY_TYPE_SYSTEM;
			case 2: 
				return ICatalogEntry.ENTRY_TYPE_URI;
			default :
				return ICatalogEntry.ENTRY_TYPE_URI;
			}
		}

		public void saveData()
		{
			String uri = resourceLocationField.getText();
			if (!URIHelper.hasProtocol(uri))
			{
				uri = URIHelper.isAbsolute(uri) ? URIHelper
						.prependFileProtocol(uri) : URIHelper
						.prependPlatformResourceProtocol(uri);
			}
			getEntry().setURI(uri);
			getEntry().setKey(keyField.getText());
			getEntry().setEntryType(getKeyType());
			getEntry().setAttributeValue(
					ICatalogEntry.ATTR_WEB_URL,
					checkboxButton.getSelection() ? webAddressField.getText()
							: null);
		}

		protected void updateKeyTypeCombo(int type)
		{
			keyTypeCombo.removeAll();
			for (Iterator i = XMLUIPlugin.getXMLCatalogFileTypes()
					.iterator(); i.hasNext();)
			{
				XMLCatalogFileType theFileType = (XMLCatalogFileType) i
						.next();
				if (theFileType.extensions != null)
				{
					for(Iterator j = theFileType.extensions
					.iterator(); j.hasNext();)
					{
						String extension = (String) j.next();
						if(resourceLocationField.getText().endsWith(extension))
						{
							if(theFileType.description.equals("XSD Files"))
							{
								keyTypeCombo.add(XMLCatalogMessages.
										UI_KEY_TYPE_DESCRIPTION_XSD_PUBLIC);
								keyTypeCombo.add(XMLCatalogMessages.
										UI_KEY_TYPE_DESCRIPTION_XSD_SYSTEM);
								keyTypeCombo.setData("keyType", "schema");
							}
							else if(theFileType.description.equals("DTD Files"))
							{
								keyTypeCombo.add(XMLCatalogMessages.
										UI_KEY_TYPE_DESCRIPTION_DTD_PUBLIC);
								keyTypeCombo.add(XMLCatalogMessages.
										UI_KEY_TYPE_DESCRIPTION_DTD_SYSTEM);
								keyTypeCombo.add(XMLCatalogMessages.
										UI_KEY_TYPE_DESCRIPTION_URI);
							}
							else
							{
								keyTypeCombo.add(XMLCatalogMessages.
										UI_KEY_TYPE_DESCRIPTION_URI);
							}
						}
						
					}
						
				}
			}
			if(keyTypeCombo.getItemCount() == 0){
				keyTypeCombo.add(XMLCatalogMessages.
						UI_KEY_TYPE_DESCRIPTION_URI);
			}
//			if (resourceLocationField.getText().endsWith("xsd"))
//			{
//				keyTypeCombo.add(XMLCatalogMessages.
//						UI_KEY_TYPE_DESCRIPTION_XSD_PUBLIC"));
//				keyTypeCombo.add(XMLCatalogMessages.
//						UI_KEY_TYPE_DESCRIPTION_XSD_SYSTEM"));
//				keyTypeCombo.setData("keyType", "schema");
//			} else 
//			{
//				keyTypeCombo.add(XMLCatalogMessages.
//						UI_KEY_TYPE_DESCRIPTION_DTD_PUBLIC"));
//				keyTypeCombo.add(XMLCatalogMessages.
//						UI_KEY_TYPE_DESCRIPTION_DTD_SYSTEM"));
//				keyTypeCombo.add(XMLCatalogMessages.
//						UI_KEY_TYPE_DESCRIPTION_URI"));
//			}

			switch (type) {
				case ICatalogEntry.ENTRY_TYPE_PUBLIC:
					keyTypeCombo.select(0);
					break;
				case ICatalogEntry.ENTRY_TYPE_SYSTEM:
					keyTypeCombo.select(1);
					break;
				case ICatalogEntry.ENTRY_TYPE_URI: 
					if("schema".equals(keyTypeCombo.getData("keyType")))
					{
						keyTypeCombo.select(0); // namespace name
					}
					else 
					{
						if (keyTypeCombo.getItemCount() == 1)
						{
							keyTypeCombo.select(0);
						}
						else if(keyTypeCombo.getItemCount() == 3){
							keyTypeCombo.select(2);
						}
						
					}
					break;
				default :
					if (keyTypeCombo.getItemCount() == 1)
					{
						keyTypeCombo.select(0);
					}
					break;
			}
			
		}

		protected void updateWebAddressWidgets(int keyType)
		{
			boolean isPublicKeyType = (keyType == ICatalogEntry.ENTRY_TYPE_PUBLIC);
			checkboxButton.setEnabled(isPublicKeyType);
			webAddressField.setEnabled(isPublicKeyType
					&& checkboxButton.getSelection());
		}

		protected void updateWidgets(Widget widget)
		{
			if (widget != keyTypeCombo)
			{
				updateKeyTypeCombo(getKeyType());
			}
			updateWebAddressWidgets(getKeyType());
			computeErrorMessage();
			updateErrorMessageLabel(errorMessageLabel);
			updateOKButtonState();
		}

	}
	
	protected abstract class CatalogElementPage {
		
		Control fControl;
		
		public CatalogElementPage() {
			super();
			
		}
		
		public abstract Control createControl(Composite parent);
		
		public Control getControl(){
			return fControl;
		}
		
		public abstract ICatalogElement getData();
		
		public abstract void saveData();
	} 
	
	protected class FilterableSelectSingleFileDialog extends
			SelectSingleFileDialog implements SelectionListener
	{
		protected Combo filterControl;

		public FilterableSelectSingleFileDialog(Shell parentShell)
		{
			super(parentShell, null, true);
			setFilters(null);
		}

		public void createAndOpen()
		{
			this.create();
			getShell().setText(
					XMLCatalogMessages.UI_LABEL_SELECT_FILE);
			setBlockOnOpen(true);
			open();
		}

		public void createFilterControl(Composite composite)
		{
			Label label = new Label(composite, SWT.NONE);
			label.setText(XMLCatalogMessages.
					UI_LABEL_SELECT_FILE_FILTER_CONTROL);

			filterControl = new Combo(composite, SWT.NONE);
			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
			filterControl.setLayoutData(gd);

			filterControl.setText(XMLCatalogMessages.
					UI_TEXT_SELECT_FILE_FILTER_CONTROL);

			filterControl.add(XMLCatalogMessages.UI_TEXT_SELECT_FILE_FILTER_CONTROL);

			for (Iterator i = XMLUIPlugin.getXMLCatalogFileTypes()
					.iterator(); i.hasNext();)
			{
				XMLCatalogFileType fileType = (XMLCatalogFileType) i.next();
				if (fileType.description != null)
				{
					filterControl.add(fileType.description);
				}
			}

			filterControl.addSelectionListener(this);
		}

		protected void setFilters(XMLCatalogFileType fileType)
		{
			if (fileType == null)
			{
				// compute all the supported file extensions
				List list = new ArrayList();
				for (Iterator i = XMLUIPlugin.getXMLCatalogFileTypes()
						.iterator(); i.hasNext();)
				{
					XMLCatalogFileType theFileType = (XMLCatalogFileType) i
							.next();
					if (theFileType.extensions != null)
					{
						list.addAll(theFileType.extensions);
					}
				}
				// Any files are now supported with Resource URI
				//selectSingleFileView.setFilterExtensions(createStringArray(list));
			} else
			{
				if (fileType.extensions != null)
				{
					selectSingleFileView
							.setFilterExtensions(createStringArray(fileType.extensions));
				}
			}
		}

		public void widgetDefaultSelected(SelectionEvent e)
		{

		}

		public void widgetSelected(SelectionEvent e)
		{
			String text = filterControl.getText();
			XMLCatalogFileType fileType = getMatchingFileType(text);
			setFilters(fileType);
		}
	}

	protected class NextCatalogPage extends CatalogElementPage
	{
		protected Button browseButton;

		protected Text catalogLocationField;

		protected INextCatalog nextCatalog;
		
		protected Label errorMessageLabel;

		protected void computeErrorMessage()
		{
			errorMessage = null;

			if (errorMessage == null)
			{
				String fileName = catalogLocationField.getText();
				if (fileName.trim().length() > 0)
				{
					if (fileName.indexOf("..") != -1
							|| fileName.indexOf("./") != -1
							|| fileName.indexOf("/.") != -1
							|| fileName.indexOf(".\\") != -1
							|| fileName.indexOf("\\.") != -1)
					{
						errorMessage = XMLCatalogMessages.
								UI_WARNING_URI_MUST_NOT_HAVE_DOTS;
					}

					String uri = fileName;
					if (!URIHelper.hasProtocol(uri))
					{
						uri = URIHelper.isAbsolute(uri) ? URIHelper
								.prependFileProtocol(uri) : URIHelper
								.prependPlatformResourceProtocol(uri);
					}

					if (errorMessage == null
							&& !URIHelper.isReadableURI(uri, false))
					{
						errorMessage = XMLCatalogMessages.
								UI_WARNING_URI_NOT_FOUND_COLON
								+ fileName;
					}
				} else
				{
					errorMessage = ""; // this an error that is not actaully
					// reported ... OK is just disabled
				}
			}

		}

		public Control createControl(Composite parent)
		{
			fControl = createNextCatalogPanel(parent);
			return fControl;
		}

		protected Control createNextCatalogPanel(Composite parent)
		{
			ModifyListener modifyListener = new ModifyListener()
			{
				public void modifyText(ModifyEvent e)
				{
					updateWidgets(e.widget);
				}
			};
			
			Composite composite = new Composite(parent, SWT.NONE);
			GridData gd = new GridData(GridData.FILL_BOTH);
			composite.setLayoutData(gd);
	
			GridLayout layout = new GridLayout();
			composite.setLayout(layout);

			Composite group = new Composite(composite, SWT.NONE);
			gd = new GridData(GridData.FILL_HORIZONTAL);
			group.setLayoutData(gd);
			
			layout = new GridLayout(2, false);
			group.setLayout(layout);
			
			Label resourceLocationLabel = new Label(group, SWT.NONE);
			resourceLocationLabel.setText(XMLCatalogMessages.
					UI_LABEL_CATALOG_URI_COLON);

			// filler
			new Label(group, SWT.NONE);
			
			catalogLocationField = new Text(group, SWT.SINGLE | SWT.BORDER);
			catalogLocationField.setLayoutData(new GridData(
					GridData.FILL_HORIZONTAL));
			catalogLocationField.setText(getDisplayValue(getNextCatalog()
					.getCatalogLocation()));
			// WorkbenchHelp.setHelp(resourceLocationField,
			// XMLBuilderContextIds.XMLP_ENTRY_URI);
			catalogLocationField.addModifyListener(modifyListener);

			browseButton = createBrowseButton(group);
			browseButton.addSelectionListener(new DropDownSelectionListener(catalogLocationField));

	        errorMessageLabel = new Label(group, SWT.NONE);
			Color color = new Color(errorMessageLabel.getDisplay(), 200, 0, 0);
			errorMessageLabel.setForeground(color);
			errorMessageLabel.setLayoutData(new GridData(
					GridData.FILL_HORIZONTAL));
			updateWidgets(null);
			return composite;
		}

		public ICatalogElement getData()
		{
			return getNextCatalog();
		}

		protected INextCatalog getNextCatalog()
		{
			if(nextCatalog == null)
			{
				if (catalogElement != null
						&& catalogElement.getType() == ICatalogElement.TYPE_NEXT_CATALOG)
				{
					nextCatalog = (INextCatalog) catalogElement;
				} else
				{
					if (catalog != null)
					{
						nextCatalog = (INextCatalog) catalog
						.createCatalogElement(ICatalogElement.TYPE_NEXT_CATALOG);
					}
				}
			}
			return nextCatalog;
		}

		public void saveData()
		{
			String uri = catalogLocationField.getText();
			if (!URIHelper.hasProtocol(uri))
			{
				uri = URIHelper.isAbsolute(uri) ? URIHelper
						.prependFileProtocol(uri) : URIHelper
						.prependPlatformResourceProtocol(uri);
			}
			getNextCatalog().setCatalogLocation(uri);
		}

		protected void updateWidgets(Widget widget)
		{
			computeErrorMessage();
			updateErrorMessageLabel(errorMessageLabel);
			updateOKButtonState();
		}
	}

	protected class ToolBarItemSelectionChangeListener implements SelectionListener
	{
		public void widgetDefaultSelected(SelectionEvent e)
		{
			// TODO Auto-generated method stub
			
		}

		public void widgetSelected(SelectionEvent e)
		{
			Object selection = e.getSource();
			if (selection instanceof ToolItem)
			{
				if (!showPage((CatalogElementPage)((ToolItem)selection).getData()))
				{
					// Page flipping wasn't successful
					//handleError();
				}
			}
		}
		
	}

	public static String[] createStringArray(List list)
	{
		String[] stringArray = new String[list.size()];
		for (int i = 0; i < stringArray.length; i++)
		{
			stringArray[i] = (String) list.get(i);
		}
		return stringArray;
	}

	public static String removeLeadingSlash(String uri)
	{
		// remove leading slash from the value to avoid the whole leading slash
		// ambiguity problem
		//       
		if (uri != null)
		{
			while (uri.startsWith("/") || uri.startsWith("\\"))
			{
				uri = uri.substring(1);
			}
		}
		return uri;
	}

	protected ICatalog catalog;

	protected ICatalogElement catalogElement;

	protected String errorMessage;

	protected Button okButton;

	protected PageBook pageContainer;

	protected CatalogElementPage selectedPage;

	//protected TreeViewer treeViewer;
	
	protected ToolBar toolBar;

	public EditCatalogEntryDialog(Shell parentShell, ICatalog catalog)
	{
		super(parentShell);
		setShellStyle(getShellStyle() | SWT.RESIZE);
		this.catalog = catalog;
	}

	public EditCatalogEntryDialog(Shell parentShell,
			ICatalogElement catalogElement)
	{
		super(parentShell);
		setShellStyle(getShellStyle() | SWT.RESIZE);
		this.catalogElement = catalogElement;
		// TODO EB: fix his
		// entry.setURI(URIHelper.removePlatformResourceProtocol(entry.getURI()));
	}

	protected void buttonPressed(int buttonId)
	{
		if (buttonId == IDialogConstants.OK_ID)
		{
			selectedPage.saveData();
		}
		super.buttonPressed(buttonId);
	}
	


	protected void createButtonsForButtonBar(Composite parent)
	{
		okButton = createButton(parent, IDialogConstants.OK_ID,
				IDialogConstants.OK_LABEL, true);
		okButton.setEnabled(false);
		createButton(parent, IDialogConstants.CANCEL_ID,
				IDialogConstants.CANCEL_LABEL, false);
		updateOKButtonState();
	}

	protected void createCatalogEntryButton()
	{
		CatalogElementPage page = new CatalogEntryPage();
		page.createControl(pageContainer);
		ToolItem toolItem = new ToolItem (toolBar, SWT.PUSH);
		toolItem.setImage(catalogEntryToolBarImage);
		toolItem.setText (XMLCatalogMessages.EditCatalogEntryDialog_catalogEntryLabel);
		toolItem.setData(page);
		toolItem.addSelectionListener(new ToolBarItemSelectionChangeListener());
	}
	
	protected Control createDialogArea(Composite parent)
	{
		Composite dialogAreaComposite = (Composite)super.createDialogArea(parent);  
		GridLayout layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		dialogAreaComposite.setLayout(layout);
	    GridData gd = new GridData(GridData.FILL_BOTH);
	    gd.widthHint = 500;
	    gd.heightHint = 250;
	    dialogAreaComposite.setLayoutData(gd);   		
		createMainComponent(dialogAreaComposite);
		return this.dialogArea;
	}

	protected Composite createMainComponent(Composite composite)
	{
		if (catalogElement != null) // "edit" action
		{
			Composite composite1 = new Composite (composite, SWT.NONE);
			GridData data = new GridData (GridData.FILL_BOTH);
			composite1.setLayoutData (data);
			GridLayout layout = new GridLayout();
			composite1.setLayout(layout);

			pageContainer = new PageBook(composite1, SWT.NONE);
			pageContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
			
			if(catalogElement.getType() == ICatalogElement.TYPE_ENTRY){
				CatalogElementPage entryPage = new CatalogEntryPage();
				entryPage.createControl(pageContainer);
				showPage(entryPage);
			}
			else if(catalogElement.getType() == ICatalogElement.TYPE_NEXT_CATALOG){
				CatalogElementPage nextCatalogPage = new NextCatalogPage();
				nextCatalogPage.createControl(pageContainer);
				showPage(nextCatalogPage);
			}
			
			return composite1;
		}
		else // "add" action
		{
			return createMainComponentWithToolbar(composite);
		}
	}

	protected Composite createMainComponentWithToolbar(Composite composite)
	{
	
		FormLayout formLayout = new FormLayout ();
		formLayout.marginHeight = 5;
		formLayout.marginWidth = 5;
		composite.setLayout (formLayout);
		
		Label label = new Label(composite, SWT.NONE);
		FormData data = new FormData ();
		data.top = new FormAttachment (0, 0);
		data.left = new FormAttachment (0, 0);
		data.right = new FormAttachment (100, 0);
		label.setLayoutData (data);

		toolBar = new ToolBar (composite, SWT.BORDER | SWT.FLAT | SWT.VERTICAL);
	
		data = new FormData ();
		data.top = new FormAttachment (label, 0);
		data.left = new FormAttachment (0, 0);
		data.bottom = new FormAttachment (100, 0);
//		data.height = 250;
//		data.width = 50;
		toolBar.setLayoutData (data);

		Composite composite1 = new Composite (composite, SWT.BORDER);
		data = new FormData ();
		data.top = new FormAttachment (label, 0);
		data.left = new FormAttachment (toolBar, 0, SWT.DEFAULT);
		data.right = new FormAttachment (100, 0);
		data.bottom = new FormAttachment (100, 0);
		composite1.setLayoutData (data);
		GridLayout layout = new GridLayout();
		layout.marginHeight = 0;
		layout.marginWidth = 0;
		composite1.setLayout(layout);

		//createPageBookPanel(composite1);
		pageContainer = new PageBook(composite1, SWT.NONE);
		pageContainer.setLayoutData(new GridData(GridData.FILL_BOTH));
		
		// add pages for each type of catalog element
		createCatalogEntryButton();
		createNextCatalogButton();
		if(toolBar.getItemCount() > 0){
			ToolItem item = toolBar.getItem(0);
			showPage((CatalogElementPage)(item.getData()));
		}
		return composite1;
	}

	protected void createNextCatalogButton()
	{
		CatalogElementPage page = new NextCatalogPage();
		page.createControl(pageContainer);
		ToolItem toolItem = new ToolItem (toolBar, SWT.PUSH);
		toolItem.setImage(nextCatalogToolBarImage);
		toolItem.setText (XMLCatalogMessages.EditCatalogEntryDialog_nextCatalogLabel);
		toolItem.setData(page);
		toolItem.addSelectionListener(new ToolBarItemSelectionChangeListener());

	}

	protected ICatalogElement getCatalogElement()
	{
		return catalogElement;
	}

	protected String getDisplayValue(String string)
	{
		return string != null ? string : "";
	}

	protected XMLCatalogFileType getMatchingFileType(String description)
	{
		XMLCatalogFileType fileType = null;
		for (Iterator i = XMLUIPlugin.getXMLCatalogFileTypes()
				.iterator(); i.hasNext();)
		{
			XMLCatalogFileType theFileType = (XMLCatalogFileType) i.next();
			if (theFileType.description != null
					&& theFileType.description.equals(description))
			{
				fileType = theFileType;
			}
		}
		return fileType;
	}

	protected boolean showPage(CatalogElementPage page)
	{
		if (pageContainer.isDisposed())
		{
			return false;
		}
		selectedPage = page;
		pageContainer.setVisible(true);
		pageContainer.showPage(selectedPage.getControl());
		catalogElement = selectedPage.getData();
		return true;
	}
	
	protected void updateErrorMessageLabel(Label errorMessageLabel)
	{
		errorMessageLabel.setText(errorMessage != null ? errorMessage : "");
	}	
	
	protected void updateOKButtonState()
	{
		if (okButton != null)
		{
			okButton.setEnabled(errorMessage == null);
		}
	}	
	
	protected Button createBrowseButton(Composite composite){
		Button browseButton = new Button(composite,  SWT.FLAT );
//		browseButton.setText(XMLCatalogMessages.
//				UI_BUTTON_BROWSE"));
		browseButton.setImage(borwseImage);
		Rectangle r = borwseImage.getBounds();
		GridData gd = new GridData();
		int IMAGE_WIDTH_MARGIN = 6;
		int IMAGE_HEIGHT_MARGIN = 6;
		gd.heightHint = r.height+ IMAGE_HEIGHT_MARGIN;
		gd.widthHint = r.width + IMAGE_WIDTH_MARGIN;
		browseButton.setLayoutData(gd);
		
		return browseButton;
		
	}
	
	class DropDownSelectionListener extends SelectionAdapter {
		private Menu    menu = null;
		private Control control;

		public DropDownSelectionListener(Control control)
		{
			super();
			this.control = control;
		}
		public void widgetSelected(SelectionEvent event) {
			// Create the menu if it has not already been created
			if (menu == null) {
				// Lazy create the menu.
				menu = new Menu(getShell());
				MenuItem menuItem = new MenuItem(menu, SWT.NONE);
				menuItem.setText(XMLCatalogMessages.UI_BUTTON_MENU_BROWSE_WORKSPACE);
				/*
				 * Add a menu selection listener so that the menu is hidden
				 * when the user selects an item from the drop down menu.
				 */
				menuItem.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						setMenuVisible(false);
						invokeWorkspaceFileSelectionDialog();
					}
				});
				
				menuItem = new MenuItem(menu, SWT.NONE);
				menuItem.setText(XMLCatalogMessages.UI_BUTTON_MENU_BROWSE_FILE_SYSTEM);
				/*
				 * Add a menu selection listener so that the menu is hidden
				 * when the user selects an item from the drop down menu.
				 */
				menuItem.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e) {
						setMenuVisible(false);
						invokeFileSelectionDialog();
					}
				});
			
			}
			
			// Position the menu below and vertically aligned with the the drop down tool button.
			Button button = (Button) event.widget;
			
			// set location
			Point ptBrowse = button.getLocation();
			Rectangle rcBrowse = button.getBounds();
			ptBrowse.y += rcBrowse.height;
			ptBrowse = button.getParent().toDisplay(ptBrowse);
			menu.setLocation(ptBrowse.x, ptBrowse.y);
			
			setMenuVisible(true);
			
		}
		private void setMenuVisible(boolean visible) 
		{
			menu.setVisible(visible);
			//this.visible = visible;
		}
		
		private void invokeWorkspaceFileSelectionDialog()
		{
			FilterableSelectSingleFileDialog dialog = new FilterableSelectSingleFileDialog(
					getShell());
			dialog.createAndOpen();

			IFile file = dialog.getFile();
			if (file != null)
			{
				// remove leading slash from the value to avoid the
				// whole leading slash ambiguity problem
				//                    
				String uri = file.getFullPath().toString();
				while (uri.startsWith("/") || uri.startsWith("\\"))
				{
					uri = uri.substring(1);
				}
				if(control instanceof Text){
					((Text)control).setText(uri);
				}
				
			}
		}
		
		private void invokeFileSelectionDialog()
		{
			FileDialog dialog = new FileDialog(getShell(), SWT.SINGLE);
			String file = dialog.open();
			if (control instanceof Text && file != null)
			{
				((Text) control).setText(file);
			}
		}
	}
		
}
