/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.myorg.myviewer;

import java.util.Collection;
import java.util.Iterator;
import org.myorg.myapi.APIObject;
import org.openide.util.LookupEvent;
import org.openide.util.NbBundle;
import org.openide.windows.TopComponent;
import org.netbeans.api.settings.ConvertAsProperties;
import org.openide.awt.ActionID;
import org.openide.awt.ActionReference;
import org.openide.util.Lookup;
import org.openide.util.LookupListener;
import org.openide.util.Utilities;

/**
 * Top component which displays something.
 */
@ConvertAsProperties(dtd = "-//org.myorg.myviewer//MyViewer//EN",
autostore = false)
@TopComponent.Description(preferredID = "MyViewerTopComponent",
//iconBase="SET/PATH/TO/ICON/HERE", 
persistenceType = TopComponent.PERSISTENCE_ALWAYS)
@TopComponent.Registration(mode = "explorer", openAtStartup = true)
@ActionID(category = "Window", id = "org.myorg.myviewer.MyViewerTopComponent")
@ActionReference(path = "Menu/Window" /*, position = 333 */)
@TopComponent.OpenActionRegistration(displayName = "#CTL_MyViewerAction",
preferredID = "MyViewerTopComponent")
public final class MyViewerTopComponent extends TopComponent implements LookupListener {

    public MyViewerTopComponent() {
        initComponents();
        setName(NbBundle.getMessage(MyViewerTopComponent.class, "CTL_MyViewerTopComponent"));
        setToolTipText(NbBundle.getMessage(MyViewerTopComponent.class, "HINT_MyViewerTopComponent"));

    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();

        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, org.openide.util.NbBundle.getMessage(MyViewerTopComponent.class, "MyViewerTopComponent.jLabel1.text")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, org.openide.util.NbBundle.getMessage(MyViewerTopComponent.class, "MyViewerTopComponent.jLabel2.text")); // NOI18N

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel1)
                    .addComponent(jLabel2))
                .addContainerGap(303, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel2)
                .addContainerGap(250, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    // End of variables declaration//GEN-END:variables
    private Lookup.Result result = null;

    @Override
    public void componentOpened() {
        result = Utilities.actionsGlobalContext().lookupResult(APIObject.class);
        result.addLookupListener(this);
    }

    @Override
    public void componentClosed() {
        result.removeLookupListener(this);
        result = null;
    }

//    @Override
//    public void resultChanged(LookupEvent lookupEvent) {
//        Lookup.Result r = (Lookup.Result) lookupEvent.getSource();
//        Collection c = r.allInstances();
//        if (!c.isEmpty()) {
//            APIObject o = (APIObject) c.iterator().next();
//            jLabel1.setText(Integer.toString(o.getIndex()));
//            jLabel2.setText(o.getDate().toString());
//        } else {
//            jLabel1.setText("[no selection]");
//            jLabel2.setText("");
//        }
//    }
    @Override
    public void resultChanged(LookupEvent lookupEvent) {
        Lookup.Result r = (Lookup.Result) lookupEvent.getSource();
        Collection c = r.allInstances();
        if (!c.isEmpty()) {
            StringBuilder text1 = new StringBuilder();
            StringBuilder text2 = new StringBuilder();
            for (Iterator i = c.iterator(); i.hasNext();) {
                APIObject o = (APIObject) i.next();
                text1.append(o.getIndex());
                text2.append(o.getDate().toString());
                if (i.hasNext()) {
                    text1.append(',');
                    text2.append(',');
                }
            }
            jLabel1.setText(text1.toString());
            jLabel2.setText(text2.toString());
        } else {
            jLabel1.setText("[no selection]");
            jLabel2.setText("");
        }
    }

    void writeProperties(java.util.Properties p) {
        // better to version settings since initial version as advocated at
        // http://wiki.apidesign.org/wiki/PropertyFiles
        p.setProperty("version", "1.0");
        // TODO store your settings
    }

    void readProperties(java.util.Properties p) {
        String version = p.getProperty("version");
        // TODO read your settings according to their version
    }
}
