/*
 Javier Kohen's Java Framework Classes.
 Copyright (C) 2000  Javier Kohen <jkohen at tough.com>
 
 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
 (at your option) 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 ar.com.jkohen.awt;
 
 import java.awt.*;
 import java.awt.event.*;
 import java.util.Vector;
 
 import ar.com.jkohen.util.Resources;
 import ar.com.jkohen.irc.MircMessage;
 
 public class TextFieldHistory extends TextField implements ActionListener, KeyListener
 {
 	private static Frame frame;
 	private static Resources res;
 	private static TextAttributePicker pa;
 
 	private boolean focusTraversable;
 
 	// Purge entries past this number (actual entry is part of the count.)
 	// Twenty seems a sane number for a human being's short-term memory of what he could've written =)
 	// Forty either, because memory works better at night
 	private int history_max_size = 40;
 
 	private Vector history;
 	private int pos;
 
 	public TextFieldHistory(Frame f)
 	{
 		this(0);
 		this.frame = f;
 	}
 
 	public TextFieldHistory(int columns)
 	{
 		this("", columns);
 	}
 
 	public TextFieldHistory(String text)
 	{
 		this(text, 0);
 	}
 
 	public TextFieldHistory(String text, int columns)
 	{
 		super(text, columns);
 
 		// First place is for the current entry's content.
 		history = new Vector(1);
 		history.addElement("");
 		pos = 0;
 
 		addActionListener(this);
 		addKeyListener(this);
 	}
 
 	public int getMaximumHistorySize()
 	{
 		return history_max_size;
 	}
 
 	public void setMaximumHistorySize(int new_size)
 	{
 		history_max_size = new_size;
 		history.setSize(history_max_size);
 	}
 
 	private void loadItem(int n)
 	{
 		String item = (String) history.elementAt(pos);
 		setText(item);
 		setCaretPosition(item.length());
 	}
 
 	public void insert(String new_text)
 	{
 		int i = getSelectionStart();
 		int j = getSelectionEnd();
 		String text = getText();
 
 		if (i == j)
 		{
 			// Insert attributes at caret position.
 			int pos = getCaretPosition();
 
 			text = text.substring(0, pos).concat(new_text).concat(text.substring(pos));
 
 			setText(text);
 			setCaretPosition(pos + new_text.length());
 		}
 		else
 		{
 			// Insert attributes at start and at end of selection.
 			text = text.substring(0, i).concat(new_text).concat(text.substring(i, j)).concat(new_text).concat(text.substring(j));
 
 			setText(text);
 			setSelectionStart(i);
 			setSelectionEnd(j + (new_text.length() * 2));
 		}
 	}
 
 	public void pickAttr()
 	{
 		if (pa == null)
 		{
 			Dimension disposition = new Dimension(16, 1);
 			Dimension item_size = new Dimension(12, 16);
 			Dimension gap = new Dimension(2, 2);
 			pa = new TextAttributePicker(frame, this, disposition, item_size, gap);
 
 			// WORKAROUND: #34 something is broken in NN.
 			pa.addWindowListener(new WindowAdapter()
 			{
 				public void windowClosed(WindowEvent e)
 				{
 					pa = null;
 				}
 
 				public void windowClosing(WindowEvent windowevent)
 				{
 					windowevent.getWindow().dispose();
 				}
 			});
 		}
 		else
 		{
 			pa.setTextField(this);
 			pa.setVisible(true);
 		}
 	}
 
 	public void actionPerformed(ActionEvent e)
 	{
 		// Record entered lines.
 		String entry = e.getActionCommand();
 
 		if (entry.length() == 0)
 			return;
 
 		// Reset history position.
 		pos = 0;
 
 		history.insertElementAt(e.getActionCommand(), 1);
 
 		if (history.size() > history_max_size)
 			history.setSize(history_max_size);
 	}
 
 	public void keyPressed(KeyEvent ev)
 	{
 		if (!this.isEditable())
 			return;
 
 		if (ev.getModifiers() == KeyEvent.CTRL_MASK)
 		{
 			switch (ev.getKeyCode())
 			{
 			case (KeyEvent.VK_P):
 				pickAttr();
 				break;
 
 			case (KeyEvent.VK_O):
 				insert(String.valueOf(MircMessage.RESET));
 				break;
 
 			case (KeyEvent.VK_B):
 				insert(String.valueOf(MircMessage.BOLD));
 				break;
 
 			case (KeyEvent.VK_U):
 				insert(String.valueOf(MircMessage.UNDERLINE));
 				break;
 
 			case (KeyEvent.VK_I):
 				insert(String.valueOf(MircMessage.ITALIC));
 				break;
 
 			case (KeyEvent.VK_R):
 				insert(String.valueOf(MircMessage.REVERSE));
 				break;
 
 			case (KeyEvent.VK_G):
 				insert(String.valueOf(MircMessage.BELL));
 				break;
 			}
 		}
 		else
 		{
 			switch (ev.getKeyCode())
 			{
 			case KeyEvent.VK_UP:
 				if (pos == 0)
 				{
 					// Store not yet entered entry.
 					history.setElementAt(getText(), 0);
 				}
 				pos = (pos + 1) % history.size();
 				loadItem(pos);
 				break;
 
 			case KeyEvent.VK_DOWN:
 				if (pos == 0)
 				{
 					// Store not yet entered entry.
 					history.setElementAt(getText(), 0);
 					pos = history.size();
 				}
 				pos--;
 				loadItem(pos);
 				break;
 
 			case KeyEvent.VK_ESCAPE:
 				pos = 0;
 				loadItem(pos);
 				break;
 
 			default:
 				pos = 0;
 				break;
 			}
 		}
 	}
 
 	public void keyReleased(KeyEvent e)
 	{
 	}
 
 	public void keyTyped(KeyEvent e)
 	{
 	}
 
 	public void setFocusTraversable(boolean b)
 	{
 		this.focusTraversable = b;
 	}
 /*
 	public boolean isFocusTraversable()
 	{
 		return(focusTraversable);
 	}
 */
 	public void transferFocus()
 	{
 
 	}
 }