package org.helioviewer.jhv.gui.components;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.KeyListener;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;

import javax.swing.BorderFactory;
import javax.swing.JPanel;

import org.helioviewer.jhv.gui.controller.CameraMouseController;
import org.helioviewer.jhv.gui.interfaces.ImagePanelPlugin;
import org.helioviewer.viewmodel.view.ComponentView;

/**
 * This class represents an image component that is used to display the image of
 * all images.
 *
 * @author caplins
 * @author Alen Agheksanterian
 * @author Benjamin Wamsler
 * @author Stephan Pagel
 * @author Markus Langenberg
 */
public class MainImagePanel extends JPanel {

    private final ArrayList<MouseMotionListener> mouseMotionListeners = new ArrayList<MouseMotionListener>();
    private final LinkedList<ImagePanelPlugin> plugins = new LinkedList<ImagePanelPlugin>();

    private final static CameraMouseController mouseController = new CameraMouseController();
    private final static ComponentView componentView = new ComponentView();

    public MainImagePanel() {
        super(new BorderLayout(0, 0));
        setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));

        Component component = componentView.getComponent();
        component.addMouseListener(mouseController);
        component.addMouseMotionListener(mouseController);
        component.addMouseWheelListener(mouseController);

        if (KeyListener.class.isAssignableFrom(mouseController.getClass())) {
            component.addKeyListener((KeyListener) mouseController);
        }
        add(component);

        mouseController.setImagePanel(this);
    }

    public ComponentView getComponentView() {
        return componentView;
    }

    /**
     * Adds a new plug-in to the component. Plug-ins in this case are controller
     * which e.g. has to react on inputs made to this component.
     *
     * @param newPlugin
     *            new plug-in which has to to be added to this component
     */
    public void addPlugin(ImagePanelPlugin newPlugin) {
        if (newPlugin == null) {
            return;
        }

        newPlugin.setImagePanel(this);
        newPlugin.setView(componentView);
        plugins.add(newPlugin);
    }

    /**
     * Removes a plug-in from the component.
     *
     * @param oldPlugin
     *            plug-in which has to to be removed from this component
     *
     * @see MainImagePanel#addPlugin(ImagePanelPlugin)
     */
    public void removePlugin(ImagePanelPlugin oldPlugin) {
        if (oldPlugin == null) {
            return;
        }

        oldPlugin.setView(null);
        oldPlugin.setImagePanel(null);
        plugins.remove(oldPlugin);
    }

    @Override
    public void addMouseListener(MouseListener l) {
        if (!Arrays.asList(componentView.getComponent().getMouseListeners()).contains(l)) {
            componentView.getComponent().addMouseListener(l);
        }
    }

    @Override
    public void addMouseWheelListener(MouseWheelListener l) {
        componentView.getComponent().addMouseWheelListener(l);
    }

    @Override
    public void removeMouseListener(MouseListener l) {
        componentView.getComponent().removeMouseListener(l);
    }

    @Override
    public void removeMouseWheelListener(MouseWheelListener l) {
        componentView.getComponent().removeMouseWheelListener(l);
    }

    @Override
    public void addMouseMotionListener(MouseMotionListener l) {
        if (l != null) {
            mouseMotionListeners.add(l);
        }
    }

    @Override
    public void removeMouseMotionListener(MouseMotionListener l) {
        if (l != null) {
            mouseMotionListeners.remove(l);
        }
    }

}

@@ -2408,32 +2408,726 @@
 .add(newPlugin);
+%0A%0A        Component component = componentView.getComponent();%0A%0A        if (newPlugin instanceof MouseListener && !Arrays.asList(component.getMouseListeners()).contains(newPlugin)) %7B%0A            component.addMouseListener((MouseListener) newPlugin);%0A        %7D%0A        if (newPlugin instanceof MouseMotionListener && !Arrays.asList(component.getMouseMotionListeners()).contains(newPlugin)) %7B%0A            component.addMouseMotionListener((MouseMotionListener) newPlugin);%0A        %7D%0A        if (newPlugin instanceof MouseWheelListener && !Arrays.asList(component.getMouseWheelListeners()).contains(newPlugin)) %7B%0A            component.addMouseWheelListener((MouseWheelListener) newPlugin);%0A        %7D
 %0A    %7D%0A%0A    /**%0A
@@ -3579,62 +3579,42 @@
 n);%0A
-    %7D%0A%0A    @Override%0A    public void addMouseListener(
+%0A        if (oldPlugin instanceof 
 Mous
@@ -3614,37 +3614,33 @@
 of MouseListener
- l) %7B
+)
 %0A        if (!Ar
@@ -3636,27 +3636,12 @@
     
-if (!Arrays.asList(
+    
 comp
@@ -3665,19 +3665,22 @@
 onent().
-get
+remove
 MouseLis
@@ -3688,72 +3688,10 @@
 ener
-s()).contains(l)) %7B%0A            componentView.getComponent().add
+((
 Mous
@@ -3695,26 +3695,35 @@
 ouseListener
-(l
+) oldPlugin
 );%0A        %7D
@@ -3724,88 +3724,53 @@
     
- 
-%7D%0A    %7D%0A%0A    @Override%0A    public void addMouseWheelListener(MouseWheel
+ if (oldPlugin instanceof MouseMotion
 Listener
  l) 
@@ -3757,38 +3757,38 @@
 seMotionListener
- l) %7B%0A
+)%0A    
         componen
@@ -3812,71 +3812,8 @@
 t().
-addMouseWheelListener(l);%0A    %7D%0A%0A    @Override%0A    public void 
 remo
@@ -3811,32 +3811,38 @@
 nt().removeMouse
+Motion
 Listener(MouseLi
@@ -3838,150 +3838,75 @@
 ner(
+(
 Mouse
-Listener l) %7B%0A        componentView.getComponent().removeMouseListener(l
+MotionListener) oldPlugin
 );%0A    
-%7D%0A%0A
     
-@Override%0A    public void removeMouseWheelListener(
+if (oldPlugin instanceof 
 Mous
@@ -3911,38 +3911,38 @@
 useWheelListener
- l) %7B%0A
+)%0A    
         componen
@@ -3991,339 +3991,40 @@
 ner(
-l);%0A    %7D%0A%0A    @Override%0A    public void addMouseMotionListener(MouseMotionListener l) %7B%0A        if (l != null) %7B%0A            mouseMotionListeners.add(l);%0A        %7D%0A    %7D%0A%0A    @Override%0A    public void removeMouseMotionListener(MouseMotionListener l) %7B%0A        if (l != null) %7B%0A            mouseMotionListeners.remove(l);%0A        %7D
+(MouseWheelListener) oldPlugin);
 %0A   

Fix mouse