/*******************************************************************************
 * Copyright (c) 2000, 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
 *     Sebastian Davids <sdavids@gmx.de> - bug 77332 - [Markers] Add task dialog improvements
 *******************************************************************************/

package org.eclipse.ui.views.markers.internal;

import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.TrayDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.internal.ide.IDEWorkbenchPlugin;
import org.eclipse.ui.internal.ide.StatusUtil;

/**
 * Shows the properties of a new or existing marker
 */
class DialogMarkerProperties extends TrayDialog {

	private static final String DIALOG_SETTINGS_SECTION = "DialogMarkerPropertiesDialogSettings"; //$NON-NLS-1$
	
    /**
     * The marker being shown, or <code>null</code> for a new marker
     */
    private IMarker marker = null;

    /**
     * The resource on which to create a new marker
     */
    private IResource resource = null;

    /**
     * The type of marker to be created
     */
    private String type = IMarker.MARKER;

    /**
     * The initial attributes to use when creating a new marker
     */
    private Map initialAttributes = null;

    /**
     * The text control for the Description field.
     */
    private Text descriptionText;

    /**
     * The control for the Creation Time field.
     */
    private Label creationTime;

    /**
     * The text control for the Resource field.
     */
    private Text resourceText;

    /**
     * The text control for the Folder field.
     */
    private Text folderText;

    /**
     * The text control for the Location field.
     */
    private Text locationText;

    /**
     * Dirty flag.  True if any changes have been made.
     */
    private boolean dirty;

    private String title;

    /**
     * Creates the dialog.  By default this dialog creates a new marker.
     * To set the resource and initial attributes for the new marker, 
     * use <code>setResource</code> and <code>setInitialAttributes</code>.
     * To show or modify an existing marker, use <code>setMarker</code>.
     * 
     * @param shell the parent shell
     */
    DialogMarkerProperties(Shell parentShell) {
        super(parentShell);
        setShellStyle(getShellStyle() | SWT.RESIZE);
    }

    /**
     * Creates the dialog.  By default this dialog creates a new marker.
     * To set the resource and initial attributes for the new marker, 
     * use <code>setResource</code> and <code>setInitialAttributes</code>.
     * To show or modify an existing marker, use <code>setMarker</code>.
     * 
     * @param shell the parent shell
     * @param title the title of the dialog
     */
    DialogMarkerProperties(Shell parentShell, String title) {
        super(parentShell);
        setShellStyle(getShellStyle() | SWT.RESIZE);
        this.title = title;
    }

    /**
     * Sets the marker to show or modify.
     * 
     * @param marker the marker, or <code>null</code> to create a new marker
     */
    void setMarker(IMarker marker) {
        this.marker = marker;
        if (marker != null) {
            try {
                type = marker.getType();
            } catch (CoreException e) {
            }
        }
    }

    /**
     * Returns the marker being created or modified.
     * For a new marker, this returns <code>null</code> until
     * the dialog returns, but is non-null after.
     */
    IMarker getMarker() {
        return marker;
    }

    /**
     * Sets the resource to use when creating a new marker.
     * If not set, the new marker is created on the workspace root.
     * 
     * @param resource the marker's resource
     */
    public void setResource(IResource resource) {
        this.resource = resource;
    }

    /**
     * Returns the resource to use when creating a new marker,
     * or <code>null</code> if none has been set.
     * If not set, the new marker is created on the workspace root.
     */
    IResource getResource() {
        return resource;
    }

    /**
     * Sets initial attributes to use when creating a new marker.
     * If not set, the new marker is created with default attributes.
     */
    void setInitialAttributes(Map initialAttributes) {
        this.initialAttributes = initialAttributes;
    }

    /**
     * Returns the initial attributes to use when creating a new marker,
     * or <code>null</code> if not set.
     * If not set, the new marker is created with default attributes.
     */
    Map getInitialAttributes() {
        if (initialAttributes == null) {
            initialAttributes = new HashMap();
        }
        return initialAttributes;
    }

    /**
     * Method declared on Window.
     */
    protected void configureShell(Shell newShell) {
        super.configureShell(newShell);
        if (title == null) {
			newShell.setText(MarkerMessages.propertiesDialog_title);
		} else {
			newShell.setText(title);
		}
    }

    /**
     * Method declared on Dialog.
     */
    protected Control createDialogArea(Composite parent) {
        //initialize resources/properties
        if (marker != null) {
            resource = marker.getResource();
            try {
                initialAttributes = marker.getAttributes();
            } catch (CoreException e) {
            }
        } else if (resource == null) {
            resource = ResourcesPlugin.getWorkspace().getRoot();
        }

        Composite comp = (Composite) super.createDialogArea(parent);
        Composite composite = new Composite(comp, SWT.NULL);
        GridLayout layout = new GridLayout(2, false);
        layout.marginWidth = 0;
        layout.marginHeight = 0;
		composite.setLayout(layout);
        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        composite.setLayoutData(gridData);
    
        initializeDialogUnits(composite);

        createDescriptionArea(composite);
        if (marker != null) {
            createSeperator(composite);
            createCreationTimeArea(composite);
        }
        createAttributesArea(composite);
        if (resource != null) {
            createSeperator(composite);
            createResourceArea(composite);
        }

        updateDialogFromMarker();
        updateEnablement();
        
        Dialog.applyDialogFont(composite);
        
        return composite;
    }

    /**
     * Creates a seperator.
     */
    protected void createSeperator(Composite parent) {
		Label seperator = new Label(parent, SWT.NULL);
		GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
		gridData.horizontalSpan = 2;
		seperator.setLayoutData(gridData);
	}
    
    /**
     * Method createCreationTimeArea.
     * @param parent
     */
    private void createCreationTimeArea(Composite parent) {
        Label label = new Label(parent, SWT.NONE);
        label.setText(MarkerMessages
                .propertiesDialog_creationTime_text);

        creationTime = new Label(parent, SWT.NONE);
    }

    /**
     * Creates the OK and Cancel buttons.
     */
    protected void createButtonsForButtonBar(Composite parent) {
        createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,
                true);
        createButton(parent, IDialogConstants.CANCEL_ID,
                IDialogConstants.CANCEL_LABEL, false);
    }

    /**
     * Creates the area for the Description field.
     */
    private void createDescriptionArea(Composite parent) {
        Label label = new Label(parent, SWT.NONE);
        label.setText(MarkerMessages.propertiesDialog_description_text);
        descriptionText = new Text(parent, (SWT.SINGLE | SWT.BORDER));
        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        gridData.widthHint =  convertHorizontalDLUsToPixels(400);
        descriptionText.setLayoutData(gridData);

        descriptionText.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                markDirty();
            }
        });
    }

    /**
     * This method is intended to be overridden by subclasses. The attributes area is created between
     * the creation time area and the resource area.
     * 
     * @param parent the parent composite
     */
    protected void createAttributesArea(Composite parent) {
    }

    /**
     * Creates the area for the Resource field.
     */
    private void createResourceArea(Composite parent) {
        Label resourceLabel = new Label(parent, SWT.NONE);
        resourceLabel.setText(MarkerMessages.propertiesDialog_resource_text);
        resourceText = new Text(parent, SWT.SINGLE | SWT.WRAP
                | SWT.READ_ONLY | SWT.BORDER);
        GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
        resourceText.setLayoutData(gridData);

        Label folderLabel = new Label(parent, SWT.NONE);
        folderLabel.setText(MarkerMessages.propertiesDialog_folder_text);
        folderText = new Text(parent, SWT.SINGLE | SWT.WRAP | SWT.READ_ONLY
                | SWT.BORDER);
        gridData = new GridData(GridData.FILL_HORIZONTAL);
        folderText.setLayoutData(gridData);

        Label locationLabel = new Label(parent, SWT.NONE);
        locationLabel.setText(MarkerMessages.propertiesDialog_location_text);
        locationText = new Text(parent, SWT.SINGLE | SWT.WRAP
                | SWT.READ_ONLY | SWT.BORDER);
        gridData = new GridData(GridData.FILL_HORIZONTAL);
        locationText.setLayoutData(gridData);
    }

    /**
     * Updates the dialog from the marker state.
     */
    protected void updateDialogFromMarker() {
        if (marker == null) {
            updateDialogForNewMarker();
            return;
        }
        descriptionText.setText(Util.getProperty(IMarker.MESSAGE, marker));
        if (creationTime != null) {
			creationTime.setText(Util.getCreationTime(marker));
		}
        if (resourceText != null) {
			resourceText.setText(Util.getResourceName(marker));
		}
        if (folderText != null) {
			folderText.setText(Util.getContainerName(marker));
		}
        if (locationText != null) {
            String line = Util.getProperty(IMarker.LINE_NUMBER, marker);
            if (line.equals("")) { //$NON-NLS-1$
				locationText.setText(""); //$NON-NLS-1$
			} else {
				locationText.setText(NLS.bind(MarkerMessages.label_lineNumber, line));
			}
        }

        descriptionText.selectAll();
    }

    /**
     * Updates the dialog from the predefined attributes.
     */
    protected void updateDialogForNewMarker() {
        if (resource != null && resourceText != null && folderText != null) {
            resourceText.setText(resource.getName());

            IPath path = resource.getFullPath();
            int n = path.segmentCount() - 1; // n is the number of segments in container, not path
            if (n > 0) {
                int len = 0;
                for (int i = 0; i < n; ++i) {
					len += path.segment(i).length();
				}
                // account for /'s
                if (n > 1) {
					len += n - 1;
				}
                StringBuffer sb = new StringBuffer(len);
                for (int i = 0; i < n; ++i) {
                    if (i != 0) {
						sb.append('/');
					}
                    sb.append(path.segment(i));
                }
                folderText.setText(sb.toString());
            }
        }

        if (initialAttributes != null) {
            Object description = initialAttributes.get(IMarker.MESSAGE);
            if (description != null && description instanceof String) {
				descriptionText.setText((String) description);
			}
            descriptionText.selectAll();

            Object line = initialAttributes.get(IMarker.LINE_NUMBER);
            if (line != null && line instanceof Integer && locationText != null) {
				locationText.setText(
                    NLS.bind(MarkerMessages.label_lineNumber, line));
			}
        }
    }

    /**
     * Method declared on Dialog
     */
    protected void okPressed() {
        if (marker == null || Util.isEditable(marker)) {
            saveChanges();
        }
        super.okPressed();
    }

    /**
     * Sets the dialog's dirty flag to <code>true</code>
     */
    protected void markDirty() {
        dirty = true;
    }

    /**
     * @return
     * <ul>
     * <li><code>true</code> if the dirty flag has been set to true.</li>
     * <li><code>false</code> otherwise.</li>
     * </ul>
     */
    protected boolean isDirty() {
        return dirty;
    }

    /**
     * Saves the changes made in the dialog if needed.
     * Creates a new marker if needed.
     * Updates the existing marker only if there have been changes.
     */
    private void saveChanges() {

        final CoreException[] coreExceptions = new CoreException[1];

        try {
            final Map attrs = getMarkerAttributes();

            PlatformUI.getWorkbench().getProgressService().busyCursorWhile(
                    new IRunnableWithProgress() {
                        /* (non-Javadoc)
                         * @see org.eclipse.jface.operation.IRunnableWithProgress#run(org.eclipse.core.runtime.IProgressMonitor)
                         */
                        public void run(IProgressMonitor monitor) {
                            try {

                                monitor.beginTask("", 100);//$NON-NLS-1$
                                ResourcesPlugin.getWorkspace().run(
                                        new IWorkspaceRunnable() {
                                            public void run(
                                                    IProgressMonitor monitor)
                                                    throws CoreException {
                                                if (marker == null) {
													createMarker(monitor);
												}
                                                if (isDirty()) {
													updateMarker(monitor, attrs);
												}
                                            }
                                        }, monitor);
                                monitor.done();
                            } catch (CoreException e) {
                                coreExceptions[0] = e;
                            }
                        }

                    });
        } catch (InvocationTargetException e) {
            IDEWorkbenchPlugin.log(e.getMessage(), StatusUtil.newStatus(
                    IStatus.ERROR, e.getMessage(), e));
            return;
        }

        catch (InterruptedException e) {
        }

        if (coreExceptions[0] != null) {
			ErrorDialog
                    .openError(
                            getShell(),
                            MarkerMessages.Error, null, coreExceptions[0].getStatus());
		} 

    }

    /**
     * Creates or updates the marker.  Must be called within a workspace runnable.
     * @param monitor the monitor we report to. 
     * @param attrs the attributes from the dialog
     */
    private void updateMarker(IProgressMonitor monitor, Map attrs)
            throws CoreException {
        // Set the marker attributes from the current dialog field values.
        // Do not use setAttributes(Map) as that overwrites any attributes
        // not covered by the dialog.

        int increment = 50 / attrs.size();

        for (Iterator i = attrs.keySet().iterator(); i.hasNext();) {
            monitor.worked(increment);
            String key = (String) i.next();
            Object val = attrs.get(key);
            marker.setAttribute(key, val);
        }
    }

    /**
     * Returns the marker attributes to save back to the marker, 
     * based on the current dialog fields.
     */
    protected Map getMarkerAttributes() {
        Map attrs;
        if (initialAttributes == null) {
            attrs = initialAttributes;
        } else {
            attrs = new HashMap();
        }
        attrs.put(IMarker.MESSAGE, descriptionText.getText());
        return attrs;
    }

    /**
     * Create the marker and report progress
     * to the monitor.
     * @param monitor
     * @throws CoreException
     */
    private void createMarker(IProgressMonitor monitor) throws CoreException {
        if (resource == null) {
			return;
		}

        monitor.worked(10);
        marker = resource.createMarker(type);
        monitor.worked(40);
    }

    /**
     * Updates widget enablement for the dialog. Should be overridden by subclasses. 
     */
    protected void updateEnablement() {
        descriptionText.setEditable(isEditable());
    }

    /**
     * @return
     * <ul>
     * <li><code>true</code> if the marker is editable or the dialog is creating a new marker.</li>
     * <li><code>false</code> if the marker is not editable.</li>
     * </ul>
     */
    protected boolean isEditable() {
        if (marker == null) {
            return true;
        }
        return Util.isEditable(marker);
    }

    /**
     * Sets the marker type when creating a new marker.
     * 
     * @param type the marker type
     */
    void setType(String type) {
        this.type = type;
    }
    
	/* (non-Javadoc)
     * @see org.eclipse.jface.window.Dialog#getDialogBoundsSettings()
     * 
     * @since 3.2
     */
	protected IDialogSettings getDialogBoundsSettings() {
        IDialogSettings settings = IDEWorkbenchPlugin.getDefault().getDialogSettings();
        IDialogSettings section = settings.getSection(DIALOG_SETTINGS_SECTION);
        if (section == null) {
            section = settings.addNewSection(DIALOG_SETTINGS_SECTION);
        } 
        return section;
	}
}
