/*******************************************************************************
 * Copyright (c) 2001, 2007 Oracle 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:
 *     Oracle Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.jsf.ui.internal.classpath;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jst.jsf.core.internal.jsflibraryconfig.JSFLibraryRegistryUtil;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.ArchiveFile;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.JSFLibrary;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.JSFLibraryRegistryFactory;
import org.eclipse.jst.jsf.core.internal.jsflibraryregistry.JSFVersion;
import org.eclipse.jst.jsf.ui.internal.JSFUiPlugin;
import org.eclipse.jst.jsf.ui.internal.Messages;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CCombo;
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.Image;
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.FileDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;

/**
 * Common control for adding JSF library instances
 * @deprecated
 */
public class JSFLibraryEditControl extends Composite implements ModifyListener, SelectionListener 
{
	private Text txtName;
	private Label lblName;
	private CCombo cboVersions;
	private Label lblVersions;
	private Button chkDeploy;
	private Composite btnBar;
	private Button btnAdd;
	private Button btnRemove;
	private TableViewer jars;
	
	private boolean initing = false;

	private JSFLibrary workingCopyLibrary;
	
	private String validationMsg;
	private Set _listeners;
	private int _isNew = -1;//use isNew() method.. not this variable directly

	/**
	 * @param workingCopyLibrary  working copy of the JSF library
	 * @param parent parent SWT control
	 */
	public JSFLibraryEditControl(JSFLibrary workingCopyLibrary, Composite parent){
		super(parent, SWT.NONE);
		this.workingCopyLibrary = workingCopyLibrary;
		_listeners = new HashSet(1);
		createControl(parent);
	}
	
	/**
	 * @param listener
	 */
	public void addValidationListener(JSFLibraryValidationListener listener){
		removeValidationListener(listener);
		_listeners.add(listener);
	}
	
	/**
	 * @param listener
	 */
	public void removeValidationListener(JSFLibraryValidationListener listener){
		_listeners.remove(listener);
	}
	
	/**
	 * @param parent
	 */
	public void createControl(Composite parent) {
		initing = true;

//		this = new Composite(parent, SWT.NONE);
		this.setLayout(new GridLayout(2, false));
		this.setLayoutData(new GridData(GridData.FILL_BOTH));

		lblName = new Label(this, SWT.NONE);
		lblName.setText(Messages.JSFLibraryWizard_LibraryName);
		lblName.setLayoutData(new GridData(GridData.BEGINNING));

		txtName = new Text(this, SWT.BORDER);
		txtName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		txtName.addModifyListener(this);

		lblVersions = new Label(this, SWT.NONE);
		lblVersions.setText(Messages.JSFLibraryWizard_VersionSupported);

		cboVersions = new CCombo(this, SWT.SINGLE | SWT.READ_ONLY | SWT.BORDER);
		cboVersions.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		cboVersions.addModifyListener(this);

		Group jarsComp = new Group(this, SWT.NONE);
		jarsComp.setText(Messages.JSFLibraryWizard_LibraryJars);
		GridLayout gl1 = new GridLayout(2, false);
		jarsComp.setLayout(gl1);
		GridData gd2 = new GridData(GridData.FILL_HORIZONTAL
				| GridData.FILL_VERTICAL);
		gd2.horizontalSpan = 2;
		jarsComp.setLayoutData(gd2);

		createJarsViewer(jarsComp);

		createButtons(jarsComp);

		chkDeploy = new Button(this, SWT.CHECK);
		chkDeploy.setText(Messages.JSFLibraryWizard_DeployJars);
		GridData gd4 = new GridData();
		gd4.horizontalSpan = 2;
		chkDeploy.setLayoutData(gd4);
//		chkDeploy.addSelectionListener(this);
		chkDeploy.setVisible(false);

		loadVersions();

		if (!isNew()) {
			txtName.setText(workingCopyLibrary.getName());
			if (workingCopyLibrary.getJSFVersion().getName().equals(JSFVersion.UNKNOWN_LITERAL.getName())) {
				cboVersions.setText(Messages.JSFLibraryEditControl_ImplVersion_UNKNOWN);
			} else {
				cboVersions.setText(workingCopyLibrary.getJSFVersion().getName());
			}
			chkDeploy.setSelection(workingCopyLibrary.isDeployed());
		}
		jars.setInput(workingCopyLibrary);

		initing = false;

		txtName.setFocus();
	}

	private void createJarsViewer(Group jarsComp) {
		jars = new TableViewer(jarsComp, SWT.BORDER | SWT.MULTI);
		jars.setContentProvider(new IStructuredContentProvider() {
			public Object[] getElements(Object inputElement) {
				if (inputElement instanceof JSFLibrary)
					return ((JSFLibrary) inputElement).getArchiveFiles()
							.toArray();
				return new Object[0];
			}

			public void dispose() {
                // do nothing
			}

			public void inputChanged(Viewer viewer, Object oldInput,
					Object newInput) {
				// won't happen
			}
		});
		jars.setLabelProvider(new ILabelProvider() {
			private Image jarImg = null;
			public Image getImage(Object element) {
				if (jarImg == null){
					ImageDescriptor desc = JSFUiPlugin.getImageDescriptor("obj16/jar_obj.gif"); //$NON-NLS-1$
					jarImg = desc.createImage();
				}
				return jarImg;
			}

			public String getText(Object element) {
				StringBuffer labelBuf = new StringBuffer();
				if (element instanceof ArchiveFile) {
					ArchiveFile archive = (ArchiveFile) element;
					labelBuf.append(archive.getName());	
					if (!archive.exists())
						labelBuf.append(Messages.JSFLibrariesPreferencePage_MISSING_DESC); 
					labelBuf.append(" - ").append(archive.getPath()); //$NON-NLS-1$
				}
				return labelBuf.toString();
			}

			public void addListener(ILabelProviderListener listener) {
                // no listeners supported
			}

			public void dispose() {
				if (jarImg != null)
					jarImg.dispose();
			}

			public boolean isLabelProperty(Object element, String property) {
				return false;
			}

			public void removeListener(ILabelProviderListener listener) {
                // no listeners supported
			}
		});

		jars.addSelectionChangedListener(new ISelectionChangedListener(){
			public void selectionChanged(SelectionChangedEvent event){
				updateButtons();
			}
		});
		
		GridData gd = new GridData(GridData.FILL_BOTH);
//		gd.widthHint = convertWidthInCharsToPixels(30);
//		gd.heightHint = convertHeightInCharsToPixels(10);
		jars.getControl().setLayoutData(gd);
	}

	private void updateButtons() {
		btnRemove.setEnabled(!((StructuredSelection)jars.getSelection()).isEmpty());
		// getButton(IDialogConstants.OK_ID).setEnabled(modified);
	}

	private void createButtons(Composite c) {
		btnBar = new Composite(c, SWT.NONE);
		GridLayout gl = new GridLayout(1, false);
		gl.marginHeight = 0;
		gl.marginTop = 0;
		gl.marginWidth = 0;
		btnBar.setLayout(gl);
		btnBar.setLayoutData(new GridData(GridData.END));

		btnAdd = new Button(btnBar, SWT.NONE);
		btnAdd.setText(Messages.JSFLibraryWizard_Add);
		btnAdd.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
				| GridData.VERTICAL_ALIGN_BEGINNING));
		btnAdd.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				String cur = null;
				String[] chosenJars = openExtJarFileDialog(cur);
				if (chosenJars != null) {
					for (int i = 0; i < chosenJars.length; i++) {
						String jar = chosenJars[i];
						if (!workingCopyLibrary.containsArchiveFile(jar)) {
							ArchiveFile archive = JSFLibraryRegistryFactory.eINSTANCE
								.createArchiveFile();
							archive.setSourceLocation(jar);
							archive.setRelativeDestLocation("WEB-INF/lib"); //$NON-NLS-1$
							workingCopyLibrary.getArchiveFiles().add(archive);
						}
					}
					jars.refresh();
					validate();
				}
			}
		});

		btnRemove = new Button(btnBar, SWT.NONE);
		btnRemove.setEnabled(false);
		btnRemove.setText(Messages.JSFLibraryWizard_Remove);
		btnRemove.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL
				| GridData.VERTICAL_ALIGN_BEGINNING));
		btnRemove.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				if (jars.getSelection() instanceof StructuredSelection){
					StructuredSelection objs = (StructuredSelection)jars.getSelection();
					if (objs != null){
						Iterator it = objs.iterator();
						 while (it.hasNext()){
							 Object obj = it.next();
							 ArchiveFile jar = (ArchiveFile)obj;
							 workingCopyLibrary.getArchiveFiles().remove(jar);							 
						 }
					}
					jars.refresh();
					validate();
				}
			}
		});
	}

	private void loadVersions() {
		cboVersions.removeAll();
		Iterator it = JSFVersion.VALUES.iterator();
		while (it.hasNext()) {
			JSFVersion ver = (JSFVersion) it.next();
			if (ver.getName().equals(JSFVersion.UNKNOWN_LITERAL.getName())) {
				cboVersions.add(Messages.JSFLibraryEditControl_ImplVersion_UNKNOWN);
			} else {
				cboVersions.add(ver.getName());
			}
		}
	}

	private String[] openExtJarFileDialog(String existing) {
		String title = Messages.JSFLibraryWizard_ExtJarFileDialogTitle;

		FileDialog dialog = new FileDialog(getShell(),
				existing == null ? SWT.MULTI : SWT.SINGLE);
		dialog.setText(title);
		dialog.setFilterExtensions(new String[] { "*.jar;*.zip" }); //$NON-NLS-1$
		// FIXME: remember and use last path chosen??
		String filterPath = ResourcesPlugin.getWorkspace().getRoot()
				.getFullPath().toString();
		dialog.setFilterPath(filterPath);
		// if (existing != null) {
		// dialog.setFileName(existing.getPath().lastSegment());
		// }

		String res = dialog.open();
		if (res == null) {
			return null;
		}
		String[] fileNames = dialog.getFileNames();
		String[] elems = new String[fileNames.length];
		IPath file = new Path(res);
		IPath apath = file.removeLastSegments(1);
		for (int i = 0; i < fileNames.length; i++) {
			elems[i] = apath.append(fileNames[i]).toString();
		}
		return elems;
	}	

	public void modifyText(ModifyEvent e) {
		validate();
		updateButtons();	
	}

	private void fireValidateEvent(final JSFLibraryValidationEvent jSFLibraryValidationEvent) {
		new Runnable(){
			public void run() {
				for (Iterator it=_listeners.iterator();it.hasNext();){
					JSFLibraryValidationListener listener = (JSFLibraryValidationListener)it.next();
					listener.notifyValidation(jSFLibraryValidationEvent);
				}
			}
		}.run();
	}


	public void widgetSelected(SelectionEvent e) {
		validate();
		updateButtons();
	}

	public void widgetDefaultSelected(SelectionEvent e) {
        // no handling for default selection
	}

	private void validate() {
		if (initing)
			return;
		validationMsg = null;
//		setPageComplete(true);
		if (!validateName() || !validateJars() || !validateVersion()) {
//			setPageComplete(false);
		}
		fireValidateEvent(new JSFLibraryValidationEvent(validationMsg));
	}
	
	private boolean validateJars() {
		if (workingCopyLibrary.getArchiveFiles().isEmpty()) {
			validationMsg = Messages.JSFLibraryWizard_ValidateNoJars;
			return false;
		}
		return true;
	}
	
	private boolean validateVersion() {
		//FIXME: why isn't selection indesx correct???
	//	if (cboVersions.getSelectionIndex() < 0) {
	//		setErrorMessage("Choose the maximum JSF version supported if known.");
	//		return false;
	//	}
		return true;
	}
	
	private boolean validateName() {
		if (txtName.getText() == null
				|| txtName.getText().trim().equals("")) { //$NON-NLS-1$
			validationMsg = Messages.JSFLibraryWizard_ValidateNoLibraryName;
			return false;
		}
		String aName = txtName.getText().trim();
		if (isNew() || (!isNew() && !getCurrentLibraryName().equals(aName))) {
			if (isNameInRegistry(JSFLibraryRegistryUtil.getInstance()
					.getJSFLibraryRegistry().getAllJSFLibraries(), aName)) {
				validationMsg = Messages.JSFLibraryWizard_ValidateExistingLibraryName;
				return false;
			}
		}
		return true;
	}
	
	private boolean isNew() {
		if (_isNew == -1){
			_isNew = workingCopyLibrary.getName() == null ? 1 : 0;
		}
		return _isNew == 1;
	}

	private String getCurrentLibraryName() {
		return workingCopyLibrary.getName();		
	}

	private boolean isNameInRegistry(Collection c, String name) {
		Iterator it = c.iterator();
		while (it.hasNext()) {
			JSFLibrary lib = (JSFLibrary) it.next();
			if (lib.getName().equals(name)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @return the trimmed name of the user input for jsf library name
	 */
	public String getJSFLibraryName() {		
		return txtName.getText().trim();
	}


	/**
	 * @return the value of the user input for the isDeployed checkbox
	 */
	public boolean getIsDeployed() {		
		return chkDeploy.getSelection();
	}


	/**
	 * @return the jsf version selected in the version dropping
	 */
	public JSFVersion getJSFVersion() {
		if (cboVersions.getSelectionIndex() >= 0) {
			JSFVersion ver = (JSFVersion) JSFVersion.VALUES.get(cboVersions
					.getSelectionIndex());
			return ver;
		}
		return JSFVersion.UNKNOWN_LITERAL;
	}

}
