/*
 * Created on Jan 27, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package gov.nasa.jsc.plum;

import gov.nasa.jsc.plum.PlumUtil.CommentWindow;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Iterator;
import java.util.TreeMap;
import java.util.Vector;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

/**
 * @author randrews
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class TopologyPanel extends JPanel implements ActionListener{
    
    Connection conn;
    String name;
    TreeMap topology; // Maps rack names to their ComboBoxModels.
    TreeMap locidx; // Maps location names to their indices
    TreeMap rackidx;
    JButton save,comment;
    
    public TopologyPanel(Connection conn,String name){
        try{
            JPanel locations=new JPanel();
            
            this.conn=conn;
            this.name=name;
            topology=new TreeMap();
            locidx=new TreeMap();
            rackidx=new TreeMap();
            
            TreeMap racks=new TreeMap();
            ResultSet res=conn.createStatement().executeQuery("select racks.acronym as acronym,racks.idx as rackidx,locations.name as location from racks,locations, topology where racks.idx=topology.rack and locations.idx=topology.location and topology.name=\""+name+"\"");
            while(res.next())
            {
                racks.put(res.getString("acronym"),res.getString("location"));
                rackidx.put(res.getString("acronym"),res.getObject("rackidx"));
            }

            Vector locnames=new Vector();
            res=conn.createStatement().executeQuery("select name,idx from locations order by name asc");
            while(res.next())
            {
                String locname=res.getString("name");
                locnames.add(locname);
                locidx.put(locname,res.getObject("idx"));
            }
            
            locations.setLayout(new GridBagLayout());
            GridBagConstraints c=new GridBagConstraints();
            c.anchor=GridBagConstraints.WEST;
            c.gridy=0;
            
            Iterator i=racks.keySet().iterator();
            while(i.hasNext())
            {
                String rack=(String) i.next();
                
                c.gridx=0;c.weightx=0;
                locations.add(new JLabel(rack),c);
                
                JComboBox loc=new JComboBox();
                loc.setModel(new DefaultComboBoxModel(locnames));
                loc.setSelectedItem(racks.get(rack));
                
                c.gridx=1;c.weightx=1;
                locations.add(loc,c);
                
                topology.put(rack,loc.getModel());
                c.gridy++;
            }

            save=new JButton("Save");
            save.addActionListener(this);
            
            comment=new JButton("Comment");
            comment.addActionListener(this);
            
            setLayout(new GridBagLayout());
            
            JScrollPane scroll=new JScrollPane(locations);
            Dimension size=scroll.getPreferredSize();
            if(size.height>600)
            {
                size.height=600;
                scroll.setPreferredSize(size);
            }
            
            c.gridx=0;c.gridy=0;
            c.weightx=1;c.weighty=1;
            c.anchor=GridBagConstraints.CENTER;
            c.fill=GridBagConstraints.BOTH;
            add(scroll,c);
            
            c.gridy=1;
            c.weightx=0;c.weighty=0;
            add(save,c);
            
            c.gridy=2;
            add(comment,c);
            
        } catch(Exception e){
            e.printStackTrace();
        }
    }
    
    private class AsynchSaver extends Thread{
        JPanel owner;
        public AsynchSaver(JPanel owner){
            this.owner=owner;
        }
        public void run(){
            try{
                Statement stmt=conn.createStatement();
                
                Iterator i=topology.keySet().iterator();
                while(i.hasNext())
                {
                    String rack=(String) i.next();
                    DefaultComboBoxModel model=(DefaultComboBoxModel) topology.get(rack);
                    Integer loc=(Integer) locidx.get(model.getSelectedItem());
                    stmt.execute("update topology set location="+loc+" where rack="+rackidx.get(rack)+" and name=\""+name+"\"");
                }
                
                ResultSet collisions=conn.createStatement().executeQuery("select count(rack) as collisions,locations.name,locations.idx from topology,locations where locations.idx=topology.location and topology.name=\""+name+"\" group by location order by collisions desc");
                String locs="";
                while(collisions.next())
                {
                    int coll=collisions.getInt("collisions");
                    if(coll==1)break;
                    locs+=collisions.getString("name")+": ";
                    ResultSet racks=conn.createStatement().executeQuery("select acronym from racks,topology where topology.location="+collisions.getInt("idx")+" and topology.rack=racks.idx and topology.name=\""+name+"\"");
                    for(int n=0;n!=2;n++)
                    {
                        racks.next();
                        locs+=racks.getString("acronym");
                        if(n==0)locs+=", ";
                    }
                    if(racks.next())locs+=", ...";
                    locs+="\n";
                }
                if(!locs.equals(""))
                {
                    JOptionPane.showMessageDialog(owner,"The following locations have more than one rack:\n"+locs,"Rack collision",JOptionPane.WARNING_MESSAGE);
                }
            } catch(Exception e1){
                e1.printStackTrace();
            }
        }
    }
    
    public void actionPerformed(ActionEvent e){
        if(e.getSource()==save)
            new AsynchSaver(this).start();
        else if(e.getSource()==comment)
        {
            CommentWindow window=new CommentWindow(conn,"topology","name",name);
            window.setVisible(true);
        }
    }
}
