package ru.taximaxim.pgsqlblocks.dbcdata;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.DecorationOverlayIcon;
import org.eclipse.jface.viewers.IDecoration;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.swt.graphics.Image;
import ru.taximaxim.pgsqlblocks.utils.Images;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class DbcDataListLabelProvider implements ITableLabelProvider {

    private static final int BLOCKED_ICON_QUADRANT = IDecoration.TOP_RIGHT;
    private static final int UPDATE_ICON_QUADRANT = IDecoration.BOTTOM_RIGHT;
    private List<ILabelProviderListener> listeners;

    private ConcurrentMap<String, Image> imagesMap = new ConcurrentHashMap<>();
    private ConcurrentMap<String, ImageDescriptor> decoratorsMap = new ConcurrentHashMap<>();

    /**
     * Constructs a FileTreeLabelProvider
     */
    public DbcDataListLabelProvider() {
        listeners = new ArrayList<>();
    }

    @Override
    public void addListener(ILabelProviderListener listener) {
        listeners.add(listener);
    }

    @Override
    public void dispose() {
        // TODO Auto-generated method stub
    }

    @Override
    public boolean isLabelProperty(Object element, String property) {
        return false;
    }

    @Override
    public void removeListener(ILabelProviderListener listener) {
        // TODO Auto-generated method stub
    }

    @Override
    public Image getColumnImage(Object element, int columnIndex) {
        DbcData dbcData = (DbcData) element;
        switch (columnIndex) {
        case 0:
            return getImage(dbcData);
        default:
            return null;
        }
    }

    @Override
    public String getColumnText(Object element, int columnIndex) {
        DbcData dbcData = (DbcData) element;
        switch (columnIndex) {
        case 0:
            return dbcData.getName();
        default:
            return null;
        }
    }

    private Image getImage(DbcData dbcData) {
        String path = dbcData.getStatus().getImageAddr();
        Image image = imagesMap.get(path);
        if (image == null) {
            image = new Image(null, getClass().getClassLoader().getResourceAsStream(path));
            imagesMap.put(path, image);
        }

        String decoratorBlockedPath = Images.DECORATOR_BLOCKED.getImageAddr();
        ImageDescriptor decoratorBlockedImageDesc = decoratorsMap.get(decoratorBlockedPath);
        if (decoratorBlockedImageDesc == null) {
            Image blockedImage = new Image(null, getClass().getClassLoader().getResourceAsStream(decoratorBlockedPath));
            ImageDescriptor imageDescriptor = ImageDescriptor.createFromImage(blockedImage);
            decoratorsMap.put(decoratorBlockedPath, imageDescriptor);
        }

        String decoratorUpdatePath = Images.DECORATOR_UPDATE.getImageAddr();
        ImageDescriptor decoratorUpdateImageDesc = decoratorsMap.get(decoratorUpdatePath);
        if (decoratorUpdateImageDesc == null) {
            Image updateImage = new Image(null, getClass().getClassLoader().getResourceAsStream(decoratorUpdatePath));
            ImageDescriptor imageDescriptor = ImageDescriptor.createFromImage(updateImage);
            decoratorsMap.put(decoratorUpdatePath, imageDescriptor);
        }

        if (dbcData.hasBlockedProcess()) {
            image = decorateImage(image, decoratorBlockedImageDesc, BLOCKED_ICON_QUADRANT);
        }
        if (dbcData.isInUpdateState()){
            if (dbcData.hasBlockedProcess()) {
                Image old = image;
                old.dispose();
            }
            image = decorateImage(image, decoratorUpdateImageDesc, UPDATE_ICON_QUADRANT);
        }
        return image;
    }

    private Image decorateImage(Image image, ImageDescriptor imageDescriptor, int iconQuadrant) {
        DecorationOverlayIcon overlayIcon = new DecorationOverlayIcon(image, imageDescriptor, iconQuadrant);
        return overlayIcon.createImage();
    }
}
@@ -2179,17 +2179,22 @@
  String 
-p
+imageP
 ath = db
@@ -2211,16 +2211,33 @@
 tatus().
+getStatusImage().
 getImage
@@ -2280,48 +2280,38 @@
 Map.
-get(path);%0A        if (image == null) %7B%0A
+computeIfAbsent(imagePath, %0A  
     
@@ -2318,23 +2318,22 @@
         
-image =
+  k -%3E
  new Ima
@@ -2393,24 +2393,23 @@
 eam(
-path
+k)
 ));%0A
+%0A
         
     
@@ -2408,51 +2408,47 @@
     
-    imagesMap.put(path, image);
+if (dbcData.hasBlockedProcess()) %7B
 %0A    
-    %7D%0A%0A
     
@@ -2522,32 +2522,36 @@
 Addr();%0A        
+    
 ImageDescriptor 
@@ -2596,619 +2596,85 @@
 Map.
-get(decoratorBlockedPath);%0A        if (decoratorBlockedImageDesc == null) %7B%0A            Image blockedImage = new Image(null, getClass().getClassLoader().getResourceAsStream(decoratorBlockedPath));%0A            ImageDescriptor imageDescriptor = ImageDescriptor.createFromImage(blockedImage);%0A            decoratorsMap.put(decoratorBlockedPath, imageDescriptor);%0A        %7D%0A%0A        String decoratorUpdatePath = Images.DECORATOR_UPDATE.getImageAddr();%0A        ImageDescriptor decoratorUpdateImageDesc = decoratorsMap.get(decoratorUpdatePath);%0A        if (decoratorUpdateImageDesc == null) %7B%0A            Image update
+computeIfAbsent(decoratorBlockedPath, path -%3E %7B%0A                Image blocked
 Imag
@@ -2741,32 +2741,17 @@
 sStream(
-decoratorUpdateP
+p
 ath));%0A 
@@ -2765,41 +2765,18 @@
     
-ImageDescriptor imageDescriptor =
+    return
  Ima
@@ -2808,14 +2808,15 @@
 age(
-update
+blocked
 Imag
@@ -2835,118 +2835,12 @@
     
-decoratorsMap.put(decoratorUpdatePath, imageDescriptor);%0A        %7D%0A%0A        if (dbcData.hasBlockedProcess()) %7B
+%7D);%0A
 %0A   
@@ -2930,32 +2930,33 @@
 ANT);%0A        %7D%0A
+%0A
         if (dbcD
@@ -2995,212 +2995,599 @@
     
-if (dbcData.hasBlockedProcess()) %7B%0A                Image old = image;%0A                old.dispose();%0A            %7D%0A            image = decorateImage(image, decoratorUpdateImageDesc, UPDATE_ICON_QUADRANT);
+String decoratorUpdatePath = Images.DECORATOR_UPDATE.getImageAddr();%0A            ImageDescriptor decoratorUpdateImageDesc = decoratorsMap.computeIfAbsent(decoratorUpdatePath, path -%3E %7B%0A                Image updateImage = new Image(null, getClass().getClassLoader().getResourceAsStream(path));%0A                return ImageDescriptor.createFromImage(updateImage);%0A            %7D);%0A%0A            Image old = image;%0A            image = decorateImage(image, decoratorUpdateImageDesc, UPDATE_ICON_QUADRANT);%0A            if (dbcData.hasBlockedProcess()) %7B%0A                old.dispose();%0A            %7D
 %0A   

Fix using disposed image; refactor