// License: GPL. Copyright 2007 by Immanuel Scholz and others
package org.openstreetmap.josm.gui.dialogs;

import static org.openstreetmap.josm.tools.I18n.tr;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.KeyEvent;
import java.util.Collection;

import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;

import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.command.Command;
import org.openstreetmap.josm.gui.MapFrame;
import org.openstreetmap.josm.gui.layer.OsmDataLayer.CommandQueueListener;

public class CommandStackDialog extends ToggleDialog implements CommandQueueListener {

	private DefaultTreeModel treeModel = new DefaultTreeModel(new DefaultMutableTreeNode());
    private JTree tree = new JTree(treeModel);

	public CommandStackDialog(final MapFrame mapFrame) {
		super(tr("Command Stack"), "commandstack", tr("Open a list of all commands (undo buffer)."), KeyEvent.VK_O, 100);
		Main.main.undoRedo.listenerCommands.add(this);
			
		tree.setRootVisible(false);
		tree.setShowsRootHandles(true);
		tree.expandRow(0);
		tree.setCellRenderer(new DefaultTreeCellRenderer(){
			@Override public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
				super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
				DefaultMutableTreeNode v = (DefaultMutableTreeNode)value;
				if (v.getUserObject() instanceof JLabel) {
					JLabel l = (JLabel)v.getUserObject();
					setIcon(l.getIcon());
					setText(l.getText());
				}
				return this;
			}
		});
		tree.setVisibleRowCount(8);
		add(new JScrollPane(tree), BorderLayout.CENTER);
	}

	@Override public void setVisible(boolean v) {
		if (v)
			buildList();
		else if (tree != null)
			treeModel.setRoot(new DefaultMutableTreeNode());
		super.setVisible(v);
	}

	private void buildList() {
		if (Main.map == null || Main.map.mapView == null || Main.map.mapView.editLayer == null)
			return;
		Collection<Command> commands = Main.main.undoRedo.commands;
		DefaultMutableTreeNode root = new DefaultMutableTreeNode();
		for (Command c : commands)
			root.add(c.description());
		treeModel.setRoot(root);
		tree.scrollRowToVisible(treeModel.getChildCount(root)-1);
	}

	public void commandChanged(int queueSize, int redoSize) {
		if (!isVisible())
			return;
        treeModel.setRoot(new DefaultMutableTreeNode());
		buildList();
    }
}
