/*******************************************************************************
 * Copyright (c) 2003, 2004 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.update.internal.ui.wizards;

import java.lang.reflect.*;
import java.net.*;
import java.util.*;

import org.eclipse.core.runtime.*;
import org.eclipse.jface.dialogs.*;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.operation.*;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.*;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.forms.widgets.*;
import org.eclipse.ui.help.*;
import org.eclipse.update.core.*;
import org.eclipse.update.internal.search.*;
import org.eclipse.update.internal.ui.*;
import org.eclipse.update.internal.ui.model.*;
import org.eclipse.update.internal.ui.parts.*;
import org.eclipse.update.internal.core.*;
import org.eclipse.update.operations.*;
import org.eclipse.update.search.*;

public class SitePage extends BannerPage implements ISearchProvider {

	class TreeContentProvider
		extends DefaultContentProvider
		implements ITreeContentProvider {

		public Object[] getElements(Object parent) {
			return getAllSiteBookmarks();
		}

		public Object[] getChildren(final Object parent) {
			if (parent instanceof SiteBookmark) {
				final SiteBookmark bookmark = (SiteBookmark) parent;
				if (bookmark.isUnavailable())
					return new Object[0];
				final Object[] children =
					getSiteCatalogWithIndicator(
						bookmark,
						!bookmark.isSiteConnected());
				treeViewer.getControl().getDisplay().asyncExec(new Runnable() {
					public void run() {
						if (children.length > 0)
							handleSiteExpanded(bookmark, children);
					}
				});
				return children;
			}
			return new Object[0];
		}

		public Object getParent(Object element) {
			if (element instanceof SiteCategory)
				return ((SiteCategory) element).getBookmark();
			return null;
		}

		public boolean hasChildren(Object element) {
			return (element instanceof SiteBookmark);
		}

	}

	class TreeLabelProvider extends LabelProvider {

		public Image getImage(Object obj) {
			if (obj instanceof SiteBookmark)
				return UpdateUI.getDefault().getLabelProvider().get(
					UpdateUIImages.DESC_SITE_OBJ);
			if (obj instanceof SiteCategory)
				return UpdateUI.getDefault().getLabelProvider().get(
					UpdateUIImages.DESC_CATEGORY_OBJ);
			return super.getImage(obj);
		}

		public String getText(Object obj) {
			if (obj instanceof SiteBookmark) {
				return ((SiteBookmark) obj).getLabel();
			}
			return super.getText(obj);
		}
	}

	class ModelListener implements IUpdateModelChangedListener {
		public void objectChanged(Object object, String property) {
			treeViewer.refresh();
			checkItems();
		}

		public void objectsAdded(Object parent, Object[] children) {
			treeViewer.refresh();
			checkItems();
		}

		public void objectsRemoved(Object parent, Object[] children) {
			treeViewer.refresh();
			checkItems();
		}
	}

	private static DiscoveryFolder discoveryFolder = new DiscoveryFolder();
	private CheckboxTreeViewer treeViewer;
	private ScrolledFormText descLabel;
	private Button addSiteButton;
	private Button addLocalButton;
	private Button addLocalZippedButton;
	private Button editButton;
	private Button removeButton;
	private Button envFilterCheck;
	private SearchRunner searchRunner;
	private EnvironmentFilter envFilter;
	private UpdateSearchRequest searchRequest;
	private ModelListener modelListener;


	public SitePage(SearchRunner searchRunner) {
		super("SitePage"); //$NON-NLS-1$
		setTitle(UpdateUI.getString("SitePage.title")); //$NON-NLS-1$
		setDescription(UpdateUI.getString("SitePage.desc")); //$NON-NLS-1$
		UpdateUI.getDefault().getLabelProvider().connect(this);
		searchRequest =
			new UpdateSearchRequest(
				new SiteSearchCategory(),
				new UpdateSearchScope());
		searchRequest.addFilter(new BackLevelFilter());
		envFilter = new EnvironmentFilter();
		this.searchRunner = searchRunner;
		modelListener = new ModelListener();
		UpdateUI.getDefault().getUpdateModel().addUpdateModelChangedListener(
			modelListener);
	}

	private void toggleEnvFilter(boolean add) {
		if (add)
			searchRequest.addFilter(envFilter);
		else
			searchRequest.removeFilter(envFilter);
		searchRunner.setNewSearchNeeded(true);
	}

	public void dispose() {
		UpdateUI.getDefault().getLabelProvider().disconnect(this);
		UpdateUI
			.getDefault()
			.getUpdateModel()
			.removeUpdateModelChangedListener(
			modelListener);
		super.dispose();
	}

	/*
	 * (non-Javadoc) @see
	 * org.eclipse.update.internal.ui.wizards.BannerPage#createContents(org.eclipse.swt.widgets.Composite)
	 */
	protected Control createContents(Composite parent) {
		Composite client = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.numColumns = 2;
		client.setLayout(layout);

		Label label = new Label(client, SWT.NULL);
		label.setText(UpdateUI.getString("SitePage.label")); //$NON-NLS-1$
		GridData gd = new GridData();
		gd.horizontalSpan = 2;
		label.setLayoutData(gd);

		createTreeViewer(client);

		Composite buttonContainer = new Composite(client, SWT.NULL);
		buttonContainer.setLayoutData(new GridData(GridData.FILL_VERTICAL));
		layout = new GridLayout();
		layout.marginWidth = 0;
		layout.marginHeight = 0;
		buttonContainer.setLayout(layout);

		addSiteButton = new Button(buttonContainer, SWT.PUSH);
		addSiteButton.setText(UpdateUI.getString("SitePage.addUpdateSite")); //$NON-NLS-1$
		addSiteButton.setLayoutData(
			new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		SWTUtil.setButtonDimensionHint(addSiteButton);
		addSiteButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleAddSite();
			}
		});

		addLocalButton = new Button(buttonContainer, SWT.PUSH);
		addLocalButton.setText(UpdateUI.getString("SitePage.addLocalSite")); //$NON-NLS-1$
		addLocalButton.setLayoutData(
			new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		SWTUtil.setButtonDimensionHint(addLocalButton);
		addLocalButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleAddLocal();
			}
		});

		addLocalZippedButton = new Button(buttonContainer, SWT.PUSH);
		addLocalZippedButton.setText(UpdateUI.getString("SitePage.addLocalZippedSite")); //$NON-NLS-1$
		addLocalZippedButton.setLayoutData(
			new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		SWTUtil.setButtonDimensionHint(addLocalZippedButton);
		addLocalZippedButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleAddLocalZipped();
			}
		});
		
		// separator
		new Label(buttonContainer, SWT.None);
		
		editButton = new Button(buttonContainer, SWT.PUSH);
		editButton.setText(UpdateUI.getString("SitePage.edit")); //$NON-NLS-1$
		editButton.setEnabled(false);
		editButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		SWTUtil.setButtonDimensionHint(editButton);
		editButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleEdit();
			}
		});

		removeButton = new Button(buttonContainer, SWT.PUSH);
		removeButton.setText(UpdateUI.getString("SitePage.remove")); //$NON-NLS-1$
		removeButton.setEnabled(false);
		removeButton.setLayoutData(
			new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		SWTUtil.setButtonDimensionHint(removeButton);
		removeButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleRemove();
			}
		});
		
		descLabel = new ScrolledFormText(client, true);
		descLabel.setText("");
		descLabel.setBackground(parent.getBackground());
		gd = new GridData(SWT.FILL, SWT.FILL, true, true);
		gd.horizontalSpan = 1;
		descLabel.setLayoutData(gd);
		
		envFilterCheck = new Button(client, SWT.CHECK);
		envFilterCheck.setText(UpdateUI.getString("SitePage.ignore")); //$NON-NLS-1$
		envFilterCheck.setSelection(true);
		toggleEnvFilter(true);
		envFilterCheck.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				toggleEnvFilter(envFilterCheck.getSelection());
			}
		});
		gd = new GridData();
		gd.horizontalSpan = 2;
		envFilterCheck.setLayoutData(gd);

		Dialog.applyDialogFont(parent);

		WorkbenchHelp.setHelp(client, "org.eclipse.update.ui.SitePage"); //$NON-NLS-1$

		return client;
	}

	private void createTreeViewer(Composite parent) {
		treeViewer =
			new CheckboxTreeViewer(
				parent,
				SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
		treeViewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
		treeViewer.setContentProvider(new TreeContentProvider());
		treeViewer.setLabelProvider(new TreeLabelProvider());
		treeViewer.setInput(UpdateUI.getDefault().getUpdateModel());

		initializeItems();

		treeViewer.addCheckStateListener(new ICheckStateListener() {
			public void checkStateChanged(CheckStateChangedEvent e) {
				Object element = e.getElement();
				if (element instanceof SiteBookmark)
					handleSiteChecked((SiteBookmark) element, e.getChecked());
				else if (element instanceof SiteCategory) {
					handleCategoryChecked(
						(SiteCategory) element,
						e.getChecked());
				}
			}
		});

		treeViewer
			.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent e) {
				handleSelectionChanged((IStructuredSelection) e.getSelection());
			}
		});

//		treeViewer.addFilter(new ViewerFilter() {
//			public boolean select(
//				Viewer viewer,
//				Object parentElement,
//				Object element) {
//				if (element instanceof SiteBookmark)
//					return !((SiteBookmark) element).isWebBookmark();
//				return true;
//			}
//		});
	}

	private void initializeItems() {
		checkItems();
		updateSearchRequest();
	}

	private void checkItems() {
		TreeItem[] items = treeViewer.getTree().getItems();
		for (int i = 0; i < items.length; i++) {
			SiteBookmark bookmark = (SiteBookmark) items[i].getData();
			treeViewer.setChecked(bookmark, bookmark.isSelected());
			String[] ignoredCats = bookmark.getIgnoredCategories();
			treeViewer.setGrayed(bookmark, ignoredCats.length > 0
					&& bookmark.isSelected());
		}
	}

	private void handleAddSite() {
		NewUpdateSiteDialog dialog = new NewUpdateSiteDialog(getShell());
		dialog.create();
		dialog.getShell().setText(UpdateUI.getString("SitePage.new")); //$NON-NLS-1$
		if (dialog.open() == NewUpdateSiteDialog.OK)
			updateSearchRequest();
	}

	private void handleAddLocal() {
		SiteBookmark siteBookmark = LocalSiteSelector.getLocaLSite(getShell());
		if (siteBookmark != null) {
			UpdateModel model = UpdateUI.getDefault().getUpdateModel();
			model.addBookmark(siteBookmark);
			model.saveBookmarks();
			updateSearchRequest();
		}
		return;
	}

	private void handleAddLocalZipped() {
		SiteBookmark siteBookmark =
			LocalSiteSelector.getLocaLZippedSite(getShell());
		if (siteBookmark != null) {
			UpdateModel model = UpdateUI.getDefault().getUpdateModel();
			model.addBookmark(siteBookmark);
			model.saveBookmarks();
			updateSearchRequest();
		}
		return;
	}

	private void handleRemove() {
		BusyIndicator
			.showWhile(treeViewer.getControl().getDisplay(), new Runnable() {
			public void run() {
				UpdateModel updateModel =
					UpdateUI.getDefault().getUpdateModel();
				IStructuredSelection ssel =
					(IStructuredSelection) treeViewer.getSelection();
				SiteBookmark bookmark = (SiteBookmark) ssel.getFirstElement();
				String selName = bookmark.getLabel();
				boolean answer = MessageDialog
								.openQuestion(
										getShell(),
										UpdateUI
												.getString("SitePage.remove.location.conf.title"), //$NON-NLS-1$
										UpdateUI
												.getString("SitePage.remove.location.conf")	//$NON-NLS-1$
												+ " " + selName); //$NON-NLS-1$

				if (answer && !bookmark.isReadOnly()) {
					updateModel.removeBookmark(bookmark);
					updateSearchRequest();
				}
			}
		});
	}

	private void handleEdit() {
		IStructuredSelection ssel =
			(IStructuredSelection) treeViewer.getSelection();
		SiteBookmark bookmark = (SiteBookmark) ssel.getFirstElement();
		URL oldURL = bookmark.getURL();
		EditSiteDialog dialog = new EditSiteDialog(getShell(), bookmark);
		dialog.create();
		String title = bookmark.isLocal() ? UpdateUI.getString("SitePage.dialogEditLocal") : UpdateUI.getString("SitePage.dialogEditUpdateSite"); //$NON-NLS-1$ //$NON-NLS-2$
																																				  // //$NON-NLS-2$
		dialog.getShell().setText(title);
		if (dialog.open() == EditSiteDialog.OK ) {
			URL newURL = bookmark.getURL();
			if (!UpdateManagerUtils.sameURL(oldURL, newURL)) {
				UpdateModel model = UpdateUI.getDefault().getUpdateModel();
				model.fireObjectChanged(bookmark, null);
				updateSearchRequest();	
			}
		}
	}

	private void handleSiteChecked(SiteBookmark bookmark, boolean checked) {
		if (bookmark.isUnavailable()) {
			bookmark.setSelected(false);
			treeViewer.setChecked(bookmark, false);
			return;
		}
		
		bookmark.setSelected(checked);
		if (checked)
			bookmark.setIgnoredCategories(new String[0]);
			
		if (checked || bookmark.isSiteConnected())
			treeViewer.setSubtreeChecked(bookmark, checked);
		// at this point, we may realize the site is not available
		if (bookmark.isUnavailable()) {
			treeViewer.setChecked(bookmark, false);
			return;
		}
			
		treeViewer.setGrayed(bookmark, false);
		updateSearchRequest();
	}

	private void handleSiteExpanded(SiteBookmark bookmark, Object[] cats) {
		if (!bookmark.isSelected()) {
			treeViewer.setSubtreeChecked(bookmark, false);
			ArrayList result = new ArrayList();
			for (int i = 0; i < cats.length; i++) {
				if (cats[i] instanceof SiteCategory) {
					result.add(((SiteCategory) cats[i]).getFullName());
				}
			}
			bookmark.setIgnoredCategories(
				(String[]) result.toArray(new String[result.size()]));
		} else {
			String[] ignored = bookmark.getIgnoredCategories();
			HashSet imap = new HashSet();
			for (int i = 0; i < ignored.length; i++) {
				imap.add(ignored[i]);
			}

			for (int i = 0; i < cats.length; i++) {
				if (cats[i] instanceof SiteCategory) {
					SiteCategory category = (SiteCategory) cats[i];
					treeViewer.setChecked(
						category,
						!imap.contains(category.getFullName()));
				}
			}
			treeViewer.setGrayed(
				bookmark,
				ignored.length > 0 && ignored.length < cats.length);
		}
		searchRunner.setNewSearchNeeded(true);
	}

	private void handleCategoryChecked(
		SiteCategory category,
		boolean checked) {
		SiteBookmark bookmark = category.getBookmark();
		
		ArrayList array = new ArrayList();

		if (bookmark.isSelected()) {
			String[] ignored = bookmark.getIgnoredCategories();
			for (int i = 0; i < ignored.length; i++) 
				array.add(ignored[i]);
		} else {
			Object[] categs =
				getSiteCatalogWithIndicator(bookmark, !bookmark.isSiteConnected());
			for (int i=0; i<categs.length; i++)
				array.add(((SiteCategory)categs[i]).getFullName());
		}
		
		if (checked) {
			array.remove(category.getFullName());
		} else {
			array.add(category.getFullName());
		}

		bookmark.setIgnoredCategories(
			(String[]) array.toArray(new String[array.size()]));
		searchRunner.setNewSearchNeeded(true);

		Object[] children = ((TreeContentProvider) treeViewer.getContentProvider())
					.getChildren(category.getBookmark());
		treeViewer.setChecked(bookmark, array.size() < children.length);
		bookmark.setSelected(array.size() < children.length);
		treeViewer.setGrayed(
			bookmark,
			array.size() > 0 && array.size() < children.length);
		updateSearchRequest();
	}


	private void handleSelectionChanged(IStructuredSelection ssel) {
		boolean enable = false;
		Object item = ssel.getFirstElement();
		IURLEntry descEntry = null;
		if (item instanceof SiteBookmark) {
			enable = !((SiteBookmark) item).isReadOnly();
			//descEntry = ((SiteBookmark)item).getSite(null).getDescription();
		} else if (item instanceof SiteCategory) {
			descEntry = ((SiteCategory)item).getCategory().getDescription();
		}
		editButton.setEnabled(enable);
		removeButton.setEnabled(enable);
		
		String desc = null;
		if (descEntry != null)
			desc = descEntry.getAnnotation();
		if (desc == null)
			desc = ""; //$NON-NLS-1$
		descLabel.setText(desc);
	}

	private void updateSearchRequest() {
		Object[] checked = treeViewer.getCheckedElements();

		UpdateSearchScope scope = new UpdateSearchScope();
		int nsites = 0;

		for (int i = 0; i < checked.length; i++) {
			if (checked[i] instanceof SiteBookmark) {
				SiteBookmark bookmark = (SiteBookmark) checked[i];
				scope.addSearchSite(
					bookmark.getLabel(),
					bookmark.getURL(),
					bookmark.getIgnoredCategories());
				nsites++;
			}
		}
		searchRequest.setScope(scope);
		searchRunner.setNewSearchNeeded(true);
		setPageComplete(nsites > 0);
	}

	public UpdateSearchRequest getSearchRequest() {
		return searchRequest;
	}

	public void setVisible(boolean value) {
		super.setVisible(value);
		if (value) {
			searchRunner.setSearchProvider(this);
			// Reset all unavailable sites, so they can be tried again if the user wants it
			SiteBookmark[] bookmarks = getAllSiteBookmarks();
			for (int i=0; i<bookmarks.length; i++) {
				if (bookmarks[i].isUnavailable())
					bookmarks[i].setUnavailable(false);
			}
		}
	}

	class CatalogBag {
		Object[] catalog;
	}

	private Object[] getSiteCatalogWithIndicator(
		final SiteBookmark bookmark,
		final boolean connect) {
		final CatalogBag bag = new CatalogBag();

		if (bookmark.isUnavailable())
			return new Object[0];
		
		IRunnableWithProgress op = new IRunnableWithProgress() {
			public void run(IProgressMonitor monitor)
				throws InvocationTargetException {
				try {
					monitor.beginTask("", 3); //$NON-NLS-1$
					monitor.worked(1);

					if (connect)
						bookmark.connect(new SubProgressMonitor(monitor, 1));
					else
						monitor.worked(1);
					bag.catalog =
						bookmark.getCatalog(
							true,
							new SubProgressMonitor(monitor, 1));
				} catch (CoreException e) {
					throw new InvocationTargetException(e);
				} finally {
					monitor.done();
				}
			}
		};
		try {
			getContainer().run(true, true, op);
		} catch (InvocationTargetException e) {
			UpdateUI.logException(e);
		} catch (InterruptedException e) {
		}

		return (bag.catalog == null) ? new Object[0] : bag.catalog;
	}
	
	private SiteBookmark[] getAllSiteBookmarks() {
		UpdateModel model = UpdateUI.getDefault().getUpdateModel();
		Object[] bookmarks = model.getBookmarkLeafs();
		Object[] sitesToVisit =
			discoveryFolder.getChildren(discoveryFolder);
		SiteBookmark[] all = new SiteBookmark[bookmarks.length + sitesToVisit.length];
		System.arraycopy(bookmarks, 0, all, 0, bookmarks.length);
		System.arraycopy(
			sitesToVisit,
			0,
			all,
			bookmarks.length,
			sitesToVisit.length);
		return all;
	}
}
