package org.helioviewer.jhv.display;

import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.helioviewer.gl3d.scenegraph.math.GL3DVec3d;

public class Displayer {
    public static Object displaylock = new Object();
    public static int STATE2D = 1;
    public static int STATE3D = 2;
    private static Displayer instance = new Displayer();
    private ArrayList<DisplayListener> listeners = new ArrayList<DisplayListener>();
    private final ArrayList<RenderListener> renderListeners = new ArrayList<RenderListener>();
    private final ExecutorService displayPool = Executors.newSingleThreadExecutor();
    private boolean displaying = false;
    private int state = 2;
    public static ArrayList<GL3DVec3d> pointList = new ArrayList<GL3DVec3d>();
    public static int screenScale = 1;

    public void register(GL3DComponentFakeInterface gl3dcomponent) {
    }

    public static Displayer getSingletonInstance() {
        if (instance == null) {
            throw new NullPointerException("Displayer not initialized");
        }
        return instance;
    }

    public void addListener(final DisplayListener listener) {
        listeners.add(listener);
    }

    public void removeListener(final DisplayListener renderListener) {
        synchronized (renderListener) {
            listeners.remove(renderListener);
        }
    }

    public void addRenderListener(final RenderListener renderListener) {
        synchronized (renderListener) {
            renderListeners.add(renderListener);
        }
    }

    public void removeRenderListener(final RenderListener listener) {
        synchronized (renderListeners) {
            renderListeners.remove(listener);
        }
    }

    public void render() {
        if (!displaying) {
            displaying = true;
            synchronized (renderListeners) {
                for (final RenderListener renderListener : renderListeners) {
                    renderListener.render();
                }
            }
            displaying = false;
        }

    }

    private void tdisplay() {
        synchronized (displaylock) {
            for (final DisplayListener listener : listeners) {
                listener.display();
            }
        }
    }

    private final class DisplayTask implements Runnable {
        @Override
        public void run() {
            tdisplay();
        }
    }

    public void display() {
        displayPool.submit(new DisplayTask());
    }

    public void removeListeners() {
        this.listeners = new ArrayList<DisplayListener>();
    }

    public void setState(int state) {
        this.state = state;
    }

    public int getState() {
        return state;
    }
}

@@ -95,23 +95,17 @@
 Executor
-Service
+s
 ;%0Aimport
@@ -126,24 +126,34 @@
 current.
+ThreadPool
 Executor
 s;%0A%0Aimpo
@@ -144,17 +144,16 @@
 Executor
-s
 ;%0A%0Aimpor
@@ -606,24 +606,34 @@
 e final 
+ThreadPool
 Executor
 Service 
@@ -628,15 +628,8 @@
 utor
-Service
  dis
@@ -639,16 +639,71 @@
 yPool = 
+(ThreadPoolExecutor) Executors.newFixedThreadPool(1);//
 Executor
@@ -727,24 +727,25 @@
 Executor();%0A
+%0A
     private 
@@ -2520,32 +2520,85 @@
 oid display() %7B%0A
+        if (displayPool.getActiveCount() == 0) %7B%0A    
         displayP
@@ -2628,16 +2628,26 @@
 ask());%0A
+        %7D%0A
     %7D%0A%0A 

drop unnecessary display runs