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

import java.net.URL;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTreeViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.HyperlinkSettings;
import org.eclipse.ui.forms.widgets.ScrolledFormText;
import org.eclipse.update.internal.core.UpdateManagerUtils;
import org.eclipse.update.internal.ui.UpdateUI;
import org.eclipse.update.internal.ui.UpdateUIImages;
import org.eclipse.update.internal.ui.UpdateUIMessages;
import org.eclipse.update.internal.ui.model.DiscoveryFolder;
import org.eclipse.update.internal.ui.model.SiteBookmark;
import org.eclipse.update.internal.ui.model.SiteCategory;
import org.eclipse.update.internal.ui.model.UpdateModel;
import org.eclipse.update.internal.ui.parts.DefaultContentProvider;
import org.eclipse.update.internal.ui.parts.SWTUtil;
import org.eclipse.update.operations.IUpdateModelChangedListener;
import org.eclipse.update.search.EnvironmentFilter;
import org.eclipse.update.search.UpdateSearchRequest;
import org.eclipse.update.search.UpdateSearchScope;

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 false;
//			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 exportButton;
	private Button importButton;
	private Button envFilterCheck;
	private EnvironmentFilter envFilter;
	private UpdateSearchRequest searchRequest;
	private ModelListener modelListener;

	public SitePage(UpdateSearchRequest searchRequest) {
		super("SitePage"); //$NON-NLS-1$
        this.searchRequest = searchRequest;
		setTitle(UpdateUIMessages.SitePage_title); 
		setDescription(UpdateUIMessages.SitePage_desc); 
		UpdateUI.getDefault().getLabelProvider().connect(this);
    	envFilter = new EnvironmentFilter();

		modelListener = new ModelListener();
		UpdateUI.getDefault().getUpdateModel().addUpdateModelChangedListener(
			modelListener);
	}

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

	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(UpdateUIMessages.SitePage_label); 
		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(UpdateUIMessages.SitePage_addUpdateSite); 
		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(UpdateUIMessages.SitePage_addLocalSite); 
		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(UpdateUIMessages.SitePage_addLocalZippedSite); 
		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(UpdateUIMessages.SitePage_edit); 
		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(UpdateUIMessages.SitePage_remove); 
		removeButton.setEnabled(false);
		removeButton.setLayoutData(
			new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		SWTUtil.setButtonDimensionHint(removeButton);
		removeButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleRemove();
			}
		});
		
		// separator
		new Label(buttonContainer, SWT.None);
		
		importButton = new Button(buttonContainer, SWT.PUSH);
		importButton.setText(UpdateUIMessages.SitePage_import); 
		importButton.setLayoutData(
			new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		SWTUtil.setButtonDimensionHint(importButton);
		importButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleImport();
			}
		});
		
		exportButton = new Button(buttonContainer, SWT.PUSH);
		exportButton.setText(UpdateUIMessages.SitePage_export); 
		exportButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
		SWTUtil.setButtonDimensionHint(exportButton);
		exportButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				handleExport();
			}
		});

		descLabel = new ScrolledFormText(client, true);
		descLabel.setText(""); //$NON-NLS-1$
		descLabel.setBackground(parent.getBackground());
		HyperlinkSettings settings = new HyperlinkSettings(parent.getDisplay());
		descLabel.getFormText().setHyperlinkSettings(settings);
		
		gd = new GridData(SWT.FILL, SWT.FILL, true, true);
		gd.horizontalSpan = 1;
        gd.heightHint = 30;
		descLabel.setLayoutData(gd);
		
		envFilterCheck = new Button(client, SWT.CHECK);
		envFilterCheck.setText(UpdateUIMessages.SitePage_ignore); 
		envFilterCheck.setSelection(true);
		toggleEnvFilter(true);
		envFilterCheck.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				toggleEnvFilter(envFilterCheck.getSelection());
			}
		});
		gd = new GridData();
		gd.horizontalSpan = 2;
        gd.verticalAlignment = SWT.BOTTOM;
		envFilterCheck.setLayoutData(gd);

		Dialog.applyDialogFont(parent);

		PlatformUI.getWorkbench().getHelpSystem().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());
			}
		});

	}

	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(), getAllSiteBookmarks());
		dialog.create();
		dialog.getShell().setText(UpdateUIMessages.SitePage_new); 
		if (dialog.open() == NewUpdateSiteDialog.OK)
			updateSearchRequest();
	}

	private void handleAddLocal() {
		SiteBookmark siteBookmark = LocalSiteSelector.getLocaLSite(getShell(), this.getAllSiteBookmarks());
		if (siteBookmark != null) {
			if (handleNameEdit(siteBookmark) == EditSiteDialog.OK) {
				siteBookmark.setSelected(true);
				UpdateModel model = UpdateUI.getDefault().getUpdateModel();
				model.addBookmark(siteBookmark);
				model.saveBookmarks();
				updateSearchRequest();
			}
		}
		return;
	}

	private void handleAddLocalZipped() {
		SiteBookmark siteBookmark = LocalSiteSelector
				.getLocaLZippedSite(getShell(), this.getAllSiteBookmarks());
		if (siteBookmark != null) {
			if (handleNameEdit(siteBookmark) == EditSiteDialog.OK) {
				siteBookmark.setSelected(true);
				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(),
										UpdateUIMessages.SitePage_remove_location_conf_title, //$NON-NLS-1$
										UpdateUIMessages.SitePage_remove_location_conf
												+ " " + 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, getAllSiteBookmarks());
		dialog.create();
		String title = bookmark.isLocal() ? UpdateUIMessages.SitePage_dialogEditLocal : UpdateUIMessages.SitePage_dialogEditUpdateSite; 
																																				  // //$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 handleImport() {
		SiteBookmark[] siteBookmarks = SitesImportExport.getImportedBookmarks(getShell());
		if (siteBookmarks != null && siteBookmarks.length > 0) {
			UpdateModel model = UpdateUI.getDefault().getUpdateModel();
			SiteBookmark[] currentBookmarks = getAllSiteBookmarks();
			for (int i=0; i<siteBookmarks.length; i++) {
				boolean siteExists = false;
				for (int j=0; !siteExists && j<currentBookmarks.length; j++)
					if (currentBookmarks[j].getURL().equals(siteBookmarks[i].getURL()))
						siteExists = true;
				if (!siteExists)
					model.addBookmark(siteBookmarks[i]);
			}
			model.saveBookmarks();
			updateSearchRequest();
		}
		return;
	}
	
	private void handleExport() {
		SitesImportExport.exportBookmarks(getShell(), getAllSiteBookmarks());
	}
	
	private int handleNameEdit(SiteBookmark bookmark) {
		EditSiteDialog dialog = new EditSiteDialog(getShell(), bookmark, getAllSiteBookmarks(), true);
		dialog.create();
		String title = bookmark.isLocal() ? UpdateUIMessages.SitePage_dialogEditLocal : UpdateUIMessages.SitePage_dialogEditUpdateSite; 
		// //$NON-NLS-2$
		dialog.getShell().setText(title);
		int rc = dialog.open();
		return rc;
	}

	private void handleSiteChecked(SiteBookmark bookmark, boolean checked) {
		if (bookmark.isUnavailable()) {
			bookmark.setSelected(false);
			treeViewer.setChecked(bookmark, false);
			return;
		}
		
		bookmark.setSelected(checked);
		updateSearchRequest();
	}


	private void handleSelectionChanged(IStructuredSelection ssel) {
		boolean enable = false;
		Object item = ssel.getFirstElement();
		String description = null;
		if (item instanceof SiteBookmark) {
			enable = !((SiteBookmark) item).isReadOnly();
			description = ((SiteBookmark)item).getDescription();
		} else if (item instanceof SiteCategory) {
//			IURLEntry descEntry = ((SiteCategory)item).getCategory().getDescription();
//			if (descEntry != null)
//				description = descEntry.getAnnotation();
		}
		editButton.setEnabled(enable);
		removeButton.setEnabled(enable);

		if (description == null)
			description = ""; //$NON-NLS-1$
		descLabel.setText(UpdateManagerUtils.getWritableXMLString(description));
	}

	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);
		setPageComplete(nsites > 0);
	}

	public UpdateSearchRequest getSearchRequest() {
		return searchRequest;
	}
    
	public void setVisible(boolean value) {
		super.setVisible(value);
		if (value) {
			// 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);
			}
		}
	}
	
	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;
	}

	public boolean isPageComplete() {
		return treeViewer.getCheckedElements().length != 0;
	}
}
