package plugin;

import javax.swing.*;
import javax.swing.event.*;

import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;

import java.lang.reflect.*;

import lcm.spy.ChannelData;
import lcm.spy.ObjectPanel;
import lcm.lcm.LCMDataInputStream;

import senlcm.*;

public class DegViewerPlugin implements lcm.spy.SpyPlugin
{
    public boolean canHandle(long fingerprint)
    {
        if (fingerprint == senlcm.gpsd_t.LCM_FINGERPRINT ||
            fingerprint == senlcm.kvh_dsp3000_t.LCM_FINGERPRINT ||
            fingerprint == senlcm.ms_gx1_t.LCM_FINGERPRINT ||
            fingerprint == senlcm.os_compass_t.LCM_FINGERPRINT ||
            fingerprint == senlcm.rdi_pd5_t.LCM_FINGERPRINT
            )
            return true;
        else
            return false;
    }

    class MyAction extends AbstractAction
    {
	ChannelData cd;
	JDesktopPane jdp;

	public MyAction(JDesktopPane jdp, ChannelData cd)
	{
	    super("Structure Viewer (Degrees)...");
	    this.jdp = jdp;
	    this.cd = cd;
	}

	public void actionPerformed(ActionEvent e) 
	{
            Viewer v = new Viewer(cd);
	    jdp.add(v);
	    v.toFront();
	}
    }

    public Action getAction(JDesktopPane jdp, ChannelData cd)
    {
        return new MyAction(jdp, cd);
    }


    class Viewer extends JInternalFrame implements lcm.lcm.LCMSubscriber
    {
        ChannelData cd;
        ObjectPanel op;

    	public Viewer(ChannelData cd)
    	{
            super(cd.name+": Degrees", true, true);
            this.cd = cd;

            setLayout(new BorderLayout());
            op = new ObjectPanel(cd.name);
            add(new JScrollPane(op),BorderLayout.CENTER);
            setSize(550,400);
            setVisible(true);
            
            lcm.lcm.LCM.getSingleton().subscribe(cd.name, this);	    
        }        

	public void messageReceived (lcm.lcm.LCM lc, String channel, LCMDataInputStream dis)
	{
            Object o = null;

            if (!isVisible())
                return;

            try {
                dis.reset();

                /* gpsd_t */
                if (cd.fingerprint == senlcm.gpsd_t.LCM_FINGERPRINT) {
                    senlcm.gpsd_t gpsd = new senlcm.gpsd_t(dis);
                    gpsd.latitude = Math.toDegrees(gpsd.latitude);
                    gpsd.longitude = Math.toDegrees(gpsd.longitude);
                }
                /* kvh_dsp3000_t */
                else if (cd.fingerprint == senlcm.kvh_dsp3000_t.LCM_FINGERPRINT) {
                    senlcm.kvh_dsp3000_t kvh = new senlcm.kvh_dsp3000_t(dis);
                    kvh.data = Math.toDegrees(kvh.data);
                    o = kvh;
                }
                /* ms_gx1_t */
                else if (cd.fingerprint == senlcm.ms_gx1_t.LCM_FINGERPRINT) {
                    senlcm.ms_gx1_t ms = new senlcm.ms_gx1_t(dis);
                    for (int i=0; i<3; i++) {
                        ms.sAngRate[i] = Math.toDegrees(ms.sAngRate[i]);
                        ms.iAngRate[i] = Math.toDegrees(ms.iAngRate[i]);
                        ms.sEuler[i] = Math.toDegrees(ms.sEuler[i]);
                        ms.iEuler[i] = Math.toDegrees(ms.iEuler[i]);
                    }
                    o = ms;
                }
                /* os_compass */
                else if (cd.fingerprint == senlcm.os_compass_t.LCM_FINGERPRINT) {
                    senlcm.os_compass_t os = new senlcm.os_compass_t(dis);
                    for (int i=0; i<3; i++)
                        os.rph[i] = Math.toDegrees(os.rph[i]);
                    o = os;
                }
                /* rdi_pd5_t */
                else if (cd.fingerprint == senlcm.rdi_pd5_t.LCM_FINGERPRINT) {
                    senlcm.rdi_pd5_t rdi = new senlcm.rdi_pd5_t(dis);
                    rdi.pitch = Math.toDegrees(rdi.pitch);
                    rdi.roll = Math.toDegrees(rdi.roll);
                    rdi.heading = Math.toDegrees(rdi.heading);
                    o = rdi;
                }
                /* default */
                else {
                    System.out.println("DegViewerPlugin should not be active: "+cd.cls+" is not handled.");
                    Class<?> cls = cd.cls;
                    o = cls.getConstructor(DataInput.class).newInstance(dis);
                }
                
                if (op != null) 
                    op.setObject(o);
			
            } catch (NullPointerException ex) {
                cd.nerrors++;
            }
            catch (NoSuchMethodException ex) {
                cd.nerrors++;
                System.out.println("Spy.messageReceived ex: "+ex);
            } catch (InstantiationException ex) {
                cd.nerrors++;
                System.out.println("Spy.messageReceived ex: "+ex);
            } catch (IllegalAccessException ex) {
                cd.nerrors++;
                System.out.println("Spy.messageReceived ex: "+ex);
            } catch (InvocationTargetException ex) {
                cd.nerrors++;
            } catch (IOException ex) {
                cd.nerrors++;
                System.out.println("Spy.messageReceived ex: "+ex);
            }

	} // messageReceived

    } // class Viewer
} // class DegViewerPlugin
