// CreateMobyInput.java
//
// Created: December 2005
//
// This file is a component of the BioMoby project.
// Copyright Martin Senger (martin.senger@gmail.com).
//

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JPanel;

import org.biomoby.client.CmdLineHelper;
import org.biomoby.service.dashboard.data.DataTypeTreeTable;
import org.biomoby.service.dashboard.data.ServiceInputPanel;
import org.biomoby.shared.CentralCached;
import org.biomoby.shared.MobyDataType;
import org.biomoby.shared.MobyException;
import org.biomoby.shared.MobyService;
import org.biomoby.shared.event.LogListener;
import org.jdom.Document;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import org.tulsoft.tools.BaseCmdLine;
import org.tulsoft.tools.gui.JFileChooserWithHistory;
import org.tulsoft.tools.gui.SwingUtils;

/**
 * A small command-line application showing how to use
 * DataTypeTreeTable and ServiceInputPanel components. It can be used,
 * as a standalone program, to create an input XML Biomoby data,
 * either just individual Biomoby data type, or all input data for a
 * selected Biomoby service. <p>
 *
 * @author <A HREF="mailto:martin.senger@gmail.com">Martin Senger</A>
 * @version $Id: CreateMobyInput.java,v 1.11 2009/01/30 14:48:01 kawas Exp $
 */
public class CreateMobyInput
    extends CmdLineHelper {

    /*************************************************************************
     * Create a GUI for a single data type.
     *************************************************************************/
    public CreateMobyInput (MobyDataType rootType,
			    MobyDataType[] dataTypes) {
	final DataTypeTreeTable treeTable =
	    new DataTypeTreeTable (rootType, dataTypes);
	JButton printButton = new JButton ("Print XML");
        printButton.addActionListener (new ActionListener() {
		public void actionPerformed (ActionEvent e) {
		    onPrint (treeTable);
		}
	    });

 	JPanel panel = new JPanel(new GridBagLayout());
	SwingUtils.addComponent
	    (panel, treeTable,
	     0, 0, 2, 1, GridBagConstraints.BOTH, GridBagConstraints.NORTHWEST, 1.0, 1.0);
	SwingUtils.addComponent
	    (panel, printButton,
	     0, 1, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.NORTHWEST, 1.0, 0.0);
	showIt ("Data type: " + rootType.getName(), panel);
    }

    /*************************************************************************
     * Create a GUI for the whole service.
     *************************************************************************/
    public CreateMobyInput (MobyService service,
			    MobyDataType[] dataTypes) {

	// create GUI
	JPanel panel = new JPanel (new GridBagLayout());
	final ServiceInputPanel tables =
	    new ServiceInputPanel (service, dataTypes);

	JButton printButton = new JButton ("Print XML");
        printButton.addActionListener (new ActionListener() {
		public void actionPerformed (ActionEvent e) {
		    onPrint (tables);
		}
	    });
        JButton loadButton = new JButton ("Load Input");
        loadButton.addActionListener (new ActionListener() {
		public void actionPerformed (ActionEvent e) {
		    JFileChooserWithHistory chooser = new JFileChooserWithHistory(System.getProperty("tmp.dir"), "load-file");
		    chooser.getFileChooser().setMultiSelectionEnabled(false);
		    if (chooser.getFileChooser().showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
			File chosen = chooser.getFileChooser().getSelectedFile();
			StringBuilder sb = new StringBuilder();
			String line = null;
			try {
			    BufferedReader br = new BufferedReader(new FileReader(chosen));
			    while ((line = br.readLine()) != null)
				sb.append(line + "\n");
			    onLoad(tables, sb.toString());
			} catch (FileNotFoundException fnfe) {
			    
			} catch (IOException ioe) {
			    
			}
			
		    }
		    
		}
	    });
	SwingUtils.addComponent
	    (panel, tables,
	     0, 0, 2, 1, GridBagConstraints.BOTH, GridBagConstraints.NORTHWEST, 1.0, 1.0);
	SwingUtils.addComponent
	    (panel, printButton,
	     0, 1, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.NORTHWEST, 1.0, 0.0);
	SwingUtils.addComponent
	    (panel, loadButton,
	     1, 1, 1, 1, GridBagConstraints.HORIZONTAL, GridBagConstraints.NORTHWEST, 1.0, 0.0);

	showIt ("Service: " + service.getName(), panel);
    }

    /*************************************************************************
     * Show it...
     *************************************************************************/
    protected void showIt (String title, JPanel panel) {
  	JFrame frame = SwingUtils.createMainFrame (panel, title);
   	SwingUtils.showMainFrame (frame, 600, 300);
    }

    /*************************************************************************
     * Extract data type from given table and print it. The result is
     * an XML document representing this data type.
     *************************************************************************/
    protected void onPrint (DataTypeTreeTable treeTable) {
	Document doc = treeTable.getXMLDocument();
	if (doc != null) {
	    XMLOutputter xo = new XMLOutputter();
	    xo.setFormat (Format.getPrettyFormat());
	    msgln (xo.outputString (doc));
	}
    }

    /*************************************************************************
     * Extract data type from given table and print it. The result is
     * an XML document representing complete input for a service.
     *************************************************************************/
    protected void onPrint (ServiceInputPanel inputs) {
	msgln (inputs.toXML());
    }
    
    protected void onLoad (ServiceInputPanel inputs, String xml) {
	try {
	    inputs.setValues(xml);
	} catch (MobyException me) {
	    me.printStackTrace();
	}
    }

    /*************************************************************************
     *
     * Entry point...
     *
     *************************************************************************/
    public static void main (String[] args) {

	try {

	    BaseCmdLine cmd = getCmdLine (args, CreateMobyInput.class);

	    // there is not much to do without -data or -service
	    String dataType = cmd.getParam ("-data");
	    String service = cmd.getParam ("-service");
	    if (dataType == null && service == null) {
		emsgln
		    ("Either '-data <data-type>' or '-service <service>' must be specified.");
		exit (1);
	    }

	    // where is a Moby registry
	    CentralCached worker = getCachableRegistryWorker (cmd);

	    // there is not much to do without -cachedir
	    String cacheDir = cmd.getParam ("-cachedir");
	    if (cacheDir == null) {
		emsgln ("Parameter -cachedir must be specified.");
		exit (1);
	    }

	    // how much to show
	    if (! cmd.hasOption ("-q"))
		worker.addNotificationListener (new LogListener());

	    // load all data types
	    MobyDataType[] dataTypes = worker.getDataTypes();

	    // show table for data type
	    if (dataType != null) {
		MobyDataType rootType = null;
		for (int i = 0; i < dataTypes.length; i++) {
		    if (dataType.equals (dataTypes[i].getName())) {
			rootType = dataTypes[i];
			break;
		    }
		}
		if (rootType == null) {
		    emsgln ("Parameter -data specifies a non-existing data type.");
		} else {
		    new CreateMobyInput (rootType, dataTypes);
		}
	    }

	    // load a service and show it in a table
	    if (service != null) {
		MobyService mobyService = null;
		MobyService[] services = worker.getServices();
		for (int i = 0; i < services.length; i++) {
		    if (service.equals (services[i].getName())) {
			mobyService = services[i];
			break;
		    }
		}
		if (mobyService == null) {
		    emsgln ("Parameter -service specifies a non-existing service.");
		} else {
		    new CreateMobyInput (mobyService, dataTypes);
		}
	    }

	} catch (Throwable e) {
	    processErrorAndExit (e);
	}
    }

}
