// $Id: DynamicViewer.java,v 1.7 2002/08/09 20:31:24 mdean Exp $

package org.daml.jena;

/**
 * a simple viewer for Jena instances
 */
public class DynamicViewer
    extends javax.swing.JFrame
{
    /**
     * history of resources visited
     */
    java.util.Stack stack = new java.util.Stack();

    javax.swing.JTable table;
    java.util.Vector statements = new java.util.Vector();

    class TableModel
	extends javax.swing.table.AbstractTableModel
    {
	public int getRowCount()
	{
	    return statements.size();
	}

	public int getColumnCount()
	{
	    return 2;
	}

	public String getColumnName(int col)
	{
	    switch (col)
		{
		case 0:
		    return "Predicate";
		case 1:
		    return "Object";
		default:
		    return "Column " + col;
		}
	}
		
	public Object getValueAt(int row, int col)
	{
	    com.hp.hpl.mesa.rdf.jena.model.Statement statement = (com.hp.hpl.mesa.rdf.jena.model.Statement) statements.elementAt(row);
	    switch (col)
		{
		case 0:
		    return statement.getPredicate();
		case 1:
		    return statement.getObject();
		default:
		    return "?";
		}
	}
    }

    public DynamicViewer(com.hp.hpl.mesa.rdf.jena.model.Resource resource)
	throws Exception
    {
	super("Dynamic Viewer - " + resource);
	stack.push(resource);

	setSize(800, 200);
	javax.swing.JPanel panel = new javax.swing.JPanel();
	java.util.Vector columnNames = new java.util.Vector();
	table = new javax.swing.JTable(new TableModel());
	table.setPreferredScrollableViewportSize(new java.awt.Dimension(800, 50));
	javax.swing.JMenuBar menuBar = new javax.swing.JMenuBar();
	setJMenuBar(menuBar);
	javax.swing.JMenu file = new javax.swing.JMenu("File");
	javax.swing.JMenuItem fileNew = file.add("New");
	fileNew.addActionListener(new java.awt.event.ActionListener()
	    {
		public void actionPerformed(java.awt.event.ActionEvent e)
		{
		    try {
			new DynamicViewer((com.hp.hpl.mesa.rdf.jena.model.Resource) stack.peek());
		    } catch (Exception ex) {
			System.err.println(ex);
		    }
		}
	    });
	// XXX - Add File
	// XXX - Add URI
	javax.swing.JMenuItem fileExit = file.add("Exit");
	fileExit.addActionListener(new java.awt.event.ActionListener()
	    {
		public void actionPerformed(java.awt.event.ActionEvent e)
		{
		    System.exit(0);
		}
	    });
	menuBar.add(file);
	final javax.swing.JMenuItem back = new javax.swing.JMenuItem("Back");
	menuBar.add(back);
	back.addActionListener(new java.awt.event.ActionListener()
	    {
		public void actionPerformed(java.awt.event.ActionEvent e)
		{
		    stack.pop();
		    if (stack.size() < 2)
			back.setEnabled(false);
		    try {
			updateViewer();
		    } catch (Exception ex) {
			System.err.println(ex);
		    }
		}
	    });
	back.setEnabled(false);
	javax.swing.JMenu help = new javax.swing.JMenu("Help");
	menuBar.add(help);
     java.awt.event.MouseListener mouseListener = new java.awt.event.MouseListener()
    {
	public void mouseClicked(java.awt.event.MouseEvent e)
	{
	    int row = table.getSelectedRow();
	    int col = table.getSelectedColumn();
	    Object object = table.getModel().getValueAt(row, col);
	    if (object instanceof com.hp.hpl.mesa.rdf.jena.model.Resource)
		{
		    com.hp.hpl.mesa.rdf.jena.model.Resource resource = (com.hp.hpl.mesa.rdf.jena.model.Resource) object;
		    boolean backEnabled = back.isEnabled();
		    try {
			// new DynamicViewer(resource);
			// ARP seems to just create com.hp.hpl.mesa.rdf.jena.common.ResourceImpl instances rather than calling model.createResource()
			if (! resource.isAnon())
			    resource = resource.getModel().createResource(resource.getURI());
			stack.push(resource);
			back.setEnabled(true);
			updateViewer();
		    } catch (Exception ex) {
			javax.swing.JOptionPane.showMessageDialog(DynamicViewer.this, ex);
			// undo
			stack.pop();
			back.setEnabled(backEnabled);
			try {
			    updateViewer();
			} catch (Exception ex2) {
			    System.err.println(ex2);
			}
		    }
		}
	}
	public void mousePressed(java.awt.event.MouseEvent e) {}
	public void mouseReleased(java.awt.event.MouseEvent e) {}
	public void mouseEntered(java.awt.event.MouseEvent e) {}
	public void mouseExited(java.awt.event.MouseEvent e) {}
	};
        table.addMouseListener(mouseListener);
	panel.setLayout(new java.awt.BorderLayout());
	panel.add(new javax.swing.JScrollPane(table),
		  java.awt.BorderLayout.CENTER);
	getContentPane().add(panel);

	updateViewer();
    }

    /**
     * move to a new Resource, etc.
     */
    void updateViewer()
	throws Exception
    {
	com.hp.hpl.mesa.rdf.jena.model.Resource resource = (com.hp.hpl.mesa.rdf.jena.model.Resource) stack.peek();

	statements.clear();
	System.out.println(resource + " is a " + resource.getClass()); // XXX
	com.hp.hpl.mesa.rdf.jena.model.StmtIterator iterator = resource.listProperties();
	while (iterator.hasNext())
	    {
		com.hp.hpl.mesa.rdf.jena.model.Statement statement = (com.hp.hpl.mesa.rdf.jena.model.Statement) iterator.next();
		statements.add(statement);
	    }

	setTitle("Dynamic Viewer - " + resource);

	if (isVisible())
	    {
		table.revalidate();
		repaint();
	    }
	else setVisible(true);
    }
    

    static void usage()
    {
	System.err.println("Usage:  [uri]");
    }

    /**
     * command-line interface for non-embedded use
     */
    public static void main(String args[])
	throws Exception
    {
	java.awt.Frame frame = new java.awt.Frame();

	if (args.length > 1)
	    usage();
	String uri;
	if (args.length == 0)
	    {
		if ((uri = javax.swing.JOptionPane.showInputDialog(frame, 
								   "Input URI",
								   "http://")) == null)
		    System.exit(0);
	    }
	else
	    uri = args[0];

	java.net.Authenticator.setDefault(new org.daml.PromptAuthenticator(frame));

	com.hp.hpl.mesa.rdf.jena.model.Model model = new DynamicModel();
	int hash = uri.lastIndexOf('#');
	String base = (hash == (-1)) ? uri : uri.substring(0, hash);
	model.read(base);
	new DynamicViewer(model.getResource(uri));
    }
}
