/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.update.ui.forms.internal;

import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.jface.resource.*;
import org.eclipse.jface.util.PropertyChangeEvent;

/**
 * This form implementation assumes that it contains
 * form sections and that they fill up the screen.
 * Typically, the form client will use up the entire
 * parent area below the heading. Sections must
 * be able to return their preferred size in both
 * dimensions. If they contain wrappable text,
 * WebForm should be used instead.
 */

public class SectionForm extends AbstractSectionForm implements PaintListener {
	private Composite control;
	private int TITLE_HMARGIN = 10;
	private int TITLE_VMARGIN = 5;

	class FormLayout extends Layout {
		protected Point computeSize(
			Composite composite,
			int wHint,
			int hHint,
			boolean flushCache) {
			if (wHint != SWT.DEFAULT && hHint != SWT.DEFAULT)
				return new Point(wHint, hHint);
			Control client = composite.getChildren()[0];
			Point csize = client.computeSize(widthHint, heightHint, flushCache);
			if (headingVisible)
				csize.y += getTitleHeight();
			return csize;
		}
		protected void layout(Composite composite, boolean flushCache) {
			Rectangle clientArea = composite.getClientArea();
			Control client = composite.getChildren()[0];
			if (client != null && !client.isDisposed()) {
				int theight = headingVisible ? getTitleHeight() : 0;
				client.setBounds(
					clientArea.x,
					clientArea.y + theight,
					clientArea.width,
					clientArea.height - theight);
			}
		}
	}
	private int widthHint = SWT.DEFAULT;
	private int heightHint = SWT.DEFAULT;

	public SectionForm() {
	}

	public Control createControl(Composite parent) {
		Composite canvas = new Composite(parent, SWT.NONE);
		canvas.setBackground(factory.getBackgroundColor());
		canvas.setForeground(factory.getForegroundColor());
		canvas.addPaintListener(this);
		canvas.setLayout(new FormLayout());
		canvas.setMenu(parent.getMenu());
		Composite formParent = factory.createComposite(canvas);
		createFormClient(formParent);
		this.control = canvas;
		//canvas.setFocus();
		return canvas;
	}

	protected void createFormClient(Composite parent) {
		factory.createComposite(parent);
	}

	public Control getControl() {
		return control;
	}

	private int getTitleHeight() {
		int imageHeight = 0;
		if (headingImage != null
			&& SWT.getPlatform().equals("motif") == false) {
			imageHeight = headingImage.getBounds().height;
		}
		GC gc = new GC(control);
		gc.setFont(titleFont);
		FontMetrics fm = gc.getFontMetrics();
		int fontHeight = fm.getHeight();
		gc.dispose();

		int height = fontHeight + TITLE_VMARGIN + TITLE_VMARGIN;
		return Math.max(height, imageHeight);
	}

	private void paint(Control form, GC gc) {
		Rectangle bounds = form.getBounds();
		int height = getTitleHeight();
		if (headingImage != null) {
			Rectangle imageBounds = headingImage.getBounds();
			int x = bounds.width - imageBounds.width;
			int y = 0;
			//x = Math.max(x, 0);
			x = 0;
			if (headingBackground != null) {
				gc.setBackground(headingBackground);
				gc.fillRectangle(0, 0, bounds.width, height);
			}
			if (SWT.getPlatform().equals("motif") == false) {
				gc.drawImage(headingImage, x, y);
			}
			if (headingForeground != null)
				gc.setForeground(headingForeground);
			else
				gc.setForeground(factory.getForegroundColor());
			gc.setFont(titleFont);
			gc.drawText(getHeadingText(), TITLE_HMARGIN, TITLE_VMARGIN, true);
		} else {
			gc.setFont(titleFont);
			gc.setBackground(factory.getColor(FormWidgetFactory.DEFAULT_HEADER_COLOR));
			//gc.fillRectangle(TITLE_HMARGIN, TITLE_VMARGIN, bounds.width-TITLE_HMARGIN*2, height-TITLE_VMARGIN*2);
			gc.setForeground(factory.getForegroundColor());
			gc.drawText(getHeadingText(), TITLE_HMARGIN, TITLE_VMARGIN, true);
		}
	}

	public final void paintControl(PaintEvent event) {
		if (!headingVisible)
			return;
		GC gc = event.gc;
		Control form = (Control) event.widget;
		paint(form, gc);
	}

	public void setHeadingVisible(boolean newHeadingVisible) {
		super.setHeadingVisible(newHeadingVisible);
		if (control != null)
			control.layout(true);
	}
	public void setHeadingText(String headingText) {
		super.setHeadingText(headingText);
		if (control != null) {
			control.layout(true);
			control.redraw();
		}
	}

	public void propertyChange(PropertyChangeEvent event) {
		titleFont = JFaceResources.getHeaderFont();
		if (control != null) {
			control.layout(true);
			control.redraw();
		}
	}

}
