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

import java.io.*;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Vector;

import org.eclipse.swt.graphics.*;
import org.eclipse.swt.graphics.GC;
import org.eclipse.ui.forms.HyperlinkSettings;

/**
 * @version 1.0
 * @author
 */
public class Paragraph {
	public static final String HTTP = "http://"; //$NON-NLS-1$

	private Vector segments;

	private boolean addVerticalSpace = true;

	public Paragraph(boolean addVerticalSpace) {
		this.addVerticalSpace = addVerticalSpace;
	}

	public int getIndent() {
		return 0;
	}

	public boolean getAddVerticalSpace() {
		return addVerticalSpace;
	}

	/*
	 * @see IParagraph#getSegments()
	 */
	public ParagraphSegment[] getSegments() {
		if (segments == null)
			return new ParagraphSegment[0];
		return (ParagraphSegment[]) segments
				.toArray(new ParagraphSegment[segments.size()]);
	}

	public void addSegment(ParagraphSegment segment) {
		if (segments == null)
			segments = new Vector();
		segments.add(segment);
	}

	public void parseRegularText(String text, boolean expandURLs, boolean wrapAllowed,
			HyperlinkSettings settings, String fontId) {
		parseRegularText(text, expandURLs, wrapAllowed, settings, fontId, null);
	}

	public void parseRegularText(String text, boolean expandURLs, boolean wrapAllowed,
			HyperlinkSettings settings, String fontId, String colorId) {
		if (text.length() == 0)
			return;
		if (expandURLs) {
			int loc = text.indexOf(HTTP);

			if (loc == -1)
				addSegment(new TextSegment(text, fontId, colorId, wrapAllowed));
			else {
				int textLoc = 0;
				while (loc != -1) {
					addSegment(new TextSegment(text.substring(textLoc, loc),
							fontId, colorId, wrapAllowed));
					boolean added = false;
					for (textLoc = loc; textLoc < text.length(); textLoc++) {
						char c = text.charAt(textLoc);
						if (Character.isSpaceChar(c)) {
							addHyperlinkSegment(text.substring(loc, textLoc),
									settings, fontId);
							added = true;
							break;
						}
					}
					if (!added) {
						// there was no space - just end of text
						addHyperlinkSegment(text.substring(loc), settings,
								fontId);
						break;
					}
					loc = text.indexOf(HTTP, textLoc);
				}
				if (textLoc < text.length()) {
					addSegment(new TextSegment(text.substring(textLoc), fontId,
							colorId, wrapAllowed));
				}
			}
		} else {
			addSegment(new TextSegment(text, fontId, colorId, wrapAllowed));
		}
	}

	private void addHyperlinkSegment(String text, HyperlinkSettings settings,
			String fontId) {
		TextHyperlinkSegment hs = new TextHyperlinkSegment(text, settings,
				fontId);
		hs.setWordWrapAllowed(false);
		hs.setHref(text);
		addSegment(hs);
	}

	protected void computeRowHeights(GC gc, int width, Locator loc,
			int lineHeight, Hashtable resourceTable) {
		ParagraphSegment[] segments = getSegments();
		// compute heights
		Locator hloc = loc.create();
		ArrayList heights = new ArrayList();
		hloc.heights = heights;
		hloc.rowCounter = 0;
		int innerWidth = width - loc.marginWidth*2;
		for (int j = 0; j < segments.length; j++) {
			ParagraphSegment segment = segments[j];
			segment.advanceLocator(gc, innerWidth, hloc, resourceTable, true);
		}
		hloc.collectHeights();
		loc.heights = heights;
		loc.rowCounter = 0;
	}

	public void layout(GC gc, int width, Locator loc, int lineHeight,
			Hashtable resourceTable, IHyperlinkSegment selectedLink) {
		ParagraphSegment[] segments = getSegments();
		//int height;
		if (segments.length > 0) {
			/*
			if (segments[0] instanceof TextSegment
					&& ((TextSegment) segments[0]).isSelectable())
				loc.x += 1;
			*/
			// compute heights
			if (loc.heights == null)
				computeRowHeights(gc, width, loc, lineHeight, resourceTable);
			for (int j = 0; j < segments.length; j++) {
				ParagraphSegment segment = segments[j];
				boolean doSelect = false;
				if (selectedLink != null && segment.equals(selectedLink))
					doSelect = true;
				segment.layout(gc, width, loc, resourceTable, doSelect);
			}
			loc.heights = null;
			loc.y += loc.rowHeight;
		} else {
			loc.y += lineHeight;
		}
	}

	public void paint(GC gc, Rectangle repaintRegion,
			Hashtable resourceTable, IHyperlinkSegment selectedLink,
			SelectionData selData) {
		ParagraphSegment[] segments = getSegments();

		for (int i = 0; i < segments.length; i++) {
			ParagraphSegment segment = segments[i];
			if (!segment.intersects(repaintRegion))
				continue;
			boolean doSelect = false;
			if (selectedLink != null && segment.equals(selectedLink))
				doSelect = true;
			segment.paint(gc, false, resourceTable, doSelect, selData, repaintRegion);
		}
	}
	
	public void computeSelection(GC gc,	Hashtable resourceTable, IHyperlinkSegment selectedLink,
			SelectionData selData) {
		ParagraphSegment[] segments = getSegments();

		for (int i = 0; i < segments.length; i++) {
			ParagraphSegment segment = segments[i];
			//boolean doSelect = false;
			//if (selectedLink != null && segment.equals(selectedLink))
				//doSelect = true;
			segment.computeSelection(gc, resourceTable, selData);
		}
	}

	public String getAccessibleText() {
		ParagraphSegment[] segments = getSegments();
		StringWriter swriter = new StringWriter();
		PrintWriter writer = new PrintWriter(swriter);
		for (int i = 0; i < segments.length; i++) {
			ParagraphSegment segment = segments[i];
			if (segment instanceof TextSegment) {
				String text = ((TextSegment) segment).getText();
				writer.print(text);
			}
		}
		writer.println();
		swriter.flush();
		return swriter.toString();
	}

	public ParagraphSegment findSegmentAt(int x, int y) {
		if (segments != null) {
			for (int i = 0; i < segments.size(); i++) {
				ParagraphSegment segment = (ParagraphSegment) segments.get(i);
				if (segment.contains(x, y))
					return segment;
			}
		}
		return null;
	}
	public void clearCache(String fontId) {
		if (segments != null) {
			for (int i = 0; i < segments.size(); i++) {
				ParagraphSegment segment = (ParagraphSegment) segments.get(i);
				segment.clearCache(fontId);
			}
		}
	}
}
