/*******************************************************************************
 * Copyright (c) 2000, 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.jdt.internal.junit.ui;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.CompareViewerPane;
import org.eclipse.compare.IEncodedStreamContentAccessor;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.contentmergeviewer.TextMergeViewer;
import org.eclipse.compare.structuremergeviewer.DiffNode;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.DialogSettings;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITypedRegion;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.TextPresentation;
import org.eclipse.jface.text.TextViewer;
import org.eclipse.jface.text.presentation.IPresentationDamager;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.presentation.IPresentationRepairer;
import org.eclipse.jface.text.presentation.PresentationReconciler;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
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.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class CompareResultDialog extends Dialog {
    private static class CompareResultMergeViewer extends TextMergeViewer {
         private CompareResultMergeViewer(Composite parent, int style, CompareConfiguration configuration) {
             super(parent, style, configuration);
         }
        protected void configureTextViewer(TextViewer textViewer) {
            if (textViewer instanceof SourceViewer) {
                ((SourceViewer)textViewer).configure(new CompareResultViewerConfiguration());   
            }
        }
    }
    
    public static class CompareResultViewerConfiguration extends SourceViewerConfiguration {
        public static class SimpleDamagerRepairer implements IPresentationDamager, IPresentationRepairer {
            private IDocument fDocument;

            public void setDocument(IDocument document) {
                fDocument= document;
            }

            public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent event, boolean changed) {
                return new Region(0, fDocument.getLength());
            }

            public void createPresentation(TextPresentation presentation, ITypedRegion damage) {
                int suffix= CompareResultDialog.fgThis.fSuffix;
                int prefix= CompareResultDialog.fgThis.fPrefix;
                TextAttribute attr= new TextAttribute(Display.getDefault().getSystemColor(SWT.COLOR_RED), null, SWT.BOLD);
                presentation.addStyleRange(new StyleRange(prefix, fDocument.getLength()-suffix-prefix, attr.getForeground(), attr.getBackground(), attr.getStyle()));
            }
        }
        
        public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
            PresentationReconciler reconciler= new PresentationReconciler();
            SimpleDamagerRepairer dr= new SimpleDamagerRepairer();
            reconciler.setDamager(dr, IDocument.DEFAULT_CONTENT_TYPE);
            reconciler.setRepairer(dr, IDocument.DEFAULT_CONTENT_TYPE);
            return reconciler;
        }
    }
        
	private static class CompareElement implements ITypedElement, IEncodedStreamContentAccessor {
	    private String fContent;
	    
	    public CompareElement(String content) {
	        fContent= content;
	    }
	    public String getName() {
	        return "<no name>"; //$NON-NLS-1$
	    }
	    public Image getImage() {
	        return null;
	    }
	    public String getType() {
	        return "txt"; //$NON-NLS-1$
	    }
	    public InputStream getContents() {
		    try {
		        return new ByteArrayInputStream(fContent.getBytes("UTF-8")); //$NON-NLS-1$
		    } catch (UnsupportedEncodingException e) {
		        return new ByteArrayInputStream(fContent.getBytes());
		    }
	    }
        public String getCharset() throws CoreException {
            return "UTF-8"; //$NON-NLS-1$
        }
	}

    private TextMergeViewer fViewer;
    private String fExpected;
    private String fActual;
    private String fTestName;
    
    /* workaround - to make prefix and suffix accessible to the CompareResultViewerConfiguration */
    private static CompareResultDialog fgThis;
    
    private int fPrefix;
    private int fSuffix;
    
    // dialog store id constants
    private final static String DIALOG_BOUNDS_KEY= "CompareResultDialogBounds"; //$NON-NLS-1$
    private static final String X= "x"; //$NON-NLS-1$
    private static final String Y= "y"; //$NON-NLS-1$
    private static final String WIDTH= "width"; //$NON-NLS-1$
    private static final String HEIGHT= "height"; //$NON-NLS-1$
    private IDialogSettings fSettings;
	protected Rectangle fNewBounds;
	
	public CompareResultDialog(Shell parentShell, TestRunInfo failure) {
		super(parentShell);
		fgThis= this;
		setShellStyle(getShellStyle() | SWT.RESIZE | SWT.MAX);
        fTestName= failure.getTestName();
        fExpected= failure.getExpected();
        fActual= failure.getActual();
        computePrefixSuffix();
        fSettings= JUnitPlugin.getDefault().getDialogSettings();
	}
	
	protected Point getInitialSize() {
		int width= 0;
		int height= 0;
		
		final Shell s= getShell();
		if (s != null) {
			s.addControlListener(
					new ControlListener() {
						public void controlMoved(ControlEvent arg) {
							fNewBounds= s.getBounds();
						}
						public void controlResized(ControlEvent arg) {
							fNewBounds= s.getBounds();
						}
					}
			);
		}
		IDialogSettings bounds= fSettings.getSection(DIALOG_BOUNDS_KEY); 
		if (bounds == null) {
			return super.getInitialSize();
		}
		else {
			try {
				width= bounds.getInt(WIDTH);
			} catch (NumberFormatException e) {
				width= 400;
			}
			try {
				height= bounds.getInt(HEIGHT);
			} catch (NumberFormatException e) {
				height= 300;
			}
		}	
		return new Point(width, height);	
	}
	
	protected Point getInitialLocation(Point initialSize) {
		Point loc= super.getInitialLocation(initialSize);
		
		IDialogSettings bounds= fSettings.getSection(DIALOG_BOUNDS_KEY);
		if (bounds != null) {
			try {
				loc.x= bounds.getInt(X);
			} catch (NumberFormatException e) {
			}
			try {
				loc.y= bounds.getInt(Y);
			} catch (NumberFormatException e) {
			}
		}
		return loc;
	}
	
	public boolean close() {
		boolean closed= super.close();
		if (closed && fNewBounds != null)
			saveBounds(fNewBounds);
		return closed;
	}

	private void saveBounds(Rectangle bounds) {
		IDialogSettings dialogBounds= fSettings.getSection(DIALOG_BOUNDS_KEY);
		if (dialogBounds == null) {
			dialogBounds= new DialogSettings(DIALOG_BOUNDS_KEY);
			fSettings.addSection(dialogBounds);
		}
		dialogBounds.put(X, bounds.x);
		dialogBounds.put(Y, bounds.y);
		dialogBounds.put(WIDTH, bounds.width);
		dialogBounds.put(HEIGHT, bounds.height);
	}
	
	private void computePrefixSuffix() {
		int end= Math.min(fExpected.length(), fActual.length());
		int i= 0;
		for(; i < end; i++) 
			if (fExpected.charAt(i) != fActual.charAt(i))
				break;
		fPrefix= i;
		
		int j= fExpected.length()-1;
		int k= fActual.length()-1;
		int l= 0;
		for (; k >= fPrefix && j >= fPrefix; k--,j--) {
			if (fExpected.charAt(j) != fActual.charAt(k))
				break;
			l++;
		}
		fSuffix= l;
	}

    protected void configureShell(Shell newShell) {
		super.configureShell(newShell);
		newShell.setText(JUnitMessages.CompareResultDialog_title); 
	}

	protected void createButtonsForButtonBar(Composite parent) {
		createButton(parent, IDialogConstants.OK_ID, JUnitMessages.CompareResultDialog_labelOK, true); 
	}

	protected Control createDialogArea(Composite parent) {
		Composite composite = (Composite)super.createDialogArea(parent);
		GridLayout layout= new GridLayout();
		layout.numColumns= 1;
		composite.setLayout(layout);
		
		CompareViewerPane pane = new CompareViewerPane(composite, SWT.BORDER | SWT.FLAT);
		pane.setText(fTestName);
		GridData data= new GridData(GridData.FILL_HORIZONTAL | GridData.FILL_VERTICAL);
		data.widthHint= convertWidthInCharsToPixels(120);
		data.heightHint= convertHeightInCharsToPixels(13);
		pane.setLayoutData(data);
		
		Control previewer= createPreviewer(pane);
		pane.setContent(previewer);
		GridData gd= new GridData(GridData.FILL_BOTH);
		previewer.setLayoutData(gd);
		applyDialogFont(parent);
		return composite;
	}
	
	private Control createPreviewer(Composite parent) {
	    final CompareConfiguration compareConfiguration= new CompareConfiguration();
	    compareConfiguration.setLeftLabel(JUnitMessages.CompareResultDialog_expectedLabel); 
	    compareConfiguration.setLeftEditable(false);
	    compareConfiguration.setRightLabel(JUnitMessages.CompareResultDialog_actualLabel);	 
	    compareConfiguration.setRightEditable(false);
	    compareConfiguration.setProperty(CompareConfiguration.IGNORE_WHITESPACE, Boolean.FALSE);

	    fViewer= new CompareResultMergeViewer(parent, SWT.NONE, compareConfiguration);
	    fViewer.setInput(new DiffNode( 
        new CompareElement(fExpected), 
        new CompareElement(fActual)));

	    Control control= fViewer.getControl();
	    control.addDisposeListener(new DisposeListener() {
	        public void widgetDisposed(DisposeEvent e) {
	            if (compareConfiguration != null)
	                compareConfiguration.dispose();
	        }
	    });
	    return  control;
	}	
}
