/*******************************************************************************
 * 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.engine;

import org.eclipse.swt.graphics.*;
import org.eclipse.jface.resource.JFaceResources;
import java.util.Hashtable;
import org.eclipse.swt.SWT;
import java.text.BreakIterator;
import java.util.Vector;

/**
 * @version 	1.0
 * @author
 */
public class TextSegment extends ParagraphSegment implements ITextSegment {
	private Color color;
	private String fontId;
	private String text;
	protected boolean underline;
	private boolean wrapAllowed = true;
	protected Vector areaRectangles = new Vector();
	
	class AreaRectangle {
		Rectangle rect;
		int from, to;
		public AreaRectangle(Rectangle rect, int from, int to) {
			this.rect = rect;
			this.from = from;
			this.to = to;
		}
		public boolean contains(int x, int y) {
			return rect.contains(x, y);
		}
		public String getText() {
			if (from==0 && to== -1)
				return TextSegment.this.getText();
			if (from >0 && to == -1)
				return TextSegment.this.getText().substring(from);
			return TextSegment.this.getText().substring(from, to);
		}
	}
	
	public TextSegment(String text, String fontId) {
		this.text = cleanup(text);
		this.fontId = fontId;
	}

	private String cleanup(String text) {
		StringBuffer buf = new StringBuffer();
		for (int i = 0; i < text.length(); i++) {
			char c = text.charAt(i);
			if (c == '\n' || c == '\r' || c=='\f') {
				if (i > 0)
					buf.append(' ');
			} else
				buf.append(c);
		}
		return buf.toString();
	}

	public void setWordWrapAllowed(boolean value) {
		wrapAllowed = value;
	}

	public boolean isWordWrapAllowed() {
		return wrapAllowed;
	}
	
	public boolean isSelectable() {
		return false;
	}

	public Color getColor() {
		return color;
	}

	public Font getFont() {
		if (fontId == null)
			return JFaceResources.getDefaultFont();
		else
			return JFaceResources.getFontRegistry().get(fontId);
	}

	public String getText() {
		return text;
	}

	void setText(String text) {
		this.text = cleanup(text);
	}

	void setColor(Color color) {
		this.color = color;
	}

	void setFontId(String fontId) {
		this.fontId = fontId;
	}

	public boolean contains(int x, int y) {
		for (int i = 0; i < areaRectangles.size(); i++) {
			AreaRectangle ar = (AreaRectangle) areaRectangles.get(i);
			if (ar.contains(x, y))
				return true;
		}
		return false;
	}
	
	public Rectangle getBounds() {
		int x=0, y=0;
		int width = 0, height = 0;
		
		for (int i=0; i<areaRectangles.size(); i++) {
			AreaRectangle ar = (AreaRectangle)areaRectangles.get(i);
			if (i==0) y = ar.rect.y;
			x = Math.min(ar.rect.x, x);
			width = Math.max(ar.rect.width, width);
			height += ar.rect.height;
		}
		return new Rectangle(x, y, width, height);
	}

	public void advanceLocator(
		GC gc,
		int wHint,
		Locator locator,
		Hashtable objectTable) {
		Font oldFont = null;
		if (fontId != null) {
			oldFont = gc.getFont();
			gc.setFont(getFont());
		}
		FontMetrics fm = gc.getFontMetrics();
		int lineHeight = fm.getHeight();

		if (wHint == SWT.DEFAULT || !wrapAllowed) {
			Point extent = gc.textExtent(text);

			if (locator.x + extent.x > wHint) {
				// new line
				locator.x = isSelectable()?locator.indent+1:locator.indent;
				locator.y += locator.rowHeight;
				locator.rowHeight = 0;
			}
			int width = extent.x;
			if (isSelectable()) width+=2;
			locator.x += width;
			locator.width = width;
			locator.height = extent.y;
			locator.rowHeight = Math.max(locator.rowHeight, extent.y);
			return;
		}

		BreakIterator wb = BreakIterator.getLineInstance();
		wb.setText(text);

		int saved = 0;
		int last = 0;

		int width = 0;

		Point lastExtent = null;

		for (int loc = wb.first(); loc != BreakIterator.DONE; loc = wb.next()) {
			String word = text.substring(saved, loc);
			Point extent = gc.textExtent(word);

			if (locator.x + extent.x > wHint) {
				// overflow
				String savedWord = text.substring(saved, last);
				if (lastExtent==null)
				   lastExtent = gc.textExtent(savedWord);
				int lineWidth = locator.x + lastExtent.x;
				if (isSelectable()) lineWidth+=2;

				saved = last;
				locator.rowHeight = Math.max(locator.rowHeight, lastExtent.y);
				locator.x = isSelectable()?locator.indent+1:locator.indent;
				locator.y += locator.rowHeight;
				locator.rowHeight = 0;
				width = Math.max(width, lineWidth);
			}
			last = loc;
			lastExtent = extent;
		}
		String lastString = text.substring(saved, last);
		Point extent = gc.textExtent(lastString);
		int lineWidth = extent.x;
		if (isSelectable()) lineWidth += 2;
		locator.x += lineWidth;
		locator.width = width;
		locator.height = lineHeight;
		locator.rowHeight = Math.max(locator.rowHeight, extent.y);
		if (oldFont != null) {
			gc.setFont(oldFont);
		}
	}
	
	public void paint(
		GC gc,
		int width,
		Locator locator,
		Hashtable objectTable,
		boolean selected) {
		Font oldFont = null;
		Color oldColor = null;

		areaRectangles.clear();

		if (fontId != null) {
			oldFont = gc.getFont();
			gc.setFont(getFont());
		}
		if (color != null) {
			oldColor = gc.getForeground();
			gc.setForeground(color);
		}
		FontMetrics fm = gc.getFontMetrics();
		int lineHeight = fm.getHeight();
		int descent = fm.getDescent();

		if (!wrapAllowed) {
			Point extent = gc.textExtent(text);
			int ewidth = extent.x;
			if (isSelectable()) ewidth += 2;

			if (locator.x + ewidth > width) {
				// new line
				locator.resetCaret();
				if (isSelectable()) locator.x += 1;
				locator.y += locator.rowHeight;
				locator.rowHeight = 0;
			}
			gc.drawString(text, locator.x, locator.y);
			if (underline) {
				int lineY = locator.y + lineHeight - descent + 1;
				gc.drawLine(locator.x, lineY, locator.x + extent.x, lineY);
			}
			Rectangle br =
				new Rectangle(locator.x - 1, locator.y, extent.x + 2, lineHeight - descent + 3);
			areaRectangles.add(new AreaRectangle(br, 0, -1));
			if (selected) {
				if (color != null)
					gc.setForeground(oldColor);
				gc.drawFocus(br.x, br.y, br.width, br.height);
			}

			locator.x += ewidth;
			locator.width = ewidth;
			locator.height = lineHeight;
			locator.rowHeight = Math.max(locator.rowHeight, extent.y);
			if (oldFont != null) {
				gc.setFont(oldFont);
			}
			if (oldColor != null) {
				gc.setForeground(oldColor);
			}
			return;
		}

		BreakIterator wb = BreakIterator.getLineInstance();
		wb.setText(text);

		int saved = 0;
		int last = 0;

		for (int loc = wb.first(); loc != BreakIterator.DONE; loc = wb.next()) {
			if (loc == 0)
				continue;
			String word = text.substring(saved, loc);
			Point extent = gc.textExtent(word);
			int ewidth = extent.x;
			if (isSelectable()) ewidth += 2;

			if (locator.x + ewidth > width) {
				// overflow
				String prevLine = text.substring(saved, last);
				gc.drawString(prevLine, locator.x, locator.y, true);
				Point prevExtent = gc.textExtent(prevLine);
				int prevWidth = prevExtent.x;
				if (isSelectable()) prevWidth += 2;

				if (underline) {
					int lineY = locator.y + lineHeight - descent + 1;
					gc.drawLine(locator.x, lineY, locator.x + prevWidth, lineY);
				}
				Rectangle br =
					new Rectangle(
						locator.x - 1,
						locator.y,
						prevExtent.x + 2,
						lineHeight - descent + 3);
				if (selected) {
					if (color != null)
						gc.setForeground(oldColor);
					gc.drawFocus(br.x, br.y, br.width, br.height);
					if (color != null)
						gc.setForeground(color);
				}
				areaRectangles.add(new AreaRectangle(br, saved, last));
				
				locator.rowHeight = Math.max(locator.rowHeight, prevExtent.y);
				locator.resetCaret();
				if (isSelectable()) locator.x +=1;
				locator.y += locator.rowHeight;
				locator.rowHeight = 0;
				saved = last;
			}
			last = loc;
		}
		// paint the last line
		String lastLine = text.substring(saved, last);
		gc.drawString(lastLine, locator.x, locator.y, true);
		Point lastExtent = gc.textExtent(lastLine);
		int lastWidth = lastExtent.x;
		if (isSelectable()) lastWidth += 2;
		Rectangle br =
			new Rectangle(
				locator.x - 1,
				locator.y,
				lastExtent.x + 2,
				lineHeight - descent + 3);
		areaRectangles.add(new AreaRectangle(br, saved, last));
		if (underline) {
			int lineY = locator.y + lineHeight - descent + 1;
			gc.drawLine(locator.x, lineY, locator.x + lastExtent.x, lineY);
		}
		if (selected) {
			if (color != null)
				gc.setForeground(oldColor);
			gc.drawFocus(br.x, br.y, br.width, br.height);
		}
		locator.x += lastWidth;
		locator.rowHeight = Math.max(locator.rowHeight, lastExtent.y);
		if (oldFont != null) {
			gc.setFont(oldFont);
		}
		if (oldColor != null) {
			gc.setForeground(oldColor);
		}
	}
	
	public void paintFocus(GC gc, Color bg, Color fg, boolean selected) {
		if (areaRectangles==null) return;
		for (int i=0; i<areaRectangles.size(); i++) {
			AreaRectangle areaRectangle = (AreaRectangle)areaRectangles.get(i);
			Rectangle br = areaRectangle.rect;
			if (selected) {
				gc.setBackground(bg);
				gc.setForeground(fg);
				gc.drawFocus(br.x, br.y, br.width, br.height);
			}
			else {
				gc.setForeground(bg);
				gc.drawRectangle(br.x, br.y, br.width-1, br.height-1);
			}
		}
	}	
}
