/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package uce.ui;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractCellEditor;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JToolTip;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.plaf.metal.MetalToolTipUI;
import javax.swing.table.TableCellEditor;

/**
 *
 * @author chepa
 */
public class SentenceCellEditor extends AbstractCellEditor implements TableCellEditor {

	// This is the component that will handle the editing of the cell value
	private JTextField txtSentence = new JTextField() {

		{
			setBorder(null);
		}

		@Override
		public JToolTip createToolTip() {
			MultiLineToolTip tip = new MultiLineToolTip();
			tip.setComponent(this);
			return tip;
		}
	};
	// The validator which coninuously parses the sentence text
	private CellValidator validator;

	{
		txtSentence.addKeyListener(new KeyAdapter() {

			@Override
			public void keyReleased(KeyEvent e) {
				String txt = txtSentence.getText();
				validator.ValidateText(txt);
			}
		});
	}
	// This method is called when a cell value is edited by the user.
	private int row;

	public Component getTableCellEditorComponent(JTable table, Object value,
			boolean isSelected, int rowIndex, int vColIndex) {
		// 'value' is value contained in the cell located at (rowIndex, vColIndex)

		// Configure the component with the specified value
		txtSentence.setText((String) value);
		row = rowIndex;
		// Return the configured component
		return txtSentence;
	}

	// This method is called when editing is completed.
	// It must return the new value to be stored in the cell.
	public Object getCellEditorValue() {
		return txtSentence.getText();
	}

	public void setValidator(CellValidator validator) {
		this.validator = validator;
	}

	public int getRow() {
		return row;
	}

	public CellValidator getValidator() {
		return validator;
	}

	public void setSuggestions(List<String> lstSuggestions) {
		txtSentence.setToolTipText(null);
		if (lstSuggestions == null) {
			return;
		}
		String strSugg = "";
		for (String s : lstSuggestions) {
			strSugg += s + System.getProperty("line.separator");
		}
		strSugg = strSugg.trim();
		if (strSugg.equals("")) {
			txtSentence.setToolTipText(null);
			return;
		}
		txtSentence.setToolTipText(strSugg);
		String curString = txtSentence.getText().substring(0, txtSentence.getCaretPosition());
		ToolTipManager.sharedInstance().mouseMoved(
				new MouseEvent(txtSentence, 0, 0, 0,
				txtSentence.getFontMetrics(txtSentence.getFont()).charsWidth(curString.toCharArray(), 0, curString.length()), txtSentence.getHeight() / 2, // X-Y of the mouse for the tool tip
				0, false));
	}

	class MultiLineToolTip extends JToolTip {

		public MultiLineToolTip() {
			setUI(new MultiLineToolTipUI());
		}
	}

	class MultiLineToolTipUI extends MetalToolTipUI {

		private String[] strs;

		@Override
		public void paint(Graphics g, JComponent c) {
			FontMetrics metrics = g.getFontMetrics();
			Dimension size = c.getSize();
			g.setColor(c.getBackground());
			g.fillRect(0, 0, size.width, size.height);
			g.setColor(c.getForeground());
			if (strs != null) {
				for (int i = 0; i < strs.length; i++) {
					g.drawString(strs[i], 3, (metrics.getHeight()) * (i + 1));
				}
			}
		}

		@Override
		public Dimension getPreferredSize(JComponent c) {
			FontMetrics metrics = c.getFontMetrics(c.getFont());
			String tipText = ((JToolTip) c).getTipText();
			if (tipText == null) {
				tipText = "";
			}
			BufferedReader br = new BufferedReader(new StringReader(tipText));
			String line;
			int iMaxWidth = 0;
			List<String> v = new ArrayList<String>();
			try {
				while ((line = br.readLine()) != null) {
					int width = SwingUtilities.computeStringWidth(metrics, line);
					iMaxWidth = (iMaxWidth < width) ? width : iMaxWidth;
					v.add(line);
				}
			} catch (IOException ex) {
				ex.printStackTrace();
			}
			int lines = v.size();
			if (lines < 1) {
				strs = null;
				lines = 1;
			} else {
				strs = new String[lines];
				int i = 0;
				for (String s : v) {
					strs[i++] = s;
				}
			}
			int height = metrics.getHeight() * lines;
			return new Dimension(iMaxWidth + 6, height + 4);
		}
	}
}
