/*
 * SyntaxHiliteOptionPane.java - Syntax highlighting option pane
 * :tabSize=4:indentSize=4:noTabs=false:
 * :folding=explicit:collapseFolds=1:
 *
 * Copyright (C) 1999, 2000, 2001 Slava Pestov
 * Portions copyright (C) 1999 mike dillon
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package org.gjt.sp.jedit.options;

//{{{ Imports
import javax.swing.border.EmptyBorder;
import javax.swing.table.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.Vector;
import java.util.Collections;

import org.gjt.sp.jedit.syntax.*;
import org.gjt.sp.jedit.gui.StyleEditor;
import org.gjt.sp.jedit.*;
import org.gjt.sp.util.GenericGUIUtilities;
import org.gjt.sp.util.StandardUtilities;
import org.gjt.sp.util.SyntaxUtilities;
//}}}

//{{{ SyntaxHiliteOptionPane class
/**
 * Style option pane.
 * @author Slava Pestov
 * @version $Id: SyntaxHiliteOptionPane.java 24411 2016-06-19 11:02:53Z kerik-sf $
 */
public class SyntaxHiliteOptionPane extends AbstractOptionPane
{
	public static final EmptyBorder noFocusBorder = new EmptyBorder(1,1,1,1);

	//{{{ StyleOptionPane constructor
	public SyntaxHiliteOptionPane()
	{
		super("syntax");
	}
	//}}}

	//{{{ Protected members

	//{{{ _init() method
	@Override
	protected void _init()
	{
		setLayout(new BorderLayout(6,6));

		add(BorderLayout.CENTER,createStyleTableScroller());
	} //}}}

	//{{{ _save() method
	@Override
	protected void _save()
	{
		styleModel.save();
	} //}}}

	//}}}

	//{{{ Private members
	private StyleTableModel styleModel;
	private JTable styleTable;

	//{{{ createStyleTableScroller() method
	private JScrollPane createStyleTableScroller()
	{
		styleModel = createStyleTableModel();
		styleTable = new JTable(styleModel);
		styleTable.setRowHeight(GenericGUIUtilities.defaultRowHeight());
		styleTable.setRowSelectionAllowed(false);
		styleTable.setColumnSelectionAllowed(false);
		styleTable.setCellSelectionEnabled(false);
		styleTable.getTableHeader().setReorderingAllowed(false);
		styleTable.addMouseListener(new MouseHandler());
		TableColumnModel tcm = styleTable.getColumnModel();
 		TableColumn styleColumn = tcm.getColumn(1);
		styleColumn.setCellRenderer(new StyleTableModel.StyleRenderer());
		Dimension d = styleTable.getPreferredSize();
		d.height = Math.min(d.height,100);
		JScrollPane scroller = new JScrollPane(styleTable);
		scroller.setPreferredSize(d);
		return scroller;
	} //}}}

	//{{{ createStyleTableModel() method
	private static StyleTableModel createStyleTableModel()
	{
		return new StyleTableModel();
	} //}}}

	//}}}

	//{{{ MouseHandler class
	private class MouseHandler extends MouseAdapter
	{
		@Override
		public void mouseClicked(MouseEvent evt)
		{
			int row = styleTable.rowAtPoint(evt.getPoint());
			if(row == -1)
				return;

			SyntaxStyle style;
			SyntaxStyle current = (SyntaxStyle)styleModel.getValueAt(row,1);
			String token = (String) styleModel.getValueAt(row, 0);
			JDialog dialog = GenericGUIUtilities.getParentDialog(
					SyntaxHiliteOptionPane.this);
			if (dialog != null)
				style = new StyleEditor(dialog, current, token).getStyle();
			else
			{
				View view = GUIUtilities.getView(SyntaxHiliteOptionPane.this);
				style = new StyleEditor(view, current, token).getStyle();
			}
			if(style != null)
				styleModel.setValueAt(style,row,1);
		}
	} //}}}

	//{{{ StyleTableModel class
	private static class StyleTableModel extends AbstractTableModel
	{
		private final java.util.List<StyleChoice> styleChoices;

		//{{{ StyleTableModel constructor
		StyleTableModel()
		{
			styleChoices = new Vector<StyleChoice>(Token.ID_COUNT + 4);
			// start at 1 not 0 to skip Token.NULL
			for(int i = 1; i < Token.ID_COUNT; i++)
			{
				String tokenName = Token.tokenToString((byte)i);
				addStyleChoice(tokenName,"view.style." + tokenName.toLowerCase());
			}

			addStyleChoice(jEdit.getProperty("options.syntax.foldLine.1"),
			               "view.style.foldLine.1");
			addStyleChoice(jEdit.getProperty("options.syntax.foldLine.2"),
			               "view.style.foldLine.2");
			addStyleChoice(jEdit.getProperty("options.syntax.foldLine.3"),
			               "view.style.foldLine.3");
			addStyleChoice(jEdit.getProperty("options.syntax.foldLine.0"),
			               "view.style.foldLine.0");

			Collections.sort(styleChoices,new StandardUtilities.StringCompare<StyleChoice>(true));
		} //}}}

		//{{{ getColumnCount() method
		public int getColumnCount()
		{
			return 2;
		} //}}}

		//{{{ getRowCount() method
		public int getRowCount()
		{
			return styleChoices.size();
		} //}}}

		//{{{ getValueAt() method
		public Object getValueAt(int row, int col)
		{
			StyleChoice ch = styleChoices.get(row);
			switch(col)
			{
				case 0:
					return ch.label;
				case 1:
					return ch.style;
				default:
					return null;
			}
		} //}}}

		//{{{ setValueAt() method
		@Override
		public void setValueAt(Object value, int row, int col)
		{
			StyleChoice ch = styleChoices.get(row);
			if(col == 1)
				ch.style = (SyntaxStyle)value;
			fireTableRowsUpdated(row,row);
		} //}}}

		//{{{ getColumnName() method
		@Override
		public String getColumnName(int index)
		{
			switch(index)
			{
				case 0:
					return jEdit.getProperty("options.syntax.object");
				case 1:
					return jEdit.getProperty("options.syntax.style");
				default:
					return null;
			}
		} //}}}

		//{{{ save() method
		public void save()
		{
			for (StyleChoice ch : styleChoices)
			{
				jEdit.setProperty(ch.property,
					GUIUtilities.getStyleString(ch.style));
			}
		} //}}}

		//{{{ addStyleChoice() method
		private void addStyleChoice(String label, String property)
		{
			Font font = new JLabel().getFont();
			styleChoices.add(new StyleChoice(label,
			                                 property,
			                                 SyntaxUtilities.parseStyle(jEdit.getProperty(property),
			                                                         font.getFamily(), font.getSize(), true)));
		} //}}}

		//{{{ StyleChoice class
		private static class StyleChoice
		{
			private String label;
			private String property;
			private SyntaxStyle style;

			StyleChoice(String label, String property, SyntaxStyle style)
			{
				this.label = label;
				this.property = property;
				this.style = style;
			}

			// for sorting
			@Override
			public String toString()
			{
				return label;
			}
		} //}}}

		//{{{ StyleRenderer class
		static class StyleRenderer extends JLabel
			implements TableCellRenderer
		{
			//{{{ StyleRenderer constructor
			StyleRenderer()
			{
				setOpaque(true);
				setBorder(SyntaxHiliteOptionPane.noFocusBorder);
				setText("Hello World");
			} //}}}

			//{{{ getTableCellRendererComponent() method
			public Component getTableCellRendererComponent(
				JTable table,
				Object value,
				boolean isSelected,
				boolean cellHasFocus,
				int row,
				int col)
			{
				if (value != null)
				{
					SyntaxStyle style = (SyntaxStyle)value;
					setForeground(style.getForegroundColor());
					if (style.getBackgroundColor() != null)
						setBackground(style.getBackgroundColor());
					else
					{
						// this part sucks
						setBackground(jEdit.getColorProperty(
							"view.bgColor"));
					}
					setFont(style.getFont());
				}

				setBorder(cellHasFocus ? UIManager.getBorder(
					"Table.focusCellHighlightBorder")
				                       : SyntaxHiliteOptionPane.noFocusBorder);
				return this;
			} //}}}
		} //}}}
	} //}}}

} //}}}

