/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.ide.eclipse.adt.internal.editors;

import com.android.SdkConstants;
import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.ui.ErrorImageComposite;
import com.google.common.collect.Maps;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.plugin.AbstractUIPlugin;

import java.net.URL;
import java.util.IdentityHashMap;
import java.util.Map;

/**
 * Factory to generate icons for Android Editors.
 * <p/>
 * Icons are kept here and reused.
 */
public class IconFactory {
    public static final int COLOR_RED     = SWT.COLOR_DARK_RED;
    public static final int COLOR_GREEN   = SWT.COLOR_DARK_GREEN;
    public static final int COLOR_BLUE    = SWT.COLOR_DARK_BLUE;
    public static final int COLOR_DEFAULT = SWT.COLOR_BLACK;

    public static final int SHAPE_CIRCLE  = 'C';
    public static final int SHAPE_RECT    = 'R';
    public static final int SHAPE_DEFAULT = SHAPE_CIRCLE;

    private static IconFactory sInstance;

    private Map<String, Image> mIconMap = Maps.newHashMap();
    private Map<URL, Image> mUrlMap = Maps.newHashMap();
    private Map<String, ImageDescriptor> mImageDescMap = Maps.newHashMap();
    private Map<Image, Image> mErrorIcons;
    private Map<Image, Image> mWarningIcons;

    private IconFactory() {
    }

    public static synchronized IconFactory getInstance() {
        if (sInstance == null) {
            sInstance = new IconFactory();
        }
        return sInstance;
    }

    public void dispose() {
        // Dispose icons
        for (Image icon : mIconMap.values()) {
            // The map can contain null values
            if (icon != null) {
                icon.dispose();
            }
        }
        mIconMap.clear();
        for (Image icon : mUrlMap.values()) {
            // The map can contain null values
            if (icon != null) {
                icon.dispose();
            }
        }
        mUrlMap.clear();
        if (mErrorIcons != null) {
            for (Image icon : mErrorIcons.values()) {
                // The map can contain null values
                if (icon != null) {
                    icon.dispose();
                }
            }
            mErrorIcons = null;
        }
        if (mWarningIcons != null) {
            for (Image icon : mWarningIcons.values()) {
                // The map can contain null values
                if (icon != null) {
                    icon.dispose();
                }
            }
            mWarningIcons = null;
        }
    }

    /**
     * Returns an Image for a given icon name.
     * <p/>
     * Callers should not dispose it.
     *
     * @param osName The leaf name, without the extension, of an existing icon in the
     *        editor's "icons" directory. If it doesn't exists, a default icon will be
     *        generated automatically based on the name.
     */
    public Image getIcon(String osName) {
        return getIcon(osName, COLOR_DEFAULT, SHAPE_DEFAULT);
    }

    /**
     * Returns an Image for a given icon name.
     * <p/>
     * Callers should not dispose it.
     *
     * @param osName The leaf name, without the extension, of an existing icon in the
     *        editor's "icons" directory. If it doesn't exist, a default icon will be
     *        generated automatically based on the name.
     * @param color The color of the text in the automatically generated icons,
     *        one of COLOR_DEFAULT, COLOR_RED, COLOR_BLUE or COLOR_RED.
     * @param shape The shape of the icon in the automatically generated icons,
     *        one of SHAPE_DEFAULT, SHAPE_CIRCLE or SHAPE_RECT.
     */
    public Image getIcon(String osName, int color, int shape) {
        String key = Character.toString((char) shape) + Integer.toString(color) + osName;
        Image icon = mIconMap.get(key);
        if (icon == null && !mIconMap.containsKey(key)) {
            ImageDescriptor id = getImageDescriptor(osName, color, shape);
            if (id != null) {
                icon = id.createImage();
            }
            // Note that we store null references in the icon map, to avoid looking them
            // up every time. If it didn't exist once, it will not exist later.
            mIconMap.put(key, icon);
        }
        return icon;
    }

    /**
     * Returns an ImageDescriptor for a given icon name.
     * <p/>
     * Callers should not dispose it.
     *
     * @param osName The leaf name, without the extension, of an existing icon in the
     *        editor's "icons" directory. If it doesn't exists, a default icon will be
     *        generated automatically based on the name.
     */
    public ImageDescriptor getImageDescriptor(String osName) {
        return getImageDescriptor(osName, COLOR_DEFAULT, SHAPE_DEFAULT);
    }

    /**
     * Returns an ImageDescriptor for a given icon name.
     * <p/>
     * Callers should not dispose it.
     *
     * @param osName The leaf name, without the extension, of an existing icon in the
     *        editor's "icons" directory. If it doesn't exists, a default icon will be
     *        generated automatically based on the name.
     * @param color The color of the text in the automatically generated icons.
     *        one of COLOR_DEFAULT, COLOR_RED, COLOR_BLUE or COLOR_RED.
     * @param shape The shape of the icon in the automatically generated icons,
     *        one of SHAPE_DEFAULT, SHAPE_CIRCLE or SHAPE_RECT.
     */
    public ImageDescriptor getImageDescriptor(String osName, int color, int shape) {
        String key = Character.toString((char) shape) + Integer.toString(color) + osName;
        ImageDescriptor id = mImageDescMap.get(key);
        if (id == null && !mImageDescMap.containsKey(key)) {
            id = AbstractUIPlugin.imageDescriptorFromPlugin(
                    AdtPlugin.PLUGIN_ID,
                    String.format("/icons/%1$s.png", osName)); //$NON-NLS-1$

            if (id == null) {
                id = new LetterImageDescriptor(osName.charAt(0), color, shape);
            }

            // Note that we store null references in the icon map, to avoid looking them
            // up every time. If it didn't exist once, it will not exist later.
            mImageDescMap.put(key, id);
        }
        return id;
    }

    /**
     * Returns an Image for a given icon name.
     * <p/>
     * Callers should not dispose it.
     *
     * @param osName The leaf name, without the extension, of an existing icon
     *            in the editor's "icons" directory. If it doesn't exist, the
     *            fallback will be used instead.
     * @param fallback the fallback icon name to use if the primary icon does
     *            not exist, or null if the method should return null if the
     *            image does not exist
     * @return the icon, which should not be disposed by the caller, or null
     * if the image does not exist *and*
     */
    @Nullable
    public Image getIcon(@NonNull String osName, @Nullable String fallback) {
        String key = osName;
        Image icon = mIconMap.get(key);
        if (icon == null && !mIconMap.containsKey(key)) {
            ImageDescriptor id = getImageDescriptor(osName, fallback);
            if (id != null) {
                icon = id.createImage();
            }
            // Note that we store null references in the icon map, to avoid looking them
            // up every time. If it didn't exist once, it will not exist later.
            mIconMap.put(key, icon);
        }
        return icon;
    }

    /**
     * Returns an icon of the given name, or if that image does not exist and
     * icon of the given fallback name.
     *
     * @param key the icon name
     * @param fallbackKey the fallback image to use if the primary key does not
     *            exist
     * @return the image descriptor, or null if the image does not exist and the
     *         fallbackKey is null
     */
    @Nullable
    public ImageDescriptor getImageDescriptor(@NonNull String key, @Nullable String fallbackKey) {
        ImageDescriptor id = mImageDescMap.get(key);
        if (id == null && !mImageDescMap.containsKey(key)) {
            id = AbstractUIPlugin.imageDescriptorFromPlugin(
                    AdtPlugin.PLUGIN_ID,
                    String.format("/icons/%1$s.png", key)); //$NON-NLS-1$
            if (id == null) {
                if (fallbackKey == null) {
                    return null;
                }
                id = getImageDescriptor(fallbackKey);
            }

            // Place the fallback image for this key as well such that we don't keep trying
            // to load the failed image
            mImageDescMap.put(key, id);
        }

        return id;
    }

    /**
     * Returns the image indicated by the given URL
     *
     * @param url the url to the image resources
     * @return the image for the url, or null if it cannot be initialized
     */
    public Image getIcon(URL url) {
        Image image = mUrlMap.get(url);
        if (image == null) {
            ImageDescriptor descriptor = ImageDescriptor.createFromURL(url);
            image = descriptor.createImage();
            mUrlMap.put(url, image);
        }

        return image;
    }

    /**
     * Returns an image with an error icon overlaid on it. The icons are cached,
     * so the base image should be cached as well, or this method will keep
     * storing new overlays into its cache.
     *
     * @param image the base image
     * @return the combined image
     */
    @NonNull
    public Image addErrorIcon(@NonNull Image image) {
        if (mErrorIcons != null) {
            Image combined = mErrorIcons.get(image);
            if (combined != null) {
                return combined;
            }
        } else {
            mErrorIcons = new IdentityHashMap<Image, Image>();
        }

        Image combined = new ErrorImageComposite(image, false).createImage();
        mErrorIcons.put(image, combined);

        return combined;
    }

    /**
     * Returns an image with a warning icon overlaid on it. The icons are
     * cached, so the base image should be cached as well, or this method will
     * keep storing new overlays into its cache.
     *
     * @param image the base image
     * @return the combined image
     */
    @NonNull
    public Image addWarningIcon(@NonNull Image image) {
        if (mWarningIcons != null) {
            Image combined = mWarningIcons.get(image);
            if (combined != null) {
                return combined;
            }
        } else {
            mWarningIcons = new IdentityHashMap<Image, Image>();
        }

        Image combined = new ErrorImageComposite(image, true).createImage();
        mWarningIcons.put(image, combined);

        return combined;
    }

    /**
     * A simple image description that generates a 16x16 image which consists
     * of a colored letter inside a black & white circle.
     */
    private static class LetterImageDescriptor extends ImageDescriptor {

        private final char mLetter;
        private final int mColor;
        private final int mShape;

        public LetterImageDescriptor(char letter, int color, int shape) {
            mLetter = Character.toUpperCase(letter);
            mColor = color;
            mShape = shape;
        }

        @Override
        public ImageData getImageData() {

            final int SX = 15;
            final int SY = 15;
            final int RX = 4;
            final int RY = 4;

            Display display = Display.getCurrent();
            if (display == null) {
                return null;
            }

            Image image = new Image(display, SX, SY);

            GC gc = new GC(image);
            gc.setAdvanced(true);
            gc.setAntialias(SWT.ON);
            gc.setTextAntialias(SWT.ON);

            // image.setBackground() does not appear to have any effect; we must explicitly
            // paint into the image the background color we want masked out later.
            // HOWEVER, alpha transparency does not work; we only get to mark a single color
            // as transparent. You might think we could pick a system color (to avoid having
            // to allocate and dispose the color), or a wildly unique color (to make sure we
            // don't accidentally pick up any extra pixels in the image as transparent), but
            // this has the very unfortunate side effect of making neighbor pixels in the
            // antialiased rendering of the circle pick up shades of that alternate color,
            // which looks bad. Therefore we pick a color which is similar to one of our
            // existing colors but hopefully different from most pixels. A visual check
            // confirms that this seems to work pretty well:
            RGB backgroundRgb = new RGB(254, 254, 254);
            Color backgroundColor = new Color(display, backgroundRgb);
            gc.setBackground(backgroundColor);
            gc.fillRectangle(0, 0, SX, SY);

            gc.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
            if (mShape == SHAPE_CIRCLE) {
                gc.fillOval(0, 0, SX - 1, SY - 1);
            } else if (mShape == SHAPE_RECT) {
                gc.fillRoundRectangle(0, 0, SX - 1, SY - 1, RX, RY);
            }

            gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
            gc.setLineWidth(1);
            if (mShape == SHAPE_CIRCLE) {
                gc.drawOval(0, 0, SX - 1, SY - 1);
            } else if (mShape == SHAPE_RECT) {
                gc.drawRoundRectangle(0, 0, SX - 1, SY - 1, RX, RY);
            }

            // Get a bold version of the default system font, if possible.
            Font font = display.getSystemFont();
            FontData[] fds = font.getFontData();
            fds[0].setStyle(SWT.BOLD);
            // use 3/4th of the circle diameter for the font size (in pixels)
            // and convert it to "font points" (font points in SWT are hardcoded in an
            // arbitrary 72 dpi and then converted in real pixels using whatever is
            // indicated by getDPI -- at least that's how it works under Win32).
            fds[0].setHeight((int) ((SY + 1) * 3./4. * 72./display.getDPI().y));
            // Note: win32 implementation always uses fds[0] so we change just that one.
            // getFontData indicates that the array of fd is really an unusual thing for X11.
            font = new Font(display, fds);
            gc.setFont(font);
            gc.setForeground(display.getSystemColor(mColor));

            // Text measurement varies so slightly depending on the platform
            int ofx = 0;
            int ofy = 0;
            if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) {
                ofx = +1;
                ofy = -1;
            } else if (SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_DARWIN) {
                // Tweak pixel positioning of some letters that don't look good on the Mac
                if (mLetter != 'T' && mLetter != 'V') {
                    ofy = -1;
                }
                if (mLetter == 'I') {
                    ofx = -2;
                }
            }

            String s = Character.toString(mLetter);
            Point p = gc.textExtent(s);
            int tx = (SX + ofx - p.x) / 2;
            int ty = (SY + ofy - p.y) / 2;
            gc.drawText(s, tx, ty, true /* isTransparent */);

            font.dispose();
            gc.dispose();

            ImageData data = image.getImageData();
            image.dispose();
            backgroundColor.dispose();

            // Set transparent pixel in the palette such that on paint (over palette,
            // which has a background of SWT.COLOR_WIDGET_BACKGROUND, and over the tree
            // which has a white background) we will substitute the background in for
            // the backgroundPixel.
            int backgroundPixel = data.palette.getPixel(backgroundRgb);
            data.transparentPixel = backgroundPixel;

            return data;
        }
    }
}
