/*
 * GroupSelectionTool.java
 *
 * Created on November 8, 2007, 3:41 PM
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package sidnet.core.gui;

import sidnet.core.interfaces.SIDnetDrawableInterface;
import sidnet.core.interfaces.SIDnetRegistrable;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.LinkedList;
import javax.swing.JPanel;
import javax.swing.event.MouseInputListener;

/**
 *
 * @author Oliver
 */
public class GroupSelectionTool extends JPanel implements SIDnetDrawableInterface, MouseListener, MouseInputListener, SIDnetRegistrable{
    
    private int xStartRect, yStartRect, xEndRect, yEndRect;
    protected sidnet.core.misc.Node[] nodeList;
    protected LinkedList<sidnet.core.misc.Node> individualGroupNodeList;
    
    /** Creates a new instance of GroupSelectionTool */
    public GroupSelectionTool(sidnet.core.misc.Node[] nodeList) {
        xStartRect = -1;
        yStartRect = -1;
        xEndRect = -1;
        yEndRect = -1;
        individualGroupNodeList = new LinkedList<sidnet.core.misc.Node>();
        this.nodeList = nodeList;
    }
    
    public void configureGUI(JPanel hostPanel)
    {
         if (hostPanel == null)
             return;
         
        this.setOpaque(false);
        this.setBackground(Color.black);
        hostPanel.add(this);

        this.setBounds(hostPanel.getBounds());

        this.setSize(hostPanel.getSize());

        /* We choose to enable this by default */
        this.setVisible(true);
        
        hostPanel.addMouseListener(this);
        hostPanel.addMouseMotionListener(this);   
    }
    
    public boolean groupExists()
    {
        return individualGroupNodeList.size() >= 2;
    }

    public void repaintGUI()
    {
        // TODO
    }
    
    public void setVisibleGUI(boolean visibility)
    {
        // DO NOTHING
    }
    
    public void terminate()
    {
        // DO NOTHING
    }
    
    public void mouseMoved(MouseEvent ev)
    {
        // NOTHING
    }
    
    public void mouseClicked(MouseEvent ev)
    {
        if (ev.getButton() != MouseEvent.BUTTON1)
            return;
        
        xStartRect = -1;
        yStartRect = -1;
        xEndRect = -1;
        yEndRect = -1;
        
        for(int i = 0; i < nodeList.length; i++)
            nodeList[i].getNodeGUI().markSelected(false);
        
        if(individualGroupNodeList.size() > 0)
            individualGroupNodeList.clear();
        super.repaint();
    }
    
    public void mouseEntered(MouseEvent ev){};
    public void mouseExited(MouseEvent ev){};    
    public void mousePressed(MouseEvent ev){};
    public void mouseReleased(MouseEvent ev)
    {
        int tmp;
        
        if (xStartRect == -1)
            return;
        
        if (xStartRect > xEndRect)
        {
            tmp = xStartRect;
            xStartRect = xEndRect;
            xEndRect = tmp;
        }
        
        if (yStartRect > yEndRect)
        {
            tmp = yStartRect;
            yStartRect = yEndRect;
            yEndRect = tmp;
        }

        
        // Mark all affected nodes
        for(int i = 0; i < nodeList.length; i++)
        {
            if (nodeList[i].getNodeGUI().getPanelLocation2D().getX() >= xStartRect && 
                nodeList[i].getNodeGUI().getPanelLocation2D().getX() <= xEndRect   &&
                nodeList[i].getNodeGUI().getPanelLocation2D().getY() >= yStartRect &&
                nodeList[i].getNodeGUI().getPanelLocation2D().getY() <= yEndRect)
                {
                    notifySelected(nodeList[i], true);
                    nodeList[i].getNodeGUI().markSelected(true);
                }
        }
    };
    
    public boolean isGroupMember(sidnet.core.misc.Node thisNode)
    {
        return individualGroupNodeList.contains(thisNode);
    }
    
    public void notifyActionPerformed(sidnet.core.misc.Node fromNode, ActionEvent e)
    {
         // Signal all affected nodes

        if (individualGroupNodeList.size() >= 2)
        {
            for (sidnet.core.misc.Node currentNode: individualGroupNodeList)
                currentNode.getNodeGUI().handleAction(e);
            return;
        }
    }
    
    public void notifySelected(sidnet.core.misc.Node node, boolean selected)
    {
        node.getNodeGUI().markSelected(selected);
        if (selected && !individualGroupNodeList.contains(node))
            individualGroupNodeList.add(node);
        if (!selected)
            individualGroupNodeList.remove(node);
    }
    
    
    public void mouseDragged(MouseEvent ev)
    {
        
        if (xStartRect == -1)
            xStartRect = ev.getX();
        
        xEndRect = ev.getX();
        
        if (yStartRect == -1)
            yStartRect = ev.getY();
        
        yEndRect = ev.getY();
        
        if (xStartRect < 0)
            xStartRect = 0;
        if (yStartRect < 0)
            yStartRect = 0;
        if (xEndRect < 0)
            xEndRect = 0;
        if (yEndRect < 0)
            yEndRect = 0;
        
        if (xStartRect > this.getWidth())
            xStartRect = this.getWidth();
        if (yStartRect > this.getHeight())
            yStartRect = this.getHeight();
        if (xEndRect > this.getWidth())
            xEndRect = this.getWidth();
        if (yEndRect > this.getHeight())
            yEndRect = this.getHeight();
        
        
        this.repaint();
    }
     
      public void paintComponent(Graphics g) {
        if (xStartRect == -1)
            return;
       
        Graphics2D g2d = (Graphics2D)g; 
                
        //super.paint(g);
        
        g2d.setColor(Color.yellow);
        g2d.setStroke(new BasicStroke(
          2, 
          BasicStroke.CAP_BUTT,
          BasicStroke.JOIN_MITER,
          50,
          new float[] {9}, 
          0));
        
        
        g2d.drawRect(xStartRect > xEndRect ? xEndRect : xStartRect, yStartRect > yEndRect ? yEndRect : yStartRect,
                     Math.abs(xStartRect - xEndRect), Math.abs(yStartRect - yEndRect));
    }
      
    protected void clear(Graphics g) {
       // super.paintComponent(g);
    }    
}
