package hiro.yoshioka.sdh;

import hiro.yoshioka.sdh.pair.DifferenceStringData;
import hiro.yoshioka.util.ColorNameEnum;
import hiro.yoshioka.util.ColorUtil;
import hiro.yoshioka.util.StringUtil;

import java.util.ArrayList;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.viewers.OwnerDrawLabelProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

public class RDHOwnerTableLabelProvider extends OwnerDrawLabelProvider {
	protected transient Log log = LogFactory.getLog(this.getClass());
	CDHTableViewer v;
	boolean supportDiff;
	int[] percentIdx;
	public static final int UNLIMITED = 0;
	public int maxMultiLine = 1;

	public RDHOwnerTableLabelProvider(CDHTableViewer view,
			boolean supportChart, int maxMultiLine) {
		this.v = view;
		this.maxMultiLine = maxMultiLine;
		this.supportDiff = v.supportDiff();

		TableColumn[] keys = v.getTable().getColumns();
		ArrayList<Integer> list = new ArrayList<Integer>();
		for (int i = 0; supportChart && i < keys.length; i++) {
			if (keys[i].getText().indexOf('%') >= 0) {
				list.add(i);
			}
		}
		percentIdx = new int[list.size()];
		for (int i = 0; i < percentIdx.length; i++) {
			percentIdx[i] = list.get(i);
		}
	}

	@Override
	protected void measure(Event event, Object element) {
		StringRecordData[] items = (StringRecordData[]) element;
		String target = items[event.index].getString();
		try {
			if (maxMultiLine > UNLIMITED) {
				String[] lines = target.split("\\\n", maxMultiLine);
				if (lines.length > 1) {
					StringBuilder buf = new StringBuilder(lines[0]);
					for (int i = 1; i < lines.length; i++) {
						lines[i] = lines[i].replaceAll("[\\n\\r]", "");
						buf.append("\n").append(lines[i]);
					}
					target = buf.toString();
				} else {
					target = target.replaceAll("[\\n\\r]", "");
				}
			}
		} catch (RuntimeException e) {
			log.fatal(StringUtil.EMPTY_STRING, e);
		}
		Point size = event.gc.textExtent(target);

		if (event.width < size.x) {
			event.width = size.x + 3;
		}
		if (event.width == 0) {
			event.width = 20;
		}
		if (maxMultiLine == UNLIMITED) {
			return;
		}
		int lines = size.x / event.width + 1;

		if (maxMultiLine > UNLIMITED && lines > maxMultiLine) {
			lines = maxMultiLine;
		}
		event.height = size.y * lines;
	}

	@Override
	protected void paint(Event event, Object element) {
		StringRecordData[] items = (StringRecordData[]) element;
		boolean doit = true;

		TableItem item = (TableItem) event.item;
		int idx = v.getTable().indexOf(item);
		if (idx % 2 == 1 && idx != v.getTable().getSelectionIndex()) {
			event.gc.setBackground(ColorUtil.getColor(ColorNameEnum.SIMA));
			event.gc.fillRectangle(event.x, event.y,
					item.getBounds(event.index).width, event.height);
		}

		for (int i = 0; i < percentIdx.length; i++) {
			if (event.index == percentIdx[i]) {
				try {
					String str = items[event.index].getString();
					if (str.length() == 0) {
						continue;
					}
					double percent = Double.parseDouble(str);
					Color foreground = event.gc.getForeground();

					if (percent < 33) {
						event.gc.setForeground(v.getTable().getDisplay()
								.getSystemColor(SWT.COLOR_GREEN));
					} else if (percent < 66) {
						event.gc.setForeground(v.getTable().getDisplay()
								.getSystemColor(SWT.COLOR_MAGENTA));
					} else {
						event.gc.setForeground(v.getTable().getDisplay()
								.getSystemColor(SWT.COLOR_RED));
					}
					event.gc.setBackground(ColorUtil
							.getColor(ColorNameEnum.SIMA));

					int cwidth = v.getTable().getColumn(event.index).getWidth();

					int width = (int) (cwidth * percent / 100);

					event.gc.fillGradientRectangle(event.x, event.y, width,
							event.height, true);
					Rectangle rect2 = new Rectangle(event.x, event.y,
							width - 1, event.height - 1);
					event.gc.drawRectangle(rect2);

					event.gc.setForeground(v.getTable().getDisplay()
							.getSystemColor(SWT.COLOR_LIST_FOREGROUND));
					String text = percent + "%";
					Point size = event.gc.textExtent(text);
					int offset = Math.max(0, (event.height - size.y) / 2);
					event.gc.drawText(text, event.x + 2, event.y + offset, true);

					event.gc.setForeground(foreground);
					doit = false;
				} catch (NumberFormatException e) {
					log.fatal(StringUtil.EMPTY_STRING, e);
				} catch (ClassCastException e) {
					log.fatal(StringUtil.EMPTY_STRING, e);
				}
			}
		}
		// fLogger.info("doit:" + doit);
		if (doit) {
			if (supportDiff
					&& items[event.index].getPair() instanceof DifferenceStringData) {
				DifferenceStringData d = (DifferenceStringData) items[event.index]
						.getPair();
				switch (d.fDifferenceKind) {
				case ADDITION:
					if (event.index == 0) {
						// return items[event.index].getString() + "[+]";
					}
					event.gc.setBackground(ColorUtil
							.getColor(ColorNameEnum.ADD));
					event.gc.fillRectangle(event.x, event.y,
							item.getBounds(event.index).width, event.height);
					break;
				case CHANGE:
					event.gc.setBackground(ColorUtil
							.getColor(ColorNameEnum.CHANGE));
					event.gc.fillRectangle(event.x, event.y,
							item.getBounds(event.index).width, event.height);
					break;
				}
			}
			String target = items[event.index].getString();
			if (maxMultiLine > UNLIMITED) {
				String[] lines = target.split("\\\n", maxMultiLine);
				if (lines.length > 1) {
					StringBuilder buf = new StringBuilder(lines[0]);
					for (int i = 1; i < lines.length; i++) {
						lines[i] = lines[i].replaceAll("[\\n\\r]", "");
						buf.append("\n").append(lines[i]);
					}
					target = buf.toString();
				} else {
					target = target.replaceAll("[\\n\\r]", "");
				}
			}
			// fLogger.info("target[" + target + "]");

			Point size = event.gc.textExtent(target);
			int offset = Math.max(0, (event.height - size.y) / 2);
			if (v.isHyperLinkColumn(event.index)
					&& idx != v.getTable().getSelectionIndex()
					&& !StringUtil.isEmpty(target)) {
				event.gc.setForeground(v.getTable().getDisplay()
						.getSystemColor(SWT.COLOR_BLUE));
				target = DefaultHyperLinkAction.getDisplayString(target);
				event.gc.drawText(target, event.x + 2, event.y + offset, true);

			} else {
				event.gc.drawText(target, event.x + 2, event.y + offset, true);
			}
		}

	}
}