import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.*;

public class EScopeFrame extends JFrame
{

    private JPanel componentPanel;
    private JMenuItem connectServer;
    private JMenuItem openExperiment;
    private JMenuItem requestData;
    private JMenuItem plotData;
    private JMenuItem quit;
    private double[] xVals=null,yVals=null;
    private String xUnits=null,yUnits=null;
    private int xLen=0,yLen=0;
    private MDSNetworkSource dataSource=new MDSNetworkSource();
    private String address;

    public EScopeFrame()
    {
        // Components for the GUI
        JMenuBar menuBar=new JMenuBar();
        JMenu menu = new JMenu("Main Menu");
        connectServer = new JMenuItem("Connect to server");
        openExperiment = new JMenuItem("Open experiment");
        requestData = new JMenuItem("Request data");
        plotData = new JMenuItem("Plot data");
        quit = new JMenuItem("Quit");

	connectServer.addActionListener(new ConnectServerAction());
        openExperiment.addActionListener(new OpenExperimentAction());
        requestData.addActionListener(new RequestDataAction());
        plotData.addActionListener(new PlotDataAction());
        quit.addActionListener(new QuitAction());

        menuBar.add(menu);
        menu.add(connectServer);
        menu.add(openExperiment);
        menu.add(requestData);
        menu.add(plotData);
        menu.add(quit);
        setJMenuBar(menuBar);

        connectServer.setEnabled(true);
        openExperiment.setEnabled(true);
        requestData.setEnabled(true);
        plotData.setEnabled(true);
        quit.setEnabled(true);

        componentPanel = new JPanel();
    }

    public void initialise()
    {
        getContentPane().add(componentPanel);

        setSize(400,200);
        setLocation(400,400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setTitle( "EScope GUI" );
        setVisible(true);
    }

    private class ConnectServerAction implements ActionListener
    {
        public ConnectServerAction() {}

        public void actionPerformed(ActionEvent event)
        {
            String serverString = JOptionPane.showInputDialog
                (EScopeFrame.this,"Specify server and port",
                 "localhost:8000");
            if(serverString == null) return; //Hit Cancel Button
            try
            {
                dataSource = new MDSNetworkSource();
                System.out.println( "\nConnecting to server ..." );
                dataSource.connect( serverString );
                System.out.println("...connection successful");
            }
            catch ( IOException e )
            {
               System.out.println( "Failed to communicate with server: " +
               e.getMessage() );
            }
        }
    }
    private class OpenExperimentAction implements ActionListener
    {
        public OpenExperimentAction() {}

        public void actionPerformed(ActionEvent event)
        {
            int ntokens = 0;
            StringTokenizer strTok=null;
            while (ntokens != 2)
            {
                String experimentString = JOptionPane.showInputDialog
                (EScopeFrame.this,"Specify experiment and shot","edam 17615");
                if(experimentString == null) return; //Hit Cancel Button
                strTok = new StringTokenizer(experimentString);
                ntokens = strTok.countTokens();
            }
            String experiment = strTok.nextToken();
            String portString = strTok.nextToken();
            try
            {
                int shot = Integer.parseInt(portString);
                System.out.println( "Opening Experiment and Shot ..." +
                   experiment + " " + shot);
                dataSource.open( experiment, shot ); // string, int

            }
            catch (NumberFormatException e) {System.out.println(e);}
            catch (IOException e) {System.out.println(e);}
        }
    }

    private class RequestDataAction implements ActionListener
    {
        public RequestDataAction() {}

        public void actionPerformed(ActionEvent event)
        {
            address = JOptionPane.showInputDialog
                  (EScopeFrame.this,"Enter legal file address",(address == null)?".signals.pb:pbmc01_im":address);
            if(address == null) return; //Hit Cancel Button
            MDSDescriptor result1=null,result2=null,result3=null,result4=null;
            String expression = null;
            try
            {
                expression="units_of(" + address + ")";
                System.out.println( "Evaluating Expression  " + expression );
                result1 = dataSource.evaluate( expression );

                expression= address;
                System.out.println( "Evaluating Expression  " + expression );
                result2 = dataSource.evaluate( expression );

                expression="units_of(dim_of(" + address +"))";
                System.out.println( "Evaluating Expression  " + expression );
                result3 = dataSource.evaluate( expression );

                expression="dim_of(" + address + ")";
                System.out.println( "Evaluating Expression  " + expression );
                result4 = dataSource.evaluate( expression );

                yUnits = result1.getCstringData();
                xUnits = result3.getCstringData();
                //If no data avaibalbe, Mdsdescriptor.getDoubleData() returns null
                //In this case getCStringData() returns the error description
                if(result2.getDoubleData() == null)
                {
                    JOptionPane.showMessageDialog(EScopeFrame.this,
                                                  "Cannot evaluate data " +
                                                  address + ": " +
                                                  result2.getCstringData(),
                                                  "Error evaluating data",
                                                  JOptionPane.ERROR_MESSAGE);
                    return;
                }
                //The same holds for the associated dimension
                if(result4.getDoubleData() == null)
                {
                    JOptionPane.showMessageDialog(EScopeFrame.this,
                                                  "Cannot evaluate dim_of(" +
                                                  address + "): " +
                                                  result2.getCstringData(),
                                                  "Error evaluating dimension",
                                                  JOptionPane.ERROR_MESSAGE);
                    return;
                }
                yLen = result2.getDoubleData().length;
                xLen = result4.getDoubleData().length;
                yVals = new double[yLen];
                xVals = new double[xLen];

                yVals = result2.getDoubleData();
                xVals = result4.getDoubleData();
            }
            catch ( IOException e )
            {
                System.out.println( "Failed to communicate with server: "
                + e.getMessage() );
            }
        }
    }

    private class PlotDataAction implements ActionListener
    {
        public PlotDataAction() {}

        public void actionPerformed(ActionEvent event)
        {
            if (xVals !=null && yVals != null && xUnits != null &&
                yUnits != null&& yLen !=0 && xLen !=0 )
            {   Plotter2.plot(xVals,yVals,xUnits,
                 yUnits,address);}
            else {System.out.println("Not enough information for plot");}
        }
    }

    private class QuitAction implements ActionListener
    {
        public QuitAction() {}

        public void actionPerformed(ActionEvent event)
        {
            try
            {
                if (dataSource.isOpen()) dataSource.close();

                if (dataSource.isConnected()) dataSource.disconnect();

                System.exit(0);
            }
            catch (IOException e) {System.out.println(e);}

        }
    }
}
