/**
 * This program and the accompanying materials
 * are made available under the terms of the License
 * which accompanies this distribution in the file LICENSE.txt
 */
package com.archimatetool.editor.diagram.figures.diagram;

import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.GridLayout;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;

import com.archimatetool.editor.diagram.figures.AbstractDiagramModelObjectFigure;
import com.archimatetool.editor.model.IArchiveManager;
import com.archimatetool.editor.ui.ColorFactory;
import com.archimatetool.editor.ui.IArchimateImages;
import com.archimatetool.editor.ui.ImageFactory;
import com.archimatetool.model.IDiagramModelImage;


/**
 * Diagram Image Figure
 * 
 * @author Phillip Beauvoir
 */
public class DiagramImageFigure extends AbstractDiagramModelObjectFigure {
    
    public static Dimension DEFAULT_SIZE = new Dimension(200, 150);
    
    private Image fImage;
    private Dimension fOriginalImageSize, fCurrentImageSize;
    
    private Color fBorderColor;
    
    // This is way faster than Draw2D re-drawing the original image at scale
    private boolean useScaledImage = true;
    
    public DiagramImageFigure(IDiagramModelImage diagramModelImage) {
        super(diagramModelImage);
    }
    
    @Override
    public IDiagramModelImage getDiagramModelObject() {
        return (IDiagramModelImage)super.getDiagramModelObject();
    }
    
    @Override
    protected void setUI() {
        setLayoutManager(new GridLayout());
        setOpaque(true);
        setImage();
    }
    
    /**
     * Update the image with new path
     */
    public void updateImage() {
        setImage();
        revalidate();
        repaint();
    }
    
    public void refreshVisuals() {
        setBorderColor();
    }

    protected void setBorderColor() {
        String val = getDiagramModelObject().getBorderColor();
        Color c = ColorFactory.get(val);
        if(c != fBorderColor) {
            fBorderColor = c;
            repaint();
        }
    }
    
    /**
     * @return The Border Color to use. If null, do not draw a border.
     */
    public Color getBorderColor() {
        return fBorderColor;
    }

    public Dimension getDefaultSize() {
        if(fOriginalImageSize != null) {
            return fOriginalImageSize;
        }
        
        return DEFAULT_SIZE;
    }
    
    @Override
    public Dimension getPreferredSize(int wHint, int hHint) {
        return getDefaultSize();
    }

    @Override
    protected void paintFigure(Graphics graphics) {
        graphics.setAntialias(SWT.ON);
        graphics.setInterpolation(SWT.HIGH);
        
        if(fImage != null) {
            if(useScaledImage) {
                rescaleImage();
                graphics.drawImage(fImage, bounds.x, bounds.y);
            }
            // This is way too slow
            else {
                graphics.drawImage(fImage, 0, 0, fImage.getBounds().width, fImage.getBounds().height,
                        bounds.x, bounds.y, bounds.width, bounds.height);
            }
        }
        else {
            super.paintFigure(graphics);
            Image image = IArchimateImages.ImageFactory.getImage(IArchimateImages.ICON_LANDSCAPE_16);
            graphics.drawImage(image, bounds.x + (bounds.width / 2) - 7, bounds.y + (bounds.height / 2) - 7);
        }
        
        // Border
        if(getBorderColor() != null) {
            graphics.setForegroundColor(getBorderColor());
            graphics.drawRectangle(new Rectangle(bounds.x, bounds.y, bounds.width - 1, bounds.height - 1));
        }
    }
    
    /**
     * Set the image and store it
     */
    protected void setImage() {
        disposeImage();
        
        fImage = getOriginalImage();
        
        if(fImage != null) {
            fOriginalImageSize = new Dimension(fImage.getBounds().width, fImage.getBounds().height);
            fCurrentImageSize = new Dimension(fOriginalImageSize);
        }
    }
    
    protected Image getOriginalImage() {
        Image image = null;
        
        String imagePath = getDiagramModelObject().getImagePath();
        
        if(imagePath != null) {
            IArchiveManager archiveManager = (IArchiveManager)getDiagramModelObject().getAdapter(IArchiveManager.class);
            try {
                image = archiveManager.createImage(imagePath);
            }
            catch(Exception ex) {
                ex.printStackTrace();
            }
        }
        
        return image;
    }
    
    /**
     * Use a re-usable rescaled image because drawing an image to scale in paintFigure(Graphics) is too slow
     */
    protected void rescaleImage() {
        int width = bounds.width;
        int height = bounds.height;
        
        if(width <= 0 && height <= 0) { // safety check
            return;
        }
        
        // If the image bounds are different to those in the current image, rescale the image
        if(width != fCurrentImageSize.width || height != fCurrentImageSize.height) {
            disposeImage();
            
            Image originalImage = getOriginalImage();
            
            // Use original image
            if(width == originalImage.getBounds().width && height == originalImage.getBounds().height) {
                fImage = originalImage;
            }
            // Scaled image
            else {
                fImage = ImageFactory.getScaledImage(originalImage, width, height);
                originalImage.dispose();
            }

            fCurrentImageSize = new Dimension(fImage.getBounds().width, fImage.getBounds().height);
        }
    }
    
    protected void disposeImage() {
        if(fImage != null && !fImage.isDisposed()) {
            fImage.dispose();
            fImage = null;
        }
    }
    
    @Override
    public IFigure getTextControl() {
        return null;
    }
    
    @Override
    public void dispose() {
        disposeImage();
        fBorderColor = null;
    }
}

@@ -2516,19 +2516,23 @@
         
-if(
+return 
 fOrigina
@@ -2546,108 +2546,51 @@
 ize 
-!
+=
 = null
-) %7B%0D%0A            return fOriginalImageSize;%0D%0A        %7D%0D%0A        %0D%0A        return DEFAULT_SIZE
+ ? DEFAULT_SIZE : fOriginalImageSize
 ;%0D%0A 
@@ -4125,53 +4125,8 @@
 mage
-.getBounds().width, fImage.getBounds().height
 );%0D%0A
@@ -4196,32 +4196,99 @@
 e);%0D%0A        %7D%0D%0A
+        else %7B%0D%0A            fOriginalImageSize = null;%0D%0A        %7D%0D%0A
     %7D%0D%0A    %0D%0A   
@@ -5867,24 +5867,24 @@
        %7D%0D%0A%0D%0A
+
             
@@ -5927,53 +5927,8 @@
 mage
-.getBounds().width, fImage.getBounds().height
 );%0D%0A

Fix getDefaultSize() returning wrong value