package com.wrapp.android.webimage;

import java.net.URL;
import java.util.LinkedList;
import java.util.Queue;

public class ImageLoader {
  private static final int NUM_WORKERS = 2;

  private static ImageLoader staticInstance;
  private final Queue<ImageRequest> pendingRequests = new LinkedList<ImageRequest>();
  private final Worker[] workerPool = new Worker[NUM_WORKERS];


  private static class Worker extends Thread {
    @Override
    public void run() {
      final Queue<ImageRequest> requestQueue = getInstance().pendingRequests;
      ImageRequest request;
      while(true) {
        synchronized(requestQueue) {
          while(requestQueue.isEmpty()) {
            try {
              requestQueue.wait();
            }
            catch(InterruptedException e) {
              e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            }
          }

          request = requestQueue.poll();
        }

        processRequest(request);
      }
    }

    private void processRequest(ImageRequest request) {
      request.listener.onDrawableLoaded(ImageCache.loadImage(request));
    }
  }


  private static ImageLoader getInstance() {
    if(staticInstance == null) {
      staticInstance = new ImageLoader();
    }
    return staticInstance;
  }

  private ImageLoader() {
    for(int i = 0; i < NUM_WORKERS; i++) {
      workerPool[i] = new Worker();
      workerPool[i].start();
    }
  }

  public static void load(URL imageUrl, ImageRequest.Listener listener, boolean cacheInMemory) {
    Queue<ImageRequest> requestQueue = getInstance().pendingRequests;
    synchronized(requestQueue) {
      for(ImageRequest request : requestQueue) {
        if(request.listener.equals(listener)) {
          if(request.imageUrl.equals(imageUrl)) {
            return;
          }
          else {
            // TODO: Check for same request but with different URL
          }
        }
      }

      // TODO: Check running tasks for duplicate jobs
    }

    synchronized(requestQueue) {
      requestQueue.add(new ImageRequest(imageUrl, listener, cacheInMemory));
      // TODO: Use notifyAll() instead?
      requestQueue.notify();
    }
  }

  public static void enableLogging(String tag, int level) {
    LogWrapper.tag = tag;
    LogWrapper.level = level;
  }
}

@@ -41,20 +41,91 @@
 ort 
-java.net.URL
+android.graphics.drawable.Drawable;%0A%0Aimport java.net.URL;%0Aimport java.util.Iterator
 ;%0Aim
@@ -446,56 +446,224 @@
 S%5D;%0A
-%0A%0A  private static class Worker extends Thread %7B
+  private final ImageRequest%5B%5D runningRequests = new ImageRequest%5BNUM_WORKERS%5D;%0A%0A%0A  private static class Worker extends Thread %7B%0A    private int index;%0A%0A    public Worker(int index) %7B%0A      this.index = index;%0A    %7D%0A
 %0A   
@@ -1316,73 +1316,507 @@
     
-request.listener.onDrawableLoaded(ImageCache.loadImage(request));
+final ImageRequest%5B%5D runningRequests = getInstance().runningRequests;%0A      Drawable drawable;%0A%0A      synchronized(runningRequests) %7B%0A        runningRequests%5Bindex%5D = request;%0A        drawable = ImageCache.loadImage(request);%0A      %7D%0A      synchronized(runningRequests) %7B%0A        if(request != null) %7B%0A          request.listener.onDrawableLoaded(drawable);%0A          runningRequests%5Bindex%5D = null;%0A        %7D%0A        else %7B%0A          LogWrapper.logMessage(%22Interrupted, returning%22);%0A        %7D%0A      %7D
 %0A   
@@ -2084,16 +2084,17 @@
  Worker(
+i
 );%0A     
@@ -2618,24 +2618,908 @@
  %7D%0A      %7D%0A%0A
+      final ImageRequest%5B%5D runningRequests = getInstance().runningRequests;%0A      synchronized(runningRequests) %7B%0A        for(int i = 0; i %3C runningRequests.length; i++) %7B%0A          ImageRequest request = runningRequests%5Bi%5D;%0A          if(request != null) %7B%0A            if(request.listener.equals(listener)) %7B%0A              if(request.imageUrl.equals(imageUrl)) %7B%0A                // Ignore duplicate requests. This is common when doing view recycling in list adapters%0A                return;%0A              %7D%0A              else %7B%0A                // Null out the running request in this index. The job will continue running, but when%0A                // it returns it will skip notifying the listener and start processing the next job in%0A                // the pending request queue.%0A                runningRequests%5Bi%5D = null;%0A              %7D%0A            %7D%0A          %7D%0A        %7D%0A      %7D%0A%0A
       // TOD

Check for already running requests, remove/return