/*
 Tiamat - a role-playing game framework
 NavigationFrame.java - frame used to navigate within AdventureStudioFrame
 
 Copyright  (C) 2006 Hugues Johnson
 
 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 com.huguesjohnson.tiamat.tools.adventureStudio;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;

import com.huguesjohnson.tiamat.tools.BaseEditorFrame;
import com.huguesjohnson.tiamat.tools.adventureStudio.event.NavigationEventHandler;

/** NavigationFrame - frame used to navigate within AdventureStudioFrame
 * @author Hugues Johnson
 */
public class NavigationPanel extends JPanel{
	/* Determines if a de-serialized file is compatible with this class. See <a href="http://java.sun.com/j2se/1.5.0/docs/guide/serialization/spec/class.html">Java Object Serialization Specifications</a>. */
	private static final long serialVersionUID=6766436794640067048L;
	
	//ui components
	private JTree tree;
	private JButton addButton;
	private JButton removeButton;
	private JButton editButton;
	private JButton renameButton;
	
	public NavigationPanel(){
	    this.initComponents();
	}
	
	private void initComponents(){
		//set the layout
		this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
		
		//add the tree
		this.tree=new JTree();
	    this.tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
	    //add selection listener
	    this.tree.addTreeSelectionListener(new TreeSelectionListener(){
	        public void valueChanged(TreeSelectionEvent e){
	        	onSelect();
	        }
	    });
	    //add mouse listener
	    this.tree.addMouseListener(new MouseAdapter(){
	    	public void mousePressed(MouseEvent e){ }
	    	public void mouseReleased(MouseEvent e){ onClick(e); }
	    });
	    //set the renderer
	    this.tree.setCellRenderer(new NavigationTreeCellRenderer());
	    //add the tree to a scroll pane
	    this.add(new JScrollPane(this.tree));
	    //erase that default junk in the tree
	    this.loadTree(null); 

		//add the button panel
		this.addButtonPanel();
	}
	
	private void addButtonPanel(){
		JPanel buttonPanel=new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel,BoxLayout.X_AXIS));
        JToolBar toolBar=new JToolBar();
        toolBar.setFloatable(false);
        toolBar.setRollover(true);		
		//add button
        this.addButton=new JButton();
        this.addButton.setIcon(new ImageIcon(this.getClass().getResource("/com/huguesjohnson/tiamat/tools/images/plus.gif")));
        this.addButton.setToolTipText("Add..");
        this.addButton.setEnabled(false);
        this.addButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent actionEvent){
                onAdd();
            }
        });
		toolBar.add(this.addButton);
		//remove button
		this.removeButton=new JButton();
		this.removeButton.setIcon(new ImageIcon(this.getClass().getResource("/com/huguesjohnson/tiamat/tools/images/minus.gif")));
		this.removeButton.setToolTipText("Delete..");
        this.removeButton.setEnabled(false);
		this.removeButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent actionEvent){
                onRemove();
            }
        });
		toolBar.add(this.removeButton);
		//add a separator
		toolBar.addSeparator();
		//edit button
		this.editButton=new JButton();
		this.editButton.setIcon(new ImageIcon(this.getClass().getResource("/com/huguesjohnson/tiamat/tools/images/edit.gif")));
		this.editButton.setToolTipText("Edit..");
        this.editButton.setEnabled(false);
		this.editButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent actionEvent){
                onEdit();
            }
        });
		toolBar.add(this.editButton);
		//rename button
		this.renameButton=new JButton();
		this.renameButton.setIcon(new ImageIcon(this.getClass().getResource("/com/huguesjohnson/tiamat/tools/images/rename.gif")));
		this.renameButton.setToolTipText("Rename");
        this.renameButton.setEnabled(false);
		this.renameButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent actionEvent){
            	onRename();
            }
        });
		toolBar.add(this.renameButton);
		//now add the toolbar and panel
		buttonPanel.add(toolBar);
		this.add(buttonPanel);
	}
	
	//override this in main class
	public void editorOpenedEvent(BaseEditorFrame editor,String title){ }
	
	public void onAdd(){ 
		NavigationTreeNode node=(NavigationTreeNode)this.tree.getLastSelectedPathComponent();
		if(node!=null){ 
			NavigationEventHandler eventHandler=node.getEventHandler();
			if(!eventHandler.canAdd()){ return; } //paranoid programming 101
			NavigationTreeNode newNode=eventHandler.onAdd();
			if((eventHandler.getCancel()==false)&&(newNode!=null)){
				//update tree with newly created file
				NavigationTreeNode root;
				NavigationTreeNode parent=(NavigationTreeNode)node.getParent();
				if(node.getEventHandler().getClass().equals(parent.getEventHandler().getClass())){
					root=parent;
				} else{
					root=node;
				}
				root.add(newNode);
				this.tree.updateUI(); //lost about an hour figuring out this annoyance with JTree
				//edit the newly created item
				this.tree.setSelectionPath(new TreePath(newNode.getPath()));
				this.onEdit();
			}
		}
	}
	
	public void onRemove(){ 
		NavigationTreeNode node=(NavigationTreeNode)this.tree.getLastSelectedPathComponent();
		if(node!=null){ 
			NavigationEventHandler eventHandler=node.getEventHandler();
			if(!eventHandler.canRemove()){ return; } //paranoid programming 101
			eventHandler.onRemove();
			if(eventHandler.getCancel()==false){
				NavigationTreeNode parent=(NavigationTreeNode)node.getParent();
				this.tree.setSelectionPath(new TreePath(parent.getPath()));
				NavigationTreeModel model=(NavigationTreeModel)this.tree.getModel();
				model.removeNodeFromParent(node);
				this.tree.updateUI();
			}
		}
	}
	
	public void onRename(){ 
		NavigationTreeNode node=(NavigationTreeNode)this.tree.getLastSelectedPathComponent();
		if(node!=null){ 
			NavigationEventHandler eventHandler=node.getEventHandler();
			if(!eventHandler.canRename()){ return; } //paranoid programming 101
			eventHandler.onRename();
			if(eventHandler.getCancel()==false){
				String caption=new String(eventHandler.getFileName());
				int indexOf=caption.indexOf(".");
				if(indexOf>0){
					caption=caption.substring(0,indexOf);
				}
				node.setCaption(caption);
				this.tree.updateUI();
			}
		}		
	}
	
	public void onEdit(){ 
		NavigationTreeNode node=(NavigationTreeNode)this.tree.getLastSelectedPathComponent();
		if(node!=null){ 
			NavigationEventHandler eventHandler=node.getEventHandler();
			if(!eventHandler.canEdit()){ return; } //paranoid programming 101
			BaseEditorFrame editor=eventHandler.onEdit();
			if((eventHandler.getCancel()==false)&&(editor!=null)){
				this.editorOpenedEvent(editor,eventHandler.getFileName());
			}
		}
		
	}
	
	public void onSelect(){
		NavigationTreeNode node=(NavigationTreeNode)this.tree.getLastSelectedPathComponent();
		if(node!=null){ 
			NavigationEventHandler eventHandler=node.getEventHandler();
			this.addButton.setEnabled(eventHandler.canAdd());
			this.editButton.setEnabled(eventHandler.canEdit());
			this.renameButton.setEnabled(eventHandler.canRename());
			this.removeButton.setEnabled(eventHandler.canRemove());
		}
	}
	
	public void onClick(MouseEvent mouseEvent){
		if(mouseEvent.getButton()>MouseEvent.BUTTON1){
			int x=mouseEvent.getX();
			int y=mouseEvent.getY();
			TreePath path=this.tree.getClosestPathForLocation(x,y);
			if(path!=null){
				this.tree.setSelectionPath(path);
				NavigationTreeNode node=(NavigationTreeNode)this.tree.getLastSelectedPathComponent();
				//build the popup menu
				JPopupMenu popupMenu=this.buildPopupMenu(node);
				popupMenu.show(this.tree,x,y);
			}
		}
	}
	
	public void loadTree(TreeModel nodes){
		this.tree.setModel(nodes);
	}
	
	public TreeModel getTreeModel(){
		return(this.tree.getModel());
	}
	
	private JPopupMenu buildPopupMenu(NavigationTreeNode node){
		NavigationEventHandler eventHandler=node.getEventHandler();
		JPopupMenu popupMenu=new JPopupMenu();
		//add
		JMenuItem menuItem=new JMenuItem("Add");
		menuItem.setIcon(new ImageIcon(this.getClass().getResource("/com/huguesjohnson/tiamat/tools/images/plus.gif")));
		menuItem.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent actionEvent){
                onAdd();
            }
        });
		menuItem.setEnabled(eventHandler.canAdd());
		popupMenu.add(menuItem);
		//remove
		menuItem=new JMenuItem("Remove");
		menuItem.setIcon(new ImageIcon(this.getClass().getResource("/com/huguesjohnson/tiamat/tools/images/minus.gif")));
		menuItem.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent actionEvent){
                onRemove();
            }
        });
		menuItem.setEnabled(eventHandler.canRemove());
		popupMenu.add(menuItem);
		//separator
		popupMenu.addSeparator();
		//edit
		menuItem=new JMenuItem("Edit");
		menuItem.setIcon(new ImageIcon(this.getClass().getResource("/com/huguesjohnson/tiamat/tools/images/edit.gif")));
		menuItem.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent actionEvent){
                onEdit();
            }
        });
		menuItem.setEnabled(eventHandler.canEdit());
		popupMenu.add(menuItem);
		//rename
		menuItem=new JMenuItem("Rename");
		menuItem.setIcon(new ImageIcon(this.getClass().getResource("/com/huguesjohnson/tiamat/tools/images/rename.gif")));
		menuItem.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent actionEvent){
                onRename();
            }
        });
		menuItem.setEnabled(eventHandler.canRename());
		popupMenu.add(menuItem);
		//return the menu
        return(popupMenu);
	}
	
}