/*******************************************************************************
 * Copyright (c) 2000, 2007 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.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
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.jface.viewers.ViewerSorter;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
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.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.ui.PlatformUI;
import org.eclipse.update.configuration.IConfiguredSite;
import org.eclipse.update.configuration.IInstallConfiguration;
import org.eclipse.update.configuration.IInstallConfigurationChangedListener;
import org.eclipse.update.configuration.LocalSystemInfo;
import org.eclipse.update.core.IFeature;
import org.eclipse.update.core.ISite;
import org.eclipse.update.internal.core.ConfiguredSite;
import org.eclipse.update.internal.core.UpdateCore;
import org.eclipse.update.internal.operations.UpdateUtils;
import org.eclipse.update.internal.ui.UpdateLabelProvider;
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.parts.DefaultContentProvider;
import org.eclipse.update.internal.ui.parts.SWTUtil;
import org.eclipse.update.operations.IInstallFeatureOperation;

public class TargetPage extends BannerPage implements IDynamicPage {
	
	private static final int FEATURE_NAME_COLUMN = 0;
	private static final int FEATURE_VERSION_COLUMN = 1;
	private static final int FEATURE_SIZE_COLUMN = 2;
	private static final int INSTALLATION_DIRECTORY_COLUMN = 3;
	
	private float featureNameColumnProcetange = 0.25f;
	private float featureVersionColumnProcetange = 0.25f;
	private float featureSizeColumnProcetange = 0.15f;
	
	private TableViewer jobViewer;
	private IInstallConfiguration config;
	private Label requiredSpaceLabel;
	private Label availableSpaceLabel;
	private IInstallFeatureOperation[] jobs;
    //private IInstallFeatureOperation currentJob;
    private Label installLocation;
    private Button changeLocation;
    private IConfiguredSite [] addedSites;
    
    private boolean isUpdate; // whether the wizard is updating a feature or installing a new one

	class JobsContentProvider
		extends DefaultContentProvider
		implements IStructuredContentProvider {
		public Object[] getElements(Object parent) {
			return jobs;
		}
	}

	class JobsLabelProvider
		extends LabelProvider
		implements ITableLabelProvider {
			
		public Image getColumnImage(Object obj, int col) {
			
			if (col > 0) {
				return null;
			}
			
			UpdateLabelProvider provider = UpdateUI.getDefault().getLabelProvider();

			IInstallFeatureOperation job = (IInstallFeatureOperation) obj;
			ImageDescriptor base =
				job.getFeature().isPatch()
					? UpdateUIImages.DESC_EFIX_OBJ
					: UpdateUIImages.DESC_FEATURE_OBJ;
			int flags = 0;
			if (job.getTargetSite() == null)
				flags = UpdateLabelProvider.F_ERROR;
			return provider.get(base, flags);
		}

		public String getColumnText(Object obj, int col) {
			
			IFeature feature = ((IInstallFeatureOperation) obj).getFeature();
			IConfiguredSite csite =((IInstallFeatureOperation)obj).getTargetSite(); 
			ISite site = csite!=null?csite.getSite():null;
			if (col == FEATURE_NAME_COLUMN) {				
				return feature.getLabel();
			} else if (col == FEATURE_VERSION_COLUMN) {
				return feature.getVersionedIdentifier().getVersion().toString();
			} else if (col == FEATURE_SIZE_COLUMN) {
				if (site==null)
					return ""; //$NON-NLS-1$
				long requiredSpace = site.getDownloadSizeFor(feature) + site.getInstallSizeFor(feature);
				return getSizeString(requiredSpace);
			} else if (col == INSTALLATION_DIRECTORY_COLUMN) {
				if (site==null)
					return ""; //$NON-NLS-1$
				return site.getURL().getFile().toString();
			}
			return ""; //$NON-NLS-1$
		}
	}
	
	class JobViewerSorter extends ViewerSorter {
		
		
		private static final int ASCENDING = 0;

		private static final int DESCENDING = 1;

		private int column;

		private int direction;

		public void doSort(int column) {

			if (column == this.column) {
				direction = 1 - direction;
			} else {
				this.column = column;
				direction = ASCENDING;
			}
		}

		/**
		 * Compares the object for sorting
		 */
		public int compare(Viewer viewer, Object o1, Object o2) {

			int rc = 0;
			
			IFeature feature1 = ((IInstallFeatureOperation) o1).getFeature();
			IFeature feature2 = ((IInstallFeatureOperation) o2).getFeature();

			String featureName1 = feature1.getLabel();
			String featureName2 = feature2.getLabel();
			
			String featureId1 = feature1.getVersionedIdentifier().getVersion().toString();
			String featureId2 = feature2.getVersionedIdentifier().getVersion().toString();

			String installationDirectory1 = ((IInstallFeatureOperation)o1).getTargetSite().getSite().getURL().getFile().toString();
			String installationDirectory2 = ((IInstallFeatureOperation)o2).getTargetSite().getSite().getURL().getFile().toString();

			switch (column) {
			case FEATURE_NAME_COLUMN:
				rc = collator.compare(featureName1, featureName2);
				break;
			case FEATURE_VERSION_COLUMN:
				rc = collator.compare(featureId1, featureId2);
				break;
			case INSTALLATION_DIRECTORY_COLUMN:
				rc = collator.compare(installationDirectory1, installationDirectory2);
				break;
			}

			// If descending order, flip the direction
			if (direction == DESCENDING)
				rc = -rc;

			return rc;
		}
	}
	
	class ConfigListener implements IInstallConfigurationChangedListener {
		public void installSiteAdded(IConfiguredSite csite) {
			
			// set the site as target for all jobs without a target
			for (int i=0; jobs != null && i<jobs.length; i++)
				if (jobs[i].getTargetSite() == null && getSiteVisibility(csite, jobs[i])) {
					jobs[i].setTargetSite(csite);
				}

			jobViewer.refresh();
		}

		public void installSiteRemoved(IConfiguredSite csite) {
			// remove the target site for all jobs that use it
			// set the site as target for all jobs without a target
			boolean refreshJobs = false;
			for (int i=0; jobs != null && i<jobs.length; i++)
				if (jobs[i].getTargetSite() == csite) {
					jobs[i].setTargetSite(null);
					refreshJobs = true;
				}
				
			pageChanged();
			
			jobViewer.refresh();
			if (refreshJobs) {
				jobViewer.getControl().setFocus();
			}
		}
	}

	/**
	 * Constructor for ReviewPage2
	 */
	public TargetPage(IInstallConfiguration config, boolean isUpdate) {
		super("Target"); //$NON-NLS-1$
		setTitle(UpdateUIMessages.InstallWizard_TargetPage_title); 
		setDescription(UpdateUIMessages.InstallWizard_TargetPage_desc); 
		this.config = config;
		UpdateUI.getDefault().getLabelProvider().connect(this);
		this.isUpdate = isUpdate;
	}

	public void setJobs(IInstallFeatureOperation[] jobs) {
		//we need only unique features
		//using Set here allows us to get rid of a duplicate elements
		Set jobsSet = new HashSet();
		for (int i = 0; i < jobs.length; i++) {
			jobsSet.add(jobs[i]);
		}
		
		this.jobs = (IInstallFeatureOperation[]) jobsSet.toArray(new IInstallFeatureOperation[jobsSet.size()]);
	}

	public void dispose() {
		UpdateUI.getDefault().getLabelProvider().disconnect(this);
//		config.removeInstallConfigurationChangedListener(configListener);
		super.dispose();
	}

	public Control createContents(Composite parent) {
		Composite client = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		layout.numColumns = 3;
		layout.marginWidth = layout.marginHeight = 0;
		client.setLayout(layout);
		client.setLayoutData(new GridData(GridData.FILL_BOTH));
		
		Label label = new Label(client, SWT.NULL);
		label.setText(UpdateUIMessages.InstallWizard_TargetPage_jobsLabel); 
		createJobViewer(client);

		label = new Label(client, SWT.NULL);
		label.setText(UpdateUIMessages.InstallWizard_TargetPage_location); 
        GridData gd = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING);
        label.setLayoutData(gd);

		installLocation = new Label(client, SWT.NULL);
        installLocation.setText(""); //$NON-NLS-1$
        gd = new GridData(GridData.FILL_HORIZONTAL);
        installLocation.setLayoutData(gd);
        
        changeLocation = new Button(client, SWT.PUSH);
        changeLocation.setText(UpdateUIMessages.InstallWizard_TargetPage_location_change); 
        changeLocation.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                changeLocationOfFeatures();
            }

			
        });
			
		Composite status = new Composite(client, SWT.NULL);
		gd = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
		gd.horizontalSpan = 3;
		status.setLayoutData(gd);
		layout = new GridLayout();
		layout.numColumns = 2;
		status.setLayout(layout);
		label = new Label(status, SWT.NULL);
		label.setText(UpdateUIMessages.InstallWizard_TargetPage_requiredSpace); 
		requiredSpaceLabel = new Label(status, SWT.NULL);
		requiredSpaceLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
		label = new Label(status, SWT.NULL);
		label.setText(UpdateUIMessages.InstallWizard_TargetPage_availableSpace); 
		availableSpaceLabel = new Label(status, SWT.NULL);
		availableSpaceLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

        PlatformUI.getWorkbench().getHelpSystem().setHelp(client, "org.eclipse.update.ui.MultiTargetPage2"); //$NON-NLS-1$
		
		Dialog.applyDialogFont(parent);
		
		return client;
	}

	private void createJobViewer(Composite parent) {
		
		final Table table = new Table(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.MULTI | SWT.RESIZE | SWT.FULL_SELECTION);
		
		TableColumn featureNameColumn = new TableColumn(table, SWT.LEFT, FEATURE_NAME_COLUMN);
		featureNameColumn.setText(UpdateUIMessages.TargetPage_FeatureNameColumn); 
		featureNameColumn.setWidth(75);
		
		TableColumn featureVersionColumn = new TableColumn(table, SWT.LEFT, FEATURE_VERSION_COLUMN);
		featureVersionColumn.setText(UpdateUIMessages.TargetPage_Feature_Version); 
		featureVersionColumn.setWidth(75);
		
		TableColumn featureSizeColumn = new TableColumn(table, SWT.LEFT, FEATURE_SIZE_COLUMN);
		featureSizeColumn.setText(UpdateUIMessages.TargetPage_Feature_Size); 
		featureSizeColumn.setWidth(75);
		
		TableColumn featureLocationColumn = new TableColumn(table, SWT.LEFT, INSTALLATION_DIRECTORY_COLUMN);
		featureLocationColumn.setText(UpdateUIMessages.TargetPage_InstallationDirectoryColumn); 
		featureLocationColumn.setWidth(75);
		jobViewer = new TableViewer(table);
		
		//jobViewer = new TableViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER | SWT.MULTI);
		GridData gd = new GridData(GridData.FILL_BOTH);
        gd.horizontalSpan = 3;
		gd.widthHint = 150;
		gd.heightHint = 200;
		jobViewer.getTable().setLayoutData(gd);
		jobViewer.setContentProvider(new JobsContentProvider());
		jobViewer.setLabelProvider(new JobsLabelProvider());
		jobViewer.setSorter(new JobViewerSorter());
		
		jobViewer.addDoubleClickListener(new IDoubleClickListener() {
				public void doubleClick(DoubleClickEvent event) {
					changeLocationOfFeatures();				
				}
			}
		);
		
		table.addListener(SWT.MenuDetect, new Listener() {
		      public void handleEvent(Event event) {
		    	  Menu menu = new Menu (getShell(), SWT.POP_UP);
					MenuItem item = new MenuItem (menu, SWT.PUSH);
					item.setText(UpdateUIMessages.InstallWizard_TargetPage_location_change);
					item.addListener(SWT.Selection, new Listener () {
							public void handleEvent (Event e) {
								changeLocationOfFeatures();
							}
						}
					);
					menu.setLocation (event.x, event.y);
					menu.setVisible (true);
		      }
			}
		);
		featureNameColumn.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent event) {
					((JobViewerSorter) jobViewer.getSorter()).doSort(FEATURE_NAME_COLUMN);
					jobViewer.refresh();
				}
		    }
		);
		
		featureVersionColumn.addSelectionListener(new SelectionAdapter() {
		      	public void widgetSelected(SelectionEvent event) {
		      		((JobViewerSorter) jobViewer.getSorter()).doSort(FEATURE_VERSION_COLUMN);
		      		jobViewer.refresh();
		      	}
		    }
		);
		
		featureSizeColumn.addSelectionListener(new SelectionAdapter() {
		      	public void widgetSelected(SelectionEvent event) {
		      		((JobViewerSorter) jobViewer.getSorter()).doSort(FEATURE_SIZE_COLUMN);
		      		jobViewer.refresh();
		      	}
		    }
		);
		
		featureLocationColumn.addSelectionListener(new SelectionAdapter() {
		      	public void widgetSelected(SelectionEvent event) {
		      		((JobViewerSorter) jobViewer.getSorter()).doSort(INSTALLATION_DIRECTORY_COLUMN);
		      		jobViewer.refresh();
		      	}
		    }
		);
		
		table.addControlListener(new ControlAdapter() {
			public void controlResized(ControlEvent e) {


				Rectangle area = table.getClientArea();
				Point preferredSize = table.computeSize(SWT.DEFAULT, SWT.DEFAULT);

				int tableWidth = area.width - 3 * table.getBorderWidth();
				if (preferredSize.y > area.height + table.getHeaderHeight()){
					Point vBarSize = table.getVerticalBar().getSize();
					tableWidth -= vBarSize.x;
				}		
				
				TableColumn featureNameColumn = table.getColumn(FEATURE_NAME_COLUMN);
				TableColumn featureVersionColumn = table.getColumn(FEATURE_VERSION_COLUMN);
				TableColumn featureSizeColumn = table.getColumn(FEATURE_SIZE_COLUMN);
				TableColumn featureLocationColumn = table.getColumn(INSTALLATION_DIRECTORY_COLUMN);

				featureNameColumn.setWidth((int)(tableWidth * featureNameColumnProcetange));
				featureVersionColumn.setWidth((int)(tableWidth * featureVersionColumnProcetange));
				featureSizeColumn.setWidth((int)(tableWidth * featureSizeColumnProcetange));
				featureLocationColumn.setWidth(tableWidth - featureNameColumn.getWidth() - featureVersionColumn.getWidth() - featureSizeColumn.getWidth());		    	

				
				featureNameColumnProcetange = featureNameColumn.getWidth() / (float)tableWidth;
				featureVersionColumnProcetange = featureVersionColumn.getWidth() / (float)tableWidth;
				featureSizeColumnProcetange = featureSizeColumn.getWidth() / (float)tableWidth;
			}
		});


		jobViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			public void selectionChanged(SelectionChangedEvent event) {
				updateStatus();

			}
		});
		
		table.setHeaderVisible(true);
	    table.setLinesVisible(true);
	}

	public void setVisible(boolean visible) {
		if (visible) {
			initializeDefaultTargetSites();
			jobViewer.setInput(jobs);
			if (jobViewer.getSelection().isEmpty() && jobs.length > 0)
				jobViewer.setSelection(new StructuredSelection(jobs[0]));
		}
		
		super.setVisible(visible);
	}

	private void verifyNotEmpty(boolean empty) {
		String errorMessage = null;
		if (empty)
			errorMessage = UpdateUIMessages.InstallWizard_TargetPage_location_empty; 
		setErrorMessage(errorMessage);
		setPageComplete(!empty);
	}


	private void updateStatus() {
		
		IStructuredSelection selectedJobs = (IStructuredSelection)jobViewer.getSelection();
		IInstallFeatureOperation selectedJob = (IInstallFeatureOperation)selectedJobs.getFirstElement();
	
		requiredSpaceLabel.setText(""); //$NON-NLS-1$
		availableSpaceLabel.setText(""); //$NON-NLS-1$
		installLocation.setText(""); //$NON-NLS-1$
		
		if (selectedJob == null) {
			return;
		}
		
		IConfiguredSite site = selectedJob.getTargetSite(); /*(IConfiguredSite) element;*/
		File file = new File(site.getSite().getURL().getFile());
		long available = -1;
		long required = -1;
		if (areAllTargetSitesSame()) {
			available = LocalSystemInfo.getFreeSpace(file);
			required = computeRequiredSizeFor(site);
			//add the download size to space required to do operation since all plugins and nonplugin data will be downloaded first
			required += computeDownloadSizeFor(site); 
			installLocation.setText(new File(selectedJob.getTargetSite().getSite().getURL().getFile()).toString());
		}		
		
		if (available == LocalSystemInfo.SIZE_UNKNOWN)
			available = -1;
		
		requiredSpaceLabel.setText(getSizeString(required));
		availableSpaceLabel.setText(getSizeString(available));
		
		
		//if the available space was retireved from the OS and the required space is greater that the available space, do not let the user continue
		if(available != LocalSystemInfo.SIZE_UNKNOWN && required > available){
			this.setPageComplete(false);
			//TODO: set error message: "...not enough space..."
		}else
			this.setPageComplete(true);
	}
	
	private boolean areAllTargetSitesSame() {
		IStructuredSelection selectedJobs = (IStructuredSelection)jobViewer.getSelection();
		Iterator iterator = selectedJobs.iterator();
		URL site = null;
		if (iterator != null) {
			while(iterator.hasNext()) {
				IInstallFeatureOperation current = (IInstallFeatureOperation) iterator.next();				
				if (site != null) {
					if (!site.equals(current.getTargetSite().getSite().getURL())) {
						return false;
					}
				} else {
					site = current.getTargetSite().getSite().getURL();
				}
			}
			return true;
		}
		return false;
	}

	private String getSizeString(long size) {
		if (size <= 0) {
			return UpdateUIMessages.InstallWizard_TargetPage_unknownSize;
		} else {
			double order = 1024.0;
			double sizeInMB = size / order;
			double sizeInGB = size / order / order;
			if ( sizeInMB < 1) {
				return NLS.bind(UpdateUIMessages.InstallWizard_TargetPage_size_KB, "" + size); //$NON-NLS-1$
			} else {
				String pattern = "#.##"; //$NON-NLS-1$
				DecimalFormat formatter = new DecimalFormat(pattern);
				if (sizeInGB < 1) {					
					return NLS.bind(UpdateUIMessages.InstallWizard_TargetPage_size_MB, formatter.format(sizeInMB));
				} else {
					return NLS.bind(UpdateUIMessages.InstallWizard_TargetPage_size_GB, formatter.format(sizeInGB));
				}
			}
		}
	}

	private long computeRequiredSizeFor(IConfiguredSite site) {
		long totalSize = 0;
		for (int i = 0; i < jobs.length; i++) {
			if (site.equals(jobs[i].getTargetSite())) {
				long jobSize = site.getSite().getInstallSizeFor(jobs[i].getFeature());
				if (jobSize == -1)
					return -1;
				totalSize += jobSize;
			}
		}
		return totalSize;
	}
	
	private long computeDownloadSizeFor(IConfiguredSite site) {
		long totalSize = 0;
		for (int i = 0; i < jobs.length; i++) {
			if (site.equals(jobs[i].getTargetSite())) {
				long jobSize = site.getSite().getDownloadSizeFor(jobs[i].getFeature());
				if (jobSize == -1)
					return -1;
				totalSize += jobSize;
			}
		}
		return totalSize;
	}

	private void pageChanged() {
		boolean empty = false;
		for (int i=0; jobs!=null && i<jobs.length; i++) {
			if (jobs[i].getTargetSite() == null) {
				empty = true;
				break;
			}
		
			IFeature feature = jobs[i].getFeature();
			if (feature.isPatch()) {
				// Patches must go together with the features
				// they are patching.
				
				// Check current jobs
				IInstallFeatureOperation patchedFeatureJob = findPatchedFeature(feature);
				if (patchedFeatureJob != null
					&& patchedFeatureJob.getTargetSite() != null
					&& !jobs[i].getTargetSite().equals(patchedFeatureJob.getTargetSite())) {
					String msg = NLS.bind(UpdateUIMessages.InstallWizard_TargetPage_patchError, (new String[] {
                    feature.getLabel(),
                    patchedFeatureJob.getFeature().getLabel()}));
					setErrorMessage(msg);
					setPageComplete(false);
					return;
				}
				// Check installed features
				IFeature patchedFeature = UpdateUtils.getPatchedFeature(feature);
				if (patchedFeature != null  
					&& !jobs[i].getTargetSite().equals(patchedFeature.getSite().getCurrentConfiguredSite())) {
					String msg = NLS.bind(UpdateUIMessages.InstallWizard_TargetPage_patchError2, (new String[] {
                    feature.getLabel(),
                    patchedFeature.getLabel(),
                    patchedFeature.getSite().getCurrentConfiguredSite().getSite().getURL().getFile()}));
					setErrorMessage(msg);
					setPageComplete(false);
					return;
				}
			}
		}
		verifyNotEmpty(empty);
	}
	
	
	private  boolean getSiteVisibility(IConfiguredSite site, IInstallFeatureOperation job) {
		// Do not allow installing into a non-updateable site
		if (!site.isUpdatable())
			return false;
		
		// If affinity site is known, only it should be shown
		IConfiguredSite affinitySite = UpdateUtils.getAffinitySite(config, job.getFeature());
		if (affinitySite != null) {
			// Must compare referenced sites because
			// configured sites themselves may come from 
			// different configurations
			return site.getSite().equals(affinitySite.getSite());
		}
		
		// Co-locate updates with the old feature
		if (job.getOldFeature() != null) {
			IConfiguredSite oldSite = UpdateUtils.getSiteWithFeature(config, job.getOldFeature().getVersionedIdentifier().getIdentifier());
			return (site == oldSite);
		}

		// Allow installing into any site that is updateable and there is no affinity specified
		return true;
	}
	
	private void initializeDefaultTargetSites() {
		
		
		IConfiguredSite mostReceantlyUsedSite = getMostReceantlyUsedSite();
		for (int i = 0; i < jobs.length; i++) {
			if (jobs[i].getTargetSite() != null)
				continue;
			
			IConfiguredSite affinitySite =	UpdateUtils.getAffinitySite(config, jobs[i].getFeature());
			if (affinitySite != null) {
				jobs[i].setTargetSite(affinitySite);
				continue;
			}

			IConfiguredSite defaultSite = UpdateUtils.getDefaultTargetSite(config, jobs[i], false);
			if (defaultSite != null) {
				jobs[i].setTargetSite(defaultSite);
				continue;
			}
			
			if (mostReceantlyUsedSite != null) {
				jobs[i].setTargetSite(mostReceantlyUsedSite);
				continue;
			}
			
			IConfiguredSite csite = getFirstTargetSite(jobs[i]);
			if (csite == null && Platform.getInstallLocation().isReadOnly() && isUpdate == false) {
				// there are no updateable sites, the installation location is read-only and we are installing a new feature
				// make an update site in the configuration area
				String configurationLocation = Platform.getConfigurationLocation().getURL().getFile();
				File site = new File(configurationLocation);
				if (!ConfiguredSite.canWrite(site)) {
					// if we cannot write to the configuration area then make an update site in the user's home directory
					site = new File(System.getProperty("user.home") + File.separator + ".eclipse" + File.separator + //$NON-NLS-1$ //$NON-NLS-2$
							Platform.getProduct().getId() + File.separator + "updates"); //$NON-NLS-1$
				}
				try {
					csite = config.createConfiguredSite(site);
					config.addConfiguredSite(csite);
					IStatus status = csite.verifyUpdatableStatus();
					if (!status.isOK())
						throw new CoreException(status);
				} catch (CoreException e) {
					// there was a problem, the user must choose an installation site
					csite = null;
					// no need to check if the directory exists because File.delete() returns false if it's not there
					deleteDir(site);
				}
			}

			jobs[i].setTargetSite(csite);
		}
	}
	
		private boolean deleteDir(File dir) {
		if (dir.isDirectory()) {
			String[] files = dir.list();
			for (int i = 0; i < files.length; i++) {
				if (!deleteDir(new File(dir, files[i]))) {
					return false;
				}
			}
		}
		return dir.delete();
	}
	
	private IConfiguredSite getMostReceantlyUsedSite() {
		IDialogSettings master = UpdateUI.getDefault().getDialogSettings();
		IDialogSettings section = master.getSection(TargetSiteDialog.MOST_RECEANTLY_USED_SITE_URL);
		if (section == null) {
			return null;
		}
		String mostReceantlyUsedSiteURLString = section.get(TargetSiteDialog.MOST_RECEANTLY_USED_SITE_URL); 
		if (mostReceantlyUsedSiteURLString == null) {
			return null;
		}
		
		URL mostReceantlyUsedSiteURL = null;
		try {
			mostReceantlyUsedSiteURL = new URL(mostReceantlyUsedSiteURLString);
		} catch (MalformedURLException mue) {
			UpdateCore.log("Url format is wrong for the mostReceantlyUsedSiteURL in preferences", mue); //$NON-NLS-1$
			mue.printStackTrace();
			return null;
		}
		IConfiguredSite[] sites = config.getConfiguredSites();
		for (int i = 0; i < sites.length; i++) {
			IConfiguredSite configuredSite = sites[i];
			if (mostReceantlyUsedSiteURL.equals(configuredSite.getSite().getURL())) {
				return configuredSite;
			}
		}
		return null;
	}
	

	private IConfiguredSite getFirstTargetSite(IInstallFeatureOperation job) {
		IConfiguredSite[] sites = config.getConfiguredSites();
		for (int i = 0; i < sites.length; i++) {
			IConfiguredSite csite = sites[i];
			if (getSiteVisibility(csite, job) && csite.getSite().getCurrentConfiguredSite().verifyUpdatableStatus().isOK())
				return csite;
		}
		return null;
	}
	
	public IInstallFeatureOperation findPatchedFeature(IFeature patch) {
		for (int i=0; i<jobs.length; i++) {
			IFeature target = jobs[i].getFeature();
			if (!target.equals(patch) && UpdateUtils.isPatch(target, patch))
				return jobs[i];
		}
		return null;
            }
    
    /* (non-Javadoc)
     * @see org.eclipse.jface.wizard.IWizardPage#isPageComplete()
     */
    public boolean isPageComplete() {
        // check if all jobs have a target site set
        for (int i = 0; jobs != null && i < jobs.length; i++) {
            if (jobs[i].getTargetSite() == null)
                return false;
        }
        return super.isPageComplete();
    }

    /**
     * @param job
     */
/*    private void setTargetLocation(IInstallFeatureOperation job) {
        if (job != null && job.getTargetSite() != null) {
            installLocation.setText(new File(job.getTargetSite().getSite().getURL().getFile()).toString());
            updateStatus(job.getTargetSite());
        }
    }*/
    
    private IInstallFeatureOperation[] toJobArray(Iterator selectedJobs) {
		
    	if (selectedJobs == null) 
    		return new IInstallFeatureOperation[0];
    	
    	ArrayList result = new ArrayList();
    	
    	while (selectedJobs.hasNext()) {
    		result.add(selectedJobs.next());
    	}
    	
    	return (IInstallFeatureOperation[])result.toArray(new IInstallFeatureOperation[result.size()]);
	}

	private void changeLocationOfFeatures() {
		IStructuredSelection selection = (IStructuredSelection) jobViewer.getSelection();
		if (selection == null)
		    return;
		Iterator selectedJob = selection.iterator();
		if (selectedJob == null) 
		    return;
		
		TargetSiteDialog dialog = new TargetSiteDialog(getShell(), config, toJobArray(selection.iterator()));
		dialog.create();

		SWTUtil.setDialogSize(dialog, 400, 300);
		
		dialog.getShell().setText(UpdateUIMessages.SitePage_new); 
		if ( dialog.open() == Dialog.OK) {
			pageChanged();
			jobViewer.refresh();
			updateStatus();
			addedSites = dialog.getAddedSites();
		}
	}
	
	void removeAddedSites() {
		if (addedSites!=null) {
			for (int i=0; i<addedSites.length; i++) {
				config.removeConfiguredSite(addedSites[i]);
			}
		}
	}
}
