/*******************************************************************************
 * 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.util.XMLCommonResources;
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(XMLCommonResources.getInstance().getString("_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(XMLCommonResources.getInstance().getString("_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(XMLCommonResources.getInstance().getString("_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(XMLCommonResources.getInstance().getString("_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(XMLCommonResources.getInstance().getString("_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(XMLCommonResources.getInstance().getString("_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(XMLCommonResources.getInstance().getString("_UI_SELECT_REGISTERED_NAMESPACES")); //$NON-NLS-1$
		radio1.addSelectionListener(this);

		radio2 = new Button(this, SWT.RADIO);
		radio2.setText(XMLCommonResources.getInstance().getString("_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(XMLCommonResources.getInstance().getString("_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);
		}
	}
}
