package org.eclipse.ui.internal.browser;

import java.io.PrintWriter;
import java.io.StringWriter;

import org.eclipse.jface.resource.JFaceResources;
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.Color;
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.Label;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Text;

public class BrowserText {
    private String url;

    private FallbackScrolledComposite scomp;

    private Label title;

    private Label exTitle;

    private Label text;

    private Label sep;

    protected Link link;

    private BrowserViewer viewer;

    private Button button;

    private Text exception;

    private boolean expanded;

    private Throwable ex;

    class ReflowScrolledComposite extends FallbackScrolledComposite {
        public ReflowScrolledComposite(Composite parent, int style) {
            super(parent, style);
        }

        public void reflow(boolean flushCache) {
            updateWidth(this);
            super.reflow(flushCache);
        }
    }

    public BrowserText(Composite parent, BrowserViewer viewer, Throwable ex) {
        this.viewer = viewer;
        this.ex = ex;
        Color bg = parent.getDisplay()
                .getSystemColor(SWT.COLOR_LIST_BACKGROUND);
        scomp = new ReflowScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
        Composite client = new Composite(scomp, SWT.NULL);
        fillContent(client, bg);
        scomp.setContent(client);        
        scomp.setBackground(bg);
    }

    private void fillContent(Composite parent, Color bg) {
        GridLayout layout = new GridLayout();
        layout.verticalSpacing = 10;
        parent.setLayout(layout);
        title = new Label(parent, SWT.WRAP);
        title.setText(Messages.BrowserText_title);
        title.setFont(JFaceResources.getHeaderFont());
        title.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        title.setBackground(bg);

        link = new Link(parent, SWT.WRAP);
        link.setText(Messages.BrowserText_link);
        link.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        link.setToolTipText(Messages.BrowserText_tooltip);
        link.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                BusyIndicator.showWhile(link.getDisplay(), new Runnable() {
                    public void run() {
                        doOpenExternal();
                    }
                });
            }
        });
        link.setBackground(bg);
        sep = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL);
        sep.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        exTitle = new Label(parent, SWT.NULL);
        exTitle.setBackground(bg);
        exTitle.setFont(JFaceResources.getBannerFont());
        exTitle.setText(Messages.BrowserText_dtitle);
        exTitle.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        text = new Label(parent, SWT.WRAP);
        text.setText(Messages.BrowserText_text);
        text.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
        text.setBackground(bg);
        button = new Button(parent, SWT.PUSH);
        updateButtonText();
        button.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                toggleException();
            }
        });
        exception = new Text(parent, SWT.MULTI);
        loadExceptionText();
        GridData gd = new GridData(GridData.FILL_BOTH);
        gd.exclude = true;
        exception.setLayoutData(gd);
    }

    private void loadExceptionText() {
        StringWriter swriter = new StringWriter();
        PrintWriter writer = new PrintWriter(swriter);
        writer.println(ex.getMessage());
        ex.printStackTrace(writer);
        writer.close();
        exception.setText(swriter.toString());
    }

    protected void toggleException() {
        expanded = !expanded;
        updateButtonText();
        GridData gd = (GridData) exception.getLayoutData();
        gd.exclude = !expanded;
        exception.setVisible(expanded);
        refresh();
    }

    private void updateButtonText() {
        if (expanded)
            button.setText(Messages.BrowserText_button_collapse);
        else
            button.setText(Messages.BrowserText_button_expand);
    }

    protected void updateWidth(Composite parent) {
        Rectangle area = parent.getClientArea();
        updateWidth(title, area.width);
        updateWidth(text, area.width);
        updateWidth(sep, area.width);
        updateWidth(link, area.width);
        updateWidth(exTitle, area.width);
        updateWidth(exception, area.width);
    }

    private void updateWidth(Control c, int width) {
        GridData gd = (GridData) c.getLayoutData();
        if (gd != null)
            gd.widthHint = width - 10;
    }

    protected void doOpenExternal() {
        IBrowserViewerContainer container = viewer.getContainer();
        if (container != null)
            container.openInExternalBrowser(url);
    }

    public Control getControl() {
        return scomp;
    }

    public boolean setUrl(String url) {
        this.url = url;
        return true;
    }

    public void setFocus() {
        link.setFocus();
    }

    public String getUrl() {
        return url;
    }

    public void refresh() {
        scomp.reflow(true);
    }
}