/*******************************************************************************
 * Copyright (c) 2001, 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.xml.ui.nsedit;

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

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.part.PageBook;
import org.eclipse.wst.common.contentmodel.util.NamespaceInfo;
import org.eclipse.wst.xml.ui.dialogs.SelectFileOrXMLCatalogIdDialog;
import org.eclipse.wst.xml.ui.internal.XMLUIPlugin;
import org.eclipse.wst.xml.uriresolver.util.IdResolver;
import org.eclipse.wst.xml.uriresolver.util.IdResolverImpl;
import org.eclipse.wst.xml.uriresolver.util.URIHelper;

public class CommonAddNamespacesControl extends Composite implements SelectionListener {

	class EditNamespaceControl extends Composite {
		protected Button browseButton;
		Text locationHintField;
		Text prefixField;
		Text uriField;

		//protected NamespaceInfo info;

		public EditNamespaceControl(Composite parent) {
			super(parent, SWT.NONE); //BORDER);
			setLayout(new GridLayout());
			setLayoutData(new GridData(GridData.FILL_BOTH));

			Label label = new Label(this, SWT.NONE);
			label.setText(XMLUIPlugin.getResourceString("%_UI_ENTER_REQ_PREFIX_AND_NAMESPACE")); //$NON-NLS-1$

			Composite composite = new Composite(this, SWT.NONE);
			GridLayout layout = new GridLayout();
			layout.numColumns = 3;
			layout.marginWidth = 0;
			layout.verticalSpacing = 1;
			composite.setLayout(layout);

			GridData gd = new GridData(GridData.FILL_HORIZONTAL);
			gd.widthHint = 350;
			composite.setLayoutData(gd);

			// row 1
			//
			Label prefixLabel = new Label(composite, SWT.NONE);
			prefixLabel.setText(XMLUIPlugin.getResourceString("%_UI_LABEL_PREFIX_COLON")); //$NON-NLS-1$

			prefixField = new Text(composite, SWT.SINGLE | SWT.BORDER);
			prefixField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			//prefixField.setText(getDisplayValue(info.prefix));
			//prefixField.addModifyListener(modifyListener);
			//prefixField.setEnabled(info.getProperty("prefix-readOnly") ==
			// null);
			Label placeHolder1 = new Label(composite, SWT.NONE);

			// row 2
			//
			Label uriLabel = new Label(composite, SWT.NONE);
			uriLabel.setText(XMLUIPlugin.getResourceString("%_UI_LABEL_NAMESPACE_NAME_COLON")); //$NON-NLS-1$

			uriField = new Text(composite, SWT.SINGLE | SWT.BORDER);
			uriField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			//uriField.setText(getDisplayValue(info.uri));
			//uriField.addModifyListener(modifyListener);
			//uriField.setEnabled(info.getProperty("uri-readOnly") == null);

			Label placeHolder2 = new Label(composite, SWT.NONE);

			// row 3
			//
			Label locationHintLabel = new Label(composite, SWT.NONE);
			locationHintLabel.setText(XMLUIPlugin.getResourceString("%_UI_LABEL_LOCATION_HINT_COLON")); //$NON-NLS-1$

			locationHintField = new Text(composite, SWT.SINGLE | SWT.BORDER);
			locationHintField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			//locationHintField.setText(getDisplayValue(info.locationHint));
			//locationHintField.addModifyListener(modifyListener);
			//locationHintField.setEnabled(info.getProperty("locationHint-readOnly")
			// == null);

			SelectionListener selectionListener = new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					performBrowse();
				}
			};

			browseButton = new Button(composite, SWT.NONE);
			browseButton.setText(XMLUIPlugin.getResourceString("%_UI_LABEL_BROWSE")); //$NON-NLS-1$
			browseButton.addSelectionListener(selectionListener);
			browseButton.setEnabled(locationHintField.getEnabled());
		}

		protected void performBrowse() {
			String[] extensions = {".xsd"}; //$NON-NLS-1$
			SelectFileOrXMLCatalogIdDialog dialog = new SelectFileOrXMLCatalogIdDialog(getShell(), extensions);
			dialog.create();
			dialog.getShell().setText(XMLUIPlugin.getResourceString("%_UI_LABEL_SELECT_FILE")); //$NON-NLS-1$
			dialog.setBlockOnOpen(true);
			dialog.open();

			if (dialog.getReturnCode() == Window.OK) {
				String grammarURI = null;
				IFile file = dialog.getFile();
				String id = dialog.getId();
				if (file != null) {
					String uri = null;
					if (resourceLocation != null) {
						uri = URIHelper.getRelativeURI(file.getLocation(), resourceLocation);
						grammarURI = file.getLocation().toOSString();
					} else {
						uri = file.getLocation().toOSString();
						grammarURI = uri;
					}
					locationHintField.setText(uri);
				} else if (id != null) {
					locationHintField.setText(id);
					IdResolver resolver = new IdResolverImpl(null);
					grammarURI = resolver.resolveId(id, id);
				}

				try {
					//TODO CMDocument document =
					// CMDocumentBuilderRegistry.getInstance().buildCMDocument(grammarURI);
					//				 List namespaceInfoList =
					// (List)document.getProperty("http://org.eclipse.wst/cm/properties/namespaceInfo");
					//				 NamespaceInfo info =
					// (NamespaceInfo)namespaceInfoList.get(0);
					//				 if (uriField.getText().trim().length() == 0 && info.uri
					// != null)
					//				 {
					//					 uriField.setText(info.uri);
					//				 }
					//				 if (prefixField.getText().trim().length() == 0 &&
					// info.prefix != null)
					//				 {
					//					 prefixField.setText(info.prefix);
					//				 }
				} catch (Exception e) {
				}
			}
		}
	}

	protected Button deleteButton;
	protected Button editButton;
	protected EditNamespaceControl editNamespaceControl;
	protected int heightHint = 250;
	protected List namespaceInfoList = new ArrayList();
	protected Button newButton;
	protected PageBook pageBook;
	protected Button radio1;
	protected Button radio2;
	protected IPath resourceLocation;
	protected Composite tableSection;
	protected CommonNamespaceInfoTable tableViewer;
	protected int widthHint = 500;


	public CommonAddNamespacesControl(Composite parent, int style, IPath resourceLocation) {
		super(parent, style);
		this.resourceLocation = resourceLocation;
		GridData gd = new GridData(GridData.FILL_BOTH);
		if (widthHint != -1) {
			gd.widthHint = widthHint;
		}
		if (heightHint != -1) {
			gd.heightHint = heightHint;
		}
		setLayoutData(gd);
		setLayout(new GridLayout());

		radio1 = new Button(this, SWT.RADIO);
		radio1.setText(XMLUIPlugin.getResourceString("%_UI_SELECT_REGISTERED_NAMESPACES")); //$NON-NLS-1$
		radio1.addSelectionListener(this);

		radio2 = new Button(this, SWT.RADIO);
		radio2.setText(XMLUIPlugin.getResourceString("%_UI_SPECIFY_NEW_NAMESPACE")); //$NON-NLS-1$
		radio2.addSelectionListener(this);

		Label separator = new Label(this, SWT.SEPARATOR | SWT.HORIZONTAL);
		separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		//Group namespaceInfoGroup = new Group(this, SWT.NONE);
		//namespaceInfoGroup.setText("Namespace Declarations");
		// //XMLCommonUIPlugin.getInstance().getString("_UI_LABEL_XML_SCHEMA_INFORMATION"));
		//namespaceInfoGroup.setLayout(new GridLayout(2, false));
		//namespaceInfoGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
		pageBook = new PageBook(this, SWT.NONE);
		pageBook.setLayoutData(new GridData(GridData.FILL_BOTH));

		tableSection = new Composite(pageBook, SWT.NONE);
		tableSection.setLayout(new GridLayout());
		Label label = new Label(tableSection, SWT.NONE);
		label.setText(XMLUIPlugin.getResourceString("%_UI_SELECT_NAMESPACE_TO_ADD")); //$NON-NLS-1$

		tableViewer = new CommonNamespaceInfoTable(tableSection, SWT.CHECK, 6);
		editNamespaceControl = new EditNamespaceControl(pageBook);
		pageBook.showPage(tableSection);

		tableViewer.setInput(namespaceInfoList);
	}



	public List getNamespaceInfoList() {
		List list = new ArrayList();
		if (radio1.getSelection()) {
			TableItem[] items = tableViewer.getTable().getItems();
			for (int i = 0; i < items.length; i++) {
				TableItem item = items[i];
				if (item.getChecked()) {
					list.add(item.getData());
				}
			}
		} else {
			NamespaceInfo info = new NamespaceInfo();
			info.prefix = editNamespaceControl.prefixField.getText();
			info.uri = editNamespaceControl.uriField.getText();
			info.locationHint = editNamespaceControl.locationHintField.getText();
			list.add(info);
		}
		return list;
	}

	public void setNamespaceInfoList(List list) {
		namespaceInfoList = list;
		tableViewer.setInput(namespaceInfoList);
	}

	public void widgetDefaultSelected(SelectionEvent e) {
	}

	public void widgetSelected(SelectionEvent e) {
		if (e.widget == radio1) {
			pageBook.showPage(tableSection);
		} else if (e.widget == radio2) {
			pageBook.showPage(editNamespaceControl);
		}
	}
}
