package org.eclipse.update.ui.forms.internal;
/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved.
 */

import org.eclipse.swt.layout.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import java.util.*;
import org.eclipse.ui.*;
import org.eclipse.jface.resource.*;
import org.eclipse.jface.util.*;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.custom.*;

/**
 * This form implementation assumes that it contains
 * children that do not have independent dimensions.
 * In other words, these widgets are not capable
 * of answering their preferred size. Instead,
 * desired width must be supplied to get the
 * preferred height. These forms are layed out
 * top to bottom, left to right and use
 * a layout algorithm very similar to
 * HTML tables. Scrolling is not optional
 * for this type of presentation - 
 * scroll bars will show up when needed.
 */

public class WebForm extends AbstractSectionForm {
	protected ScrolledComposite scrollComposite;
	private Composite control;
	private Composite client;
	private final static int HMARGIN = 5;
	private final static int VMARGIN = 5;
	private Image headingUnderlineImage;

	class WebFormLayout extends Layout {

		protected void layout(Composite parent, boolean changed) {
			Rectangle bounds = parent.getClientArea();
			int x = 0;
			int y = 0;
			if (isHeadingVisible()) {
				y = getHeadingHeight(parent);
			}
			Point csize;
			Layout layout = client.getLayout();
			if (layout != null && layout instanceof HTMLTableLayout) {
				HTMLTableLayout hlayout = (HTMLTableLayout) layout;
				csize = hlayout.computeSize(client, bounds.width, SWT.DEFAULT, true);
				if (csize.x < bounds.width)
					csize.x = bounds.width;
				Rectangle trim = control.computeTrim(0, 0, csize.x, csize.y);
				csize = new Point(trim.width, trim.height);
			} else {
				csize = client.computeSize(bounds.width, SWT.DEFAULT, changed);
			}
			client.setBounds(x, y, csize.x, csize.y);
		}

		protected Point computeSize(
			Composite parent,
			int wHint,
			int hHint,
			boolean changed) {
			int width = wHint;
			int height = 0;
			if (isHeadingVisible()) {
				height = getHeadingHeight(parent);
			}
			Point csize;
			Layout layout = client.getLayout();
			if (layout != null && layout instanceof HTMLTableLayout) {
				HTMLTableLayout hlayout = (HTMLTableLayout) layout;
				csize = hlayout.computeSize(client, width, SWT.DEFAULT, true);
				if (csize.x < width)
					csize.x = width;
				Rectangle trim = control.computeTrim(0, 0, csize.x, csize.y);
				csize = new Point(trim.width, trim.height);
			} else {
				csize = client.computeSize(width, SWT.DEFAULT, changed);
			}
			width = csize.x;
			height += csize.y;
			return new Point(width, height);
		}
	}

	public WebForm() {
	}

	public Control createControl(Composite parent) {
		scrollComposite = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
		scrollComposite.setBackground(factory.getBackgroundColor());
		scrollComposite.setMenu(parent.getMenu());
		final Composite form = factory.createComposite(scrollComposite);

		scrollComposite.setContent(form);
		scrollComposite.addListener(SWT.Resize, new Listener() {
			public void handleEvent(Event e) {
				updateSize();
			}
		});
		WebFormLayout layout = new WebFormLayout();
		form.setLayout(layout);
		form.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent e) {
				paint(e);
			}
		});
		this.control = form;
		client = factory.createComposite(form);
		createContents(client);
		initializeScrollBars(scrollComposite);
		//form.setFocus();
		return scrollComposite;
	}
	private void initializeScrollBars(ScrolledComposite scomp) {
		ScrollBar hbar = scomp.getHorizontalBar();
		if (hbar != null) {
			hbar.setIncrement(H_SCROLL_INCREMENT);
		}
		ScrollBar vbar = scomp.getVerticalBar();
		if (vbar != null) {
			vbar.setIncrement(V_SCROLL_INCREMENT);
		}
		updatePageIncrement(scomp);
	}

	private int getHeadingHeight(Composite parent) {
		int width = parent.getSize().x;
		int height = 0;
		int imageHeight = 0;
		if (getHeadingImage() != null) {
			Rectangle ibounds = getHeadingImage().getBounds();
			imageHeight = ibounds.height;
		}
		GC gc = new GC(parent);
		gc.setFont(titleFont);
		int textWidth = width - 2 * HMARGIN;
		height = FormLabel.computeWrapHeight(gc, getHeadingText(), textWidth);
		height += 2 * VMARGIN;
		height = Math.max(height, imageHeight);
		if (headingUnderlineImage != null) {
			Rectangle ibounds = headingUnderlineImage.getBounds();
			height += ibounds.height;
		}
		gc.dispose();
		return height;
	}

	protected void createContents(Composite parent) {
	}

	public Control getControl() {
		return control;
	}

	public void setHeadingVisible(boolean newHeadingVisible) {
		super.setHeadingVisible(newHeadingVisible);
		if (control != null)
			control.layout();
	}

	public Image getHeadingUnderlineImage() {
		return headingUnderlineImage;
	}

	public void setHeadingUnderlineImage(Image image) {
		this.headingUnderlineImage = image;
	}

	public void propertyChange(PropertyChangeEvent event) {
		titleFont = JFaceResources.getHeaderFont();
		if (control != null) {
			control.layout();
		}
	}
	
	protected void updateHyperlinkColors() {
		factory.updateHyperlinkColors();
		if (control != null) {
			control.redraw();
		}
	}

	public void updateSize() {
		Rectangle ssize = scrollComposite.getClientArea();
		int swidth = ssize.width;
		WebFormLayout layout = (WebFormLayout) control.getLayout();
		Point size = layout.computeSize(control, swidth, SWT.DEFAULT, true);
		if (size.x < swidth)
			size.x = swidth;
		Rectangle trim = control.computeTrim(0, 0, size.x, size.y);
		size = new Point(trim.width, trim.height);
		control.setSize(size);
		updatePageIncrement(scrollComposite);
	}

	private void paint(PaintEvent e) {
		if (isHeadingVisible() == false)
			return;
		GC gc = e.gc;
		if (headingImage != null) {
			gc.drawImage(headingImage, 0, 0);
		}
		Point size = control.getSize();
		if (getHeadingBackground() != null)
			gc.setBackground(getHeadingBackground());
		if (getHeadingForeground() != null)
			gc.setForeground(getHeadingForeground());
		gc.setFont(titleFont);
		FormLabel.paintWrapText(gc, size, getHeadingText(), HMARGIN, VMARGIN);
		if (headingUnderlineImage != null) {
			int y =
				getHeadingHeight((Composite) control)
					- headingUnderlineImage.getBounds().height;
			gc.drawImage(headingUnderlineImage, 0, y);
		}
	}
	public void setHeadingText(String headingText) {
		super.setHeadingText(headingText);
		if (control!=null)
			control.redraw();
	}

}