/*******************************************************************************
 * Copyright (c) 2003, 2006 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.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
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.TableItem;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.HyperlinkSettings;
import org.eclipse.ui.forms.widgets.ScrolledFormText;
import org.eclipse.update.internal.core.UpdateCore;
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.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 SitesLabelProvider extends LabelProvider {

		public Image getImage(Object obj) {
			if (obj instanceof SiteBookmark)
				return UpdateUI.getDefault().getLabelProvider().get(
					UpdateUIImages.DESC_SITE_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) {
			viewer.refresh();
			checkItems();
		}

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

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

	private static DiscoveryFolder discoveryFolder = new DiscoveryFolder();
	private CheckboxTableViewer viewer;
	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 Button automaticallySelectMirrorsCheckbox;
	private EnvironmentFilter envFilter;
	private UpdateSearchRequest searchRequest;
	private ModelListener modelListener;
	
	private boolean automaticallySelectMirrors = true;

	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);

		createViewer(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);

		
		automaticallySelectMirrorsCheckbox = new Button(client, SWT.CHECK);
		automaticallySelectMirrorsCheckbox.setText(UpdateUIMessages.SitePage_automaticallySelectMirrors); 
		automaticallySelectMirrorsCheckbox.setSelection(true);
		automaticallySelectMirrorsCheckbox.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(SelectionEvent e) {
				automaticallySelectMirrors = automaticallySelectMirrorsCheckbox.getSelection();
				UpdateCore.getPlugin().getPluginPreferences().setValue(UpdateCore.P_AUTOMATICALLY_CHOOSE_MIRROR, automaticallySelectMirrors);
			}
		});
		gd = new GridData();
		gd.horizontalSpan = 2;
        gd.verticalAlignment = SWT.BOTTOM;
        automaticallySelectMirrorsCheckbox.setLayoutData(gd);
		
		Dialog.applyDialogFont(parent);

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

		return client;
	}

	private void createViewer(Composite parent) {
		viewer =
			CheckboxTableViewer.newCheckList(
				parent,
				SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
		viewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH));
		viewer.setContentProvider(new IStructuredContentProvider() {
			public Object[] getElements(Object parent) {
				return getAllSiteBookmarks();
			}

			public void dispose() {
			}

			public void inputChanged(Viewer viewer, Object oldInput,
					Object newInput) {
			}
		});
		viewer.setLabelProvider(new SitesLabelProvider());
		viewer.setInput(UpdateUI.getDefault().getUpdateModel());
		
		// bug # 83212
		viewer.setSorter( new ViewerSorter());
		
		
		initializeItems();

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

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

	}

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

	private void checkItems() {
		TableItem[] items = viewer.getTable().getItems();
		for (int i = 0; i < items.length; i++) {
			SiteBookmark bookmark = (SiteBookmark) items[i].getData();
			viewer.setChecked(bookmark, 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(viewer.getControl().getDisplay(), new Runnable() {
			public void run() {
				UpdateModel updateModel =
					UpdateUI.getDefault().getUpdateModel();
				IStructuredSelection ssel =
					(IStructuredSelection) viewer.getSelection();
				SiteBookmark bookmark = (SiteBookmark) ssel.getFirstElement();
				String selName = bookmark.getLabel();
				boolean answer = MessageDialog
								.openQuestion(
										getShell(),
										UpdateUIMessages.SitePage_remove_location_conf_title, 
										UpdateUIMessages.SitePage_remove_location_conf
												+ " " + selName); //$NON-NLS-1$

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

	private void handleEdit() {
		IStructuredSelection ssel =
			(IStructuredSelection) viewer.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);
			viewer.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 = viewer.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);
			}
			automaticallySelectMirrors = UpdateCore.getPlugin().getPluginPreferences().getBoolean(UpdateCore.P_AUTOMATICALLY_CHOOSE_MIRROR);
			automaticallySelectMirrorsCheckbox.setSelection(automaticallySelectMirrors);
		}
	}
	
	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 viewer.getCheckedElements().length != 0;
	}
}
