/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
 *
 * 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.layout.gle2;

import static com.android.SdkConstants.ANDROID_STYLE_RESOURCE_PREFIX;
import static com.android.SdkConstants.PREFIX_RESOURCE_REF;
import static com.android.SdkConstants.STYLE_RESOURCE_PREFIX;
import static com.android.ide.eclipse.adt.internal.editors.layout.configuration.Configuration.MASK_RENDERING;
import static com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageUtils.SHADOW_SIZE;
import static com.android.ide.eclipse.adt.internal.editors.layout.gle2.ImageUtils.SMALL_SHADOW_SIZE;
import static com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderPreviewMode.DEFAULT;
import static com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderPreviewMode.INCLUDES;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.ide.common.rendering.api.Result;
import com.android.ide.common.rendering.api.Result.Status;
import com.android.ide.common.resources.ResourceFile;
import com.android.ide.common.resources.ResourceRepository;
import com.android.ide.common.resources.ResourceResolver;
import com.android.ide.common.resources.configuration.FolderConfiguration;
import com.android.ide.common.resources.configuration.ScreenOrientationQualifier;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.editors.descriptors.DocumentDescriptor;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.Configuration;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationChooser;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationClient;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.ConfigurationDescription;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.Locale;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.NestedConfiguration;
import com.android.ide.eclipse.adt.internal.editors.layout.configuration.VaryingConfiguration;
import com.android.ide.eclipse.adt.internal.editors.layout.gle2.IncludeFinder.Reference;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.adt.internal.resources.ResourceHelper;
import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.io.IFileWrapper;
import com.android.io.IAbstractFile;
import com.android.resources.Density;
import com.android.resources.ResourceType;
import com.android.resources.ScreenOrientation;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.devices.Device;
import com.android.sdklib.devices.Screen;
import com.android.sdklib.devices.State;
import com.android.utils.SdkUtils;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.IJobChangeListener;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
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.Region;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.progress.UIJob;
import org.w3c.dom.Document;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.lang.ref.SoftReference;
import java.util.Comparator;
import java.util.Map;

/**
 * Represents a preview rendering of a given configuration
 */
public class RenderPreview implements IJobChangeListener {
    /** Whether previews should use large shadows */
    static final boolean LARGE_SHADOWS = false;

    /**
     * Still doesn't work; get exceptions from layoutlib:
     * java.lang.IllegalStateException: After scene creation, #init() must be called
     *   at com.android.layoutlib.bridge.impl.RenderAction.acquire(RenderAction.java:151)
     * <p>
     * TODO: Investigate.
     */
    private static final boolean RENDER_ASYNC = false;

    /**
     * Height of the toolbar shown over a preview during hover. Needs to be
     * large enough to accommodate icons below.
     */
    private static final int HEADER_HEIGHT = 20;

    /** Whether to dump out rendering failures of the previews to the log */
    private static final boolean DUMP_RENDER_DIAGNOSTICS = false;

    /** Extra error checking in debug mode */
    private static final boolean DEBUG = false;

    private static final Image EDIT_ICON;
    private static final Image ZOOM_IN_ICON;
    private static final Image ZOOM_OUT_ICON;
    private static final Image CLOSE_ICON;
    private static final int EDIT_ICON_WIDTH;
    private static final int ZOOM_IN_ICON_WIDTH;
    private static final int ZOOM_OUT_ICON_WIDTH;
    private static final int CLOSE_ICON_WIDTH;
    static {
        ISharedImages sharedImages = PlatformUI.getWorkbench().getSharedImages();
        IconFactory icons = IconFactory.getInstance();
        CLOSE_ICON = sharedImages.getImage(ISharedImages.IMG_ETOOL_DELETE);
        EDIT_ICON = icons.getIcon("editPreview");   //$NON-NLS-1$
        ZOOM_IN_ICON = icons.getIcon("zoomplus");   //$NON-NLS-1$
        ZOOM_OUT_ICON = icons.getIcon("zoomminus"); //$NON-NLS-1$
        CLOSE_ICON_WIDTH = CLOSE_ICON.getImageData().width;
        EDIT_ICON_WIDTH = EDIT_ICON.getImageData().width;
        ZOOM_IN_ICON_WIDTH = ZOOM_IN_ICON.getImageData().width;
        ZOOM_OUT_ICON_WIDTH = ZOOM_OUT_ICON.getImageData().width;
    }

    /** The configuration being previewed */
    private @NonNull Configuration mConfiguration;

    /** Configuration to use if we have an alternate input to be rendered */
    private @NonNull Configuration mAlternateConfiguration;

    /** The associated manager */
    private final @NonNull RenderPreviewManager mManager;
    private final @NonNull LayoutCanvas mCanvas;

    private @NonNull SoftReference<ResourceResolver> mResourceResolver =
            new SoftReference<ResourceResolver>(null);
    private @Nullable Job mJob;
    private @Nullable Image mThumbnail;
    private @Nullable String mDisplayName;
    private int mWidth;
    private int mHeight;
    private int mX;
    private int mY;
    private int mTitleHeight;
    private double mScale = 1.0;
    private double mAspectRatio;

    /** If non null, points to a separate file containing the source */
    private @Nullable IFile mAlternateInput;

    /** If included within another layout, the name of that outer layout */
    private @Nullable Reference mIncludedWithin;

    /** Whether the mouse is actively hovering over this preview */
    private boolean mActive;

    /**
     * Whether this preview cannot be rendered because of a model error - such
     * as an invalid configuration, a missing resource, an error in the XML
     * markup, etc. If non null, contains the error message (or a blank string
     * if not known), and null if the render was successful.
     */
    private String mError;

    /** Whether in the current layout, this preview is visible */
    private boolean mVisible;

    /** Whether the configuration has changed and needs to be refreshed the next time
     * this preview made visible. This corresponds to the change flags in
     * {@link ConfigurationClient}. */
    private int mDirty;

    /**
     * Creates a new {@linkplain RenderPreview}
     *
     * @param manager the manager
     * @param canvas canvas where preview is painted
     * @param configuration the associated configuration
     * @param width the initial width to use for the preview
     * @param height the initial height to use for the preview
     */
    private RenderPreview(
            @NonNull RenderPreviewManager manager,
            @NonNull LayoutCanvas canvas,
            @NonNull Configuration configuration) {
        mManager = manager;
        mCanvas = canvas;
        mConfiguration = configuration;
        updateSize();

        // Should only attempt to create configurations for fully configured devices
        assert mConfiguration.getDevice() != null
                && mConfiguration.getDeviceState() != null
                && mConfiguration.getLocale() != null
                && mConfiguration.getTarget() != null
                && mConfiguration.getTheme() != null
                && mConfiguration.getFullConfig() != null
                && mConfiguration.getFullConfig().getScreenSizeQualifier() != null :
                    mConfiguration;
    }

    /**
     * Sets the configuration to use for this preview
     *
     * @param configuration the new configuration
     */
    public void setConfiguration(@NonNull Configuration configuration) {
        mConfiguration = configuration;
    }

    /**
     * Gets the scale being applied to the thumbnail
     *
     * @return the scale being applied to the thumbnail
     */
    public double getScale() {
        return mScale;
    }

    /**
     * Sets the scale to apply to the thumbnail
     *
     * @param scale the factor to scale the thumbnail picture by
     */
    public void setScale(double scale) {
        disposeThumbnail();
        mScale = scale;
    }

    /**
     * Returns the aspect ratio of this render preview
     *
     * @return the aspect ratio
     */
    public double getAspectRatio() {
        return mAspectRatio;
    }

    /**
     * Returns whether the preview is actively hovered
     *
     * @return whether the mouse is hovering over the preview
     */
    public boolean isActive() {
        return mActive;
    }

    /**
     * Sets whether the preview is actively hovered
     *
     * @param active if the mouse is hovering over the preview
     */
    public void setActive(boolean active) {
        mActive = active;
    }

    /**
     * Returns whether the preview is visible. Previews that are off
     * screen are typically marked invisible during layout, which means we don't
     * have to expend effort computing preview thumbnails etc
     *
     * @return true if the preview is visible
     */
    public boolean isVisible() {
        return mVisible;
    }

    /**
     * Returns whether this preview represents a forked layout
     *
     * @return true if this preview represents a separate file
     */
    public boolean isForked() {
        return mAlternateInput != null || mIncludedWithin != null;
    }

    /**
     * Returns the file to be used for this preview, or null if this is not a
     * forked layout meaning that the file is the one used in the chooser
     *
     * @return the file or null for non-forked layouts
     */
    @Nullable
    public IFile getAlternateInput() {
        if (mAlternateInput != null) {
            return mAlternateInput;
        } else if (mIncludedWithin != null) {
            return mIncludedWithin.getFile();
        }

        return null;
    }

    /**
     * Returns the area of this render preview, PRIOR to scaling
     *
     * @return the area (width times height without scaling)
     */
    int getArea() {
        return mWidth * mHeight;
    }

    /**
     * Sets whether the preview is visible. Previews that are off
     * screen are typically marked invisible during layout, which means we don't
     * have to expend effort computing preview thumbnails etc
     *
     * @param visible whether this preview is visible
     */
    public void setVisible(boolean visible) {
        if (visible != mVisible) {
            mVisible = visible;
            if (mVisible) {
                if (mDirty != 0) {
                    // Just made the render preview visible:
                    configurationChanged(mDirty); // schedules render
                } else {
                    updateForkStatus();
                    mManager.scheduleRender(this);
                }
            } else {
                dispose();
            }
        }
    }

    /**
     * Sets the layout position relative to the top left corner of the preview
     * area, in control coordinates
     */
    void setPosition(int x, int y) {
        mX = x;
        mY = y;
    }

    /**
     * Gets the layout X position relative to the top left corner of the preview
     * area, in control coordinates
     */
    int getX() {
        return mX;
    }

    /**
     * Gets the layout Y position relative to the top left corner of the preview
     * area, in control coordinates
     */
    int getY() {
        return mY;
    }

    /** Determine whether this configuration has a better match in a different layout file */
    private void updateForkStatus() {
        ConfigurationChooser chooser = mManager.getChooser();
        FolderConfiguration config = mConfiguration.getFullConfig();
        if (mAlternateInput != null && chooser.isBestMatchFor(mAlternateInput, config)) {
            return;
        }

        mAlternateInput = null;
        IFile editedFile = chooser.getEditedFile();
        if (editedFile != null) {
            if (!chooser.isBestMatchFor(editedFile, config)) {
                ProjectResources resources = chooser.getResources();
                if (resources != null) {
                    ResourceFile best = resources.getMatchingFile(editedFile.getName(),
                            ResourceType.LAYOUT, config);
                    if (best != null) {
                        IAbstractFile file = best.getFile();
                        if (file instanceof IFileWrapper) {
                            mAlternateInput = ((IFileWrapper) file).getIFile();
                        } else if (file instanceof File) {
                            mAlternateInput = AdtUtils.fileToIFile(((File) file));
                        }
                    }
                }
                if (mAlternateInput != null) {
                    mAlternateConfiguration = Configuration.create(mConfiguration,
                            mAlternateInput);
                }
            }
        }
    }

    /**
     * Creates a new {@linkplain RenderPreview}
     *
     * @param manager the manager
     * @param configuration the associated configuration
     * @return a new configuration
     */
    @NonNull
    public static RenderPreview create(
            @NonNull RenderPreviewManager manager,
            @NonNull Configuration configuration) {
        LayoutCanvas canvas = manager.getCanvas();
        return new RenderPreview(manager, canvas, configuration);
    }

    /**
     * Throws away this preview: cancels any pending rendering jobs and disposes
     * of image resources etc
     */
    public void dispose() {
        disposeThumbnail();

        if (mJob != null) {
            mJob.cancel();
            mJob = null;
        }
    }

    /** Disposes the thumbnail rendering. */
    void disposeThumbnail() {
        if (mThumbnail != null) {
            mThumbnail.dispose();
            mThumbnail = null;
        }
    }

    /**
     * Returns the display name of this preview
     *
     * @return the name of the preview
     */
    @NonNull
    public String getDisplayName() {
        if (mDisplayName == null) {
            String displayName = getConfiguration().getDisplayName();
            if (displayName == null) {
                // No display name: this must be the configuration used by default
                // for the view which is originally displayed (before adding thumbnails),
                // and you've switched away to something else; now we need to display a name
                // for this original configuration. For now, just call it "Original"
                return "Original";
            }

            return displayName;
        }

        return mDisplayName;
    }

    /**
     * Sets the display name of this preview. By default, the display name is
     * the display name of the configuration, but it can be overridden by calling
     * this setter (which only sets the preview name, without editing the configuration.)
     *
     * @param displayName the new display name
     */
    public void setDisplayName(@NonNull String displayName) {
        mDisplayName = displayName;
    }

    /**
     * Sets an inclusion context to use for this layout, if any. This will render
     * the configuration preview as the outer layout with the current layout
     * embedded within.
     *
     * @param includedWithin a reference to a layout which includes this one
     */
    public void setIncludedWithin(Reference includedWithin) {
        mIncludedWithin = includedWithin;
    }

    /**
     * Request a new render after the given delay
     *
     * @param delay the delay to wait before starting the render job
     */
    public void render(long delay) {
        Job job = mJob;
        if (job != null) {
            job.cancel();
        }
        if (RENDER_ASYNC) {
            job = new AsyncRenderJob();
        } else {
            job = new RenderJob();
        }
        job.schedule(delay);
        job.addJobChangeListener(this);
        mJob = job;
    }

    /** Render immediately */
    private void renderSync() {
        GraphicalEditorPart editor = mCanvas.getEditorDelegate().getGraphicalEditor();
        if (editor.getReadyLayoutLib(false /*displayError*/) == null) {
            // Don't attempt to render when there is no ready layout library: most likely
            // the targets are loading/reloading.
            return;
        }

        disposeThumbnail();

        Configuration configuration =
                mAlternateInput != null && mAlternateConfiguration != null
                ? mAlternateConfiguration : mConfiguration;
        ResourceResolver resolver = getResourceResolver(configuration);
        RenderService renderService = RenderService.create(editor, configuration, resolver);

        if (mIncludedWithin != null) {
            renderService.setIncludedWithin(mIncludedWithin);
        }

        if (mAlternateInput != null) {
            IAndroidTarget target = editor.getRenderingTarget();
            AndroidTargetData data = null;
            if (target != null) {
                Sdk sdk = Sdk.getCurrent();
                if (sdk != null) {
                    data = sdk.getTargetData(target);
                }
            }

            // Construct UI model from XML
            DocumentDescriptor documentDescriptor;
            if (data == null) {
                documentDescriptor = new DocumentDescriptor("temp", null);//$NON-NLS-1$
            } else {
                documentDescriptor = data.getLayoutDescriptors().getDescriptor();
            }
            UiDocumentNode model = (UiDocumentNode) documentDescriptor.createUiNode();
            model.setEditor(mCanvas.getEditorDelegate().getEditor());
            model.setUnknownDescriptorProvider(editor.getModel().getUnknownDescriptorProvider());

            Document document = DomUtilities.getDocument(mAlternateInput);
            if (document == null) {
                mError = "No document";
                createErrorThumbnail();
                return;
            }
            model.loadFromXmlNode(document);
            renderService.setModel(model);
        } else {
            renderService.setModel(editor.getModel());
        }
        RenderLogger log = editor.createRenderLogger(getDisplayName());
        renderService.setLog(log);
        RenderSession session = renderService.createRenderSession();
        Result render = session.render(1000);

        if (DUMP_RENDER_DIAGNOSTICS) {
            if (log.hasProblems() || !render.isSuccess()) {
                AdtPlugin.log(IStatus.ERROR, "Found problems rendering preview "
                        + getDisplayName() + ": "
                        + render.getErrorMessage() + " : "
                        + log.getProblems(false));
                Throwable exception = render.getException();
                if (exception != null) {
                    AdtPlugin.log(exception, "Failure rendering preview " + getDisplayName());
                }
            }
        }

        if (render.isSuccess()) {
            mError = null;
        } else {
            mError = render.getErrorMessage();
            if (mError == null) {
                mError = "";
            }
        }

        if (render.getStatus() == Status.ERROR_TIMEOUT) {
            // TODO: Special handling? schedule update again later
            return;
        }
        if (render.isSuccess()) {
            BufferedImage image = session.getImage();
            if (image != null) {
                createThumbnail(image);
            }
        }

        if (mError != null) {
            createErrorThumbnail();
        }
    }

    private ResourceResolver getResourceResolver(Configuration configuration) {
        ResourceResolver resourceResolver = mResourceResolver.get();
        if (resourceResolver != null) {
            return resourceResolver;
        }

        GraphicalEditorPart graphicalEditor = mCanvas.getEditorDelegate().getGraphicalEditor();
        String theme = configuration.getTheme();
        if (theme == null) {
            return null;
        }

        Map<ResourceType, Map<String, ResourceValue>> configuredFrameworkRes = null;
        Map<ResourceType, Map<String, ResourceValue>> configuredProjectRes = null;

        FolderConfiguration config = configuration.getFullConfig();
        IAndroidTarget target = graphicalEditor.getRenderingTarget();
        ResourceRepository frameworkRes = null;
        if (target != null) {
            Sdk sdk = Sdk.getCurrent();
            if (sdk == null) {
                return null;
            }
            AndroidTargetData data = sdk.getTargetData(target);

            if (data != null) {
                // TODO: SHARE if possible
                frameworkRes = data.getFrameworkResources();
                configuredFrameworkRes = frameworkRes.getConfiguredResources(config);
            } else {
                return null;
            }
        } else {
            return null;
        }
        assert configuredFrameworkRes != null;


        // get the resources of the file's project.
        ProjectResources projectRes = ResourceManager.getInstance().getProjectResources(
                graphicalEditor.getProject());
        configuredProjectRes = projectRes.getConfiguredResources(config);

        if (!theme.startsWith(PREFIX_RESOURCE_REF)) {
            if (frameworkRes.hasResourceItem(ANDROID_STYLE_RESOURCE_PREFIX + theme)) {
                theme = ANDROID_STYLE_RESOURCE_PREFIX + theme;
            } else {
                theme = STYLE_RESOURCE_PREFIX + theme;
            }
        }

        resourceResolver = ResourceResolver.create(
                configuredProjectRes, configuredFrameworkRes,
                ResourceHelper.styleToTheme(theme),
                ResourceHelper.isProjectStyle(theme));
        mResourceResolver = new SoftReference<ResourceResolver>(resourceResolver);
        return resourceResolver;
    }

    /**
     * Sets the new image of the preview and generates a thumbnail
     *
     * @param image the full size image
     */
    void createThumbnail(BufferedImage image) {
        if (image == null) {
            mThumbnail = null;
            return;
        }

        ImageOverlay imageOverlay = mCanvas.getImageOverlay();
        boolean drawShadows = imageOverlay == null || imageOverlay.getShowDropShadow();
        double scale = getWidth() / (double) image.getWidth();
        int shadowSize;
        if (LARGE_SHADOWS) {
            shadowSize = drawShadows ? SHADOW_SIZE : 0;
        } else {
            shadowSize = drawShadows ? SMALL_SHADOW_SIZE : 0;
        }
        if (scale < 1.0) {
            if (LARGE_SHADOWS) {
                image = ImageUtils.scale(image, scale, scale,
                        shadowSize, shadowSize);
                if (drawShadows) {
                    ImageUtils.drawRectangleShadow(image, 0, 0,
                            image.getWidth() - shadowSize,
                            image.getHeight() - shadowSize);
                }
            } else {
                image = ImageUtils.scale(image, scale, scale,
                        shadowSize, shadowSize);
                if (drawShadows) {
                    ImageUtils.drawSmallRectangleShadow(image, 0, 0,
                            image.getWidth() - shadowSize,
                            image.getHeight() - shadowSize);
                }
            }
        }

        mThumbnail = SwtUtils.convertToSwt(mCanvas.getDisplay(), image,
                true /* transferAlpha */, -1);
    }

    void createErrorThumbnail() {
        int shadowSize = LARGE_SHADOWS ? SHADOW_SIZE : SMALL_SHADOW_SIZE;
        int width = getWidth();
        int height = getHeight();
        BufferedImage image = new BufferedImage(width + shadowSize, height + shadowSize,
                BufferedImage.TYPE_INT_ARGB);

        Graphics2D g = image.createGraphics();
        g.setColor(new java.awt.Color(0xfffbfcc6));
        g.fillRect(0, 0, width, height);

        g.dispose();

        ImageOverlay imageOverlay = mCanvas.getImageOverlay();
        boolean drawShadows = imageOverlay == null || imageOverlay.getShowDropShadow();
        if (drawShadows) {
            if (LARGE_SHADOWS) {
                ImageUtils.drawRectangleShadow(image, 0, 0,
                        image.getWidth() - SHADOW_SIZE,
                        image.getHeight() - SHADOW_SIZE);
            } else {
                ImageUtils.drawSmallRectangleShadow(image, 0, 0,
                        image.getWidth() - SMALL_SHADOW_SIZE,
                        image.getHeight() - SMALL_SHADOW_SIZE);
            }
        }

        mThumbnail = SwtUtils.convertToSwt(mCanvas.getDisplay(), image,
                true /* transferAlpha */, -1);
    }

    private static double getScale(int width, int height) {
        int maxWidth = RenderPreviewManager.getMaxWidth();
        int maxHeight = RenderPreviewManager.getMaxHeight();
        if (width > 0 && height > 0
                && (width > maxWidth || height > maxHeight)) {
            if (width >= height) { // landscape
                return maxWidth / (double) width;
            } else { // portrait
                return maxHeight / (double) height;
            }
        }

        return 1.0;
    }

    /**
     * Returns the width of the preview, in pixels
     *
     * @return the width in pixels
     */
    public int getWidth() {
        return (int) (mWidth * mScale * RenderPreviewManager.getScale());
    }

    /**
     * Returns the height of the preview, in pixels
     *
     * @return the height in pixels
     */
    public int getHeight() {
        return (int) (mHeight * mScale * RenderPreviewManager.getScale());
    }

    /**
     * Handles clicks within the preview (x and y are positions relative within the
     * preview
     *
     * @param x the x coordinate within the preview where the click occurred
     * @param y the y coordinate within the preview where the click occurred
     * @return true if this preview handled (and therefore consumed) the click
     */
    public boolean click(int x, int y) {
        if (y >= mTitleHeight && y < mTitleHeight + HEADER_HEIGHT) {
            int left = 0;
            left += CLOSE_ICON_WIDTH;
            if (x <= left) {
                // Delete
                mManager.deletePreview(this);
                return true;
            }
            left += ZOOM_IN_ICON_WIDTH;
            if (x <= left) {
                // Zoom in
                mScale = mScale * (1 / 0.5);
                if (Math.abs(mScale-1.0) < 0.0001) {
                    mScale = 1.0;
                }

                render(0);
                mManager.layout(true);
                mCanvas.redraw();
                return true;
            }
            left += ZOOM_OUT_ICON_WIDTH;
            if (x <= left) {
                // Zoom out
                mScale = mScale * (0.5 / 1);
                if (Math.abs(mScale-1.0) < 0.0001) {
                    mScale = 1.0;
                }
                render(0);

                mManager.layout(true);
                mCanvas.redraw();
                return true;
            }
            left += EDIT_ICON_WIDTH;
            if (x <= left) {
                // Edit. For now, just rename
                InputDialog d = new InputDialog(
                        AdtPlugin.getShell(),
                        "Rename Preview",  // title
                        "Name:",
                        getDisplayName(),
                        null);
                if (d.open() == Window.OK) {
                    String newName = d.getValue();
                    mConfiguration.setDisplayName(newName);
                    if (mDescription != null) {
                        mManager.rename(mDescription, newName);
                    }
                    mCanvas.redraw();
                }

                return true;
            }

            // Clicked anywhere else on header
            // Perhaps open Edit dialog here?
        }

        mManager.switchTo(this);
        return true;
    }

    /**
     * Paints the preview at the given x/y position
     *
     * @param gc the graphics context to paint it into
     * @param x the x coordinate to paint the preview at
     * @param y the y coordinate to paint the preview at
     */
    void paint(GC gc, int x, int y) {
        mTitleHeight = paintTitle(gc, x, y, true /*showFile*/);
        y += mTitleHeight;
        y += 2;

        int width = getWidth();
        int height = getHeight();
        if (mThumbnail != null && mError == null) {
            gc.drawImage(mThumbnail, x, y);

            if (mActive) {
                int oldWidth = gc.getLineWidth();
                gc.setLineWidth(3);
                gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_LIST_SELECTION));
                gc.drawRectangle(x - 1, y - 1, width + 2, height + 2);
                gc.setLineWidth(oldWidth);
            }
        } else if (mError != null) {
            if (mThumbnail != null) {
                gc.drawImage(mThumbnail, x, y);
            } else {
                gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_WIDGET_BORDER));
                gc.drawRectangle(x, y, width, height);
            }

            gc.setClipping(x, y, width, height);
            Image icon = IconFactory.getInstance().getIcon("renderError"); //$NON-NLS-1$
            ImageData data = icon.getImageData();
            int prevAlpha = gc.getAlpha();
            int alpha = 96;
            if (mThumbnail != null) {
                alpha -= 32;
            }
            gc.setAlpha(alpha);
            gc.drawImage(icon, x + (width - data.width) / 2, y + (height - data.height) / 2);

            String msg = mError;
            Density density = mConfiguration.getDensity();
            if (density == Density.TV || density == Density.LOW) {
                msg = "Broken rendering library; unsupported DPI. Try using the SDK manager " +
                        "to get updated layout libraries.";
            }
            int charWidth = gc.getFontMetrics().getAverageCharWidth();
            int charsPerLine = (width - 10) / charWidth;
            msg = SdkUtils.wrap(msg, charsPerLine, null);
            gc.setAlpha(255);
            gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_BLACK));
            gc.drawText(msg, x + 5, y + HEADER_HEIGHT, true);
            gc.setAlpha(prevAlpha);
            gc.setClipping((Region) null);
        } else {
            gc.setBackground(gc.getDevice().getSystemColor(SWT.COLOR_WIDGET_BORDER));
            gc.drawRectangle(x, y, width, height);

            Image icon = IconFactory.getInstance().getIcon("refreshPreview"); //$NON-NLS-1$
            ImageData data = icon.getImageData();
            int prevAlpha = gc.getAlpha();
            gc.setAlpha(96);
            gc.drawImage(icon, x + (width - data.width) / 2,
                    y + (height - data.height) / 2);
            gc.setAlpha(prevAlpha);
        }

        if (mActive) {
            int left = x ;
            int prevAlpha = gc.getAlpha();
            gc.setAlpha(208);
            Color bg = mCanvas.getDisplay().getSystemColor(SWT.COLOR_WHITE);
            gc.setBackground(bg);
            gc.fillRectangle(left, y, x + width - left, HEADER_HEIGHT);
            gc.setAlpha(prevAlpha);

            y += 2;

            // Paint icons
            gc.drawImage(CLOSE_ICON, left, y);
            left += CLOSE_ICON_WIDTH;

            gc.drawImage(ZOOM_IN_ICON, left, y);
            left += ZOOM_IN_ICON_WIDTH;

            gc.drawImage(ZOOM_OUT_ICON, left, y);
            left += ZOOM_OUT_ICON_WIDTH;

            gc.drawImage(EDIT_ICON, left, y);
            left += EDIT_ICON_WIDTH;
        }
    }

    /**
     * Paints the preview title at the given position (and returns the required
     * height)
     *
     * @param gc the graphics context to paint into
     * @param x the left edge of the preview rectangle
     * @param y the top edge of the preview rectangle
     */
    private int paintTitle(GC gc, int x, int y, boolean showFile) {
        String displayName = getDisplayName();
        return paintTitle(gc, x, y, showFile, displayName);
    }

    /**
     * Paints the preview title at the given position (and returns the required
     * height)
     *
     * @param gc the graphics context to paint into
     * @param x the left edge of the preview rectangle
     * @param y the top edge of the preview rectangle
     * @param displayName the title string to be used
     */
    int paintTitle(GC gc, int x, int y, boolean showFile, String displayName) {
        int titleHeight = 0;

        if (showFile && mIncludedWithin != null) {
            if (mManager.getMode() != INCLUDES) {
                displayName = "<include>";
            } else {
                // Skip: just paint footer instead
                displayName = null;
            }
        }

        int width = getWidth();
        int labelTop = y + 1;
        gc.setClipping(x, labelTop, width, 100);

        // Use font height rather than extent height since we want two adjacent
        // previews (which may have different display names and therefore end
        // up with slightly different extent heights) to have identical title
        // heights such that they are aligned identically
        int fontHeight = gc.getFontMetrics().getHeight();

        if (displayName != null && displayName.length() > 0) {
            gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
            Point extent = gc.textExtent(displayName);
            int labelLeft = Math.max(x, x + (width - extent.x) / 2);
            Image icon = null;
            Locale locale = mConfiguration.getLocale();
            if (locale != null && (locale.hasLanguage() || locale.hasRegion())
                    && (!(mConfiguration instanceof NestedConfiguration)
                            || ((NestedConfiguration) mConfiguration).isOverridingLocale())) {
                icon = locale.getFlagImage();
            }

            if (icon != null) {
                int flagWidth = icon.getImageData().width;
                int flagHeight = icon.getImageData().height;
                labelLeft = Math.max(x + flagWidth / 2, labelLeft);
                gc.drawImage(icon, labelLeft - flagWidth / 2 - 1, labelTop);
                labelLeft += flagWidth / 2 + 1;
                gc.drawText(displayName, labelLeft,
                        labelTop - (extent.y - flagHeight) / 2, true);
            } else {
                gc.drawText(displayName, labelLeft, labelTop, true);
            }

            labelTop += extent.y;
            titleHeight += fontHeight;
        }

        if (showFile && (mAlternateInput != null || mIncludedWithin != null)) {
            // Draw file flag, and parent folder name
            IFile file = mAlternateInput != null
                    ? mAlternateInput : mIncludedWithin.getFile();
            String fileName = file.getParent().getName() + File.separator
                    + file.getName();
            Point extent = gc.textExtent(fileName);
            Image icon = IconFactory.getInstance().getIcon("android_file"); //$NON-NLS-1$
            int flagWidth = icon.getImageData().width;
            int flagHeight = icon.getImageData().height;

            int labelLeft = Math.max(x, x + (width - extent.x - flagWidth - 1) / 2);

            gc.drawImage(icon, labelLeft, labelTop);

            gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_GRAY));
            labelLeft += flagWidth + 1;
            labelTop -= (extent.y - flagHeight) / 2;
            gc.drawText(fileName, labelLeft, labelTop, true);

            titleHeight += Math.max(titleHeight, icon.getImageData().height);
        }

        gc.setClipping((Region) null);

        return titleHeight;
    }

    /**
     * Notifies that the preview's configuration has changed.
     *
     * @param flags the change flags, a bitmask corresponding to the
     *            {@code CHANGE_} constants in {@link ConfigurationClient}
     */
    public void configurationChanged(int flags) {
        if (!mVisible) {
            mDirty |= flags;
            return;
        }

        if ((flags & MASK_RENDERING) != 0) {
            mResourceResolver.clear();
            // Handle inheritance
            mConfiguration.syncFolderConfig();
            updateForkStatus();
            updateSize();
        }

        // Sanity check to make sure things are working correctly
        if (DEBUG) {
            RenderPreviewMode mode = mManager.getMode();
            if (mode == DEFAULT) {
                assert mConfiguration instanceof VaryingConfiguration;
                VaryingConfiguration config = (VaryingConfiguration) mConfiguration;
                int alternateFlags = config.getAlternateFlags();
                switch (alternateFlags) {
                    case Configuration.CFG_DEVICE_STATE: {
                        State configState = config.getDeviceState();
                        State chooserState = mManager.getChooser().getConfiguration()
                                .getDeviceState();
                        assert configState != null && chooserState != null;
                        assert !configState.getName().equals(chooserState.getName())
                                : configState.toString() + ':' + chooserState;

                        Device configDevice = config.getDevice();
                        Device chooserDevice = mManager.getChooser().getConfiguration()
                                .getDevice();
                        assert configDevice != null && chooserDevice != null;
                        assert configDevice == chooserDevice
                                : configDevice.toString() + ':' + chooserDevice;

                        break;
                    }
                    case Configuration.CFG_DEVICE: {
                        Device configDevice = config.getDevice();
                        Device chooserDevice = mManager.getChooser().getConfiguration()
                                .getDevice();
                        assert configDevice != null && chooserDevice != null;
                        assert configDevice != chooserDevice
                                : configDevice.toString() + ':' + chooserDevice;

                        State configState = config.getDeviceState();
                        State chooserState = mManager.getChooser().getConfiguration()
                                .getDeviceState();
                        assert configState != null && chooserState != null;
                        assert configState.getName().equals(chooserState.getName())
                                : configState.toString() + ':' + chooserState;

                        break;
                    }
                    case Configuration.CFG_LOCALE: {
                        Locale configLocale = config.getLocale();
                        Locale chooserLocale = mManager.getChooser().getConfiguration()
                                .getLocale();
                        assert configLocale != null && chooserLocale != null;
                        assert configLocale != chooserLocale
                                : configLocale.toString() + ':' + chooserLocale;
                        break;
                    }
                    default: {
                        // Some other type of override I didn't anticipate
                        assert false : alternateFlags;
                    }
                }
            }
        }

        mDirty = 0;
        mManager.scheduleRender(this);
    }

    private void updateSize() {
        Device device = mConfiguration.getDevice();
        if (device == null) {
            return;
        }
        Screen screen = device.getDefaultHardware().getScreen();
        if (screen == null) {
            return;
        }

        FolderConfiguration folderConfig = mConfiguration.getFullConfig();
        ScreenOrientationQualifier qualifier = folderConfig.getScreenOrientationQualifier();
        ScreenOrientation orientation = qualifier == null
                ? ScreenOrientation.PORTRAIT : qualifier.getValue();

        // compute width and height to take orientation into account.
        int x = screen.getXDimension();
        int y = screen.getYDimension();
        int screenWidth, screenHeight;

        if (x > y) {
            if (orientation == ScreenOrientation.LANDSCAPE) {
                screenWidth = x;
                screenHeight = y;
            } else {
                screenWidth = y;
                screenHeight = x;
            }
        } else {
            if (orientation == ScreenOrientation.LANDSCAPE) {
                screenWidth = y;
                screenHeight = x;
            } else {
                screenWidth = x;
                screenHeight = y;
            }
        }

        int width = RenderPreviewManager.getMaxWidth();
        int height = RenderPreviewManager.getMaxHeight();
        if (screenWidth > 0) {
            double scale = getScale(screenWidth, screenHeight);
            width = (int) (screenWidth * scale);
            height = (int) (screenHeight * scale);
        }

        if (width != mWidth || height != mHeight) {
            mWidth = width;
            mHeight = height;

            Image thumbnail = mThumbnail;
            mThumbnail = null;
            if (thumbnail != null) {
                thumbnail.dispose();
            }
            if (mHeight != 0) {
                mAspectRatio = mWidth / (double) mHeight;
            }
        }
    }

    /**
     * Returns the configuration associated with this preview
     *
     * @return the configuration
     */
    @NonNull
    public Configuration getConfiguration() {
        return mConfiguration;
    }

    // ---- Implements IJobChangeListener ----

    @Override
    public void aboutToRun(IJobChangeEvent event) {
    }

    @Override
    public void awake(IJobChangeEvent event) {
    }

    @Override
    public void done(IJobChangeEvent event) {
        mJob = null;
    }

    @Override
    public void running(IJobChangeEvent event) {
    }

    @Override
    public void scheduled(IJobChangeEvent event) {
    }

    @Override
    public void sleeping(IJobChangeEvent event) {
    }

    // ---- Delayed Rendering ----

    private final class RenderJob extends UIJob {
        public RenderJob() {
            super("RenderPreview");
            setSystem(true);
            setUser(false);
        }

        @Override
        public IStatus runInUIThread(IProgressMonitor monitor) {
            mJob = null;
            if (!mCanvas.isDisposed()) {
                renderSync();
                mCanvas.redraw();
                return org.eclipse.core.runtime.Status.OK_STATUS;
            }

            return org.eclipse.core.runtime.Status.CANCEL_STATUS;
        }

        @Override
        public Display getDisplay() {
            if (mCanvas.isDisposed()) {
                return null;
            }
            return mCanvas.getDisplay();
        }
    }

    private final class AsyncRenderJob extends Job {
        public AsyncRenderJob() {
            super("RenderPreview");
            setSystem(true);
            setUser(false);
        }

        @Override
        protected IStatus run(IProgressMonitor monitor) {
            mJob = null;

            if (mCanvas.isDisposed()) {
                return org.eclipse.core.runtime.Status.CANCEL_STATUS;
            }

            renderSync();

            // Update display
            mCanvas.getDisplay().asyncExec(new Runnable() {
                @Override
                public void run() {
                    mCanvas.redraw();
                }
            });

            return org.eclipse.core.runtime.Status.OK_STATUS;
        }
    }

    /**
     * Sets the input file to use for rendering. If not set, this will just be
     * the same file as the configuration chooser. This is used to render other
     * layouts, such as variations of the currently edited layout, which are
     * not kept in sync with the main layout.
     *
     * @param file the file to set as input
     */
    public void setAlternateInput(@Nullable IFile file) {
        mAlternateInput = file;
    }

    /** Corresponding description for this preview if it is a manually added preview */
    private @Nullable ConfigurationDescription mDescription;

    /**
     * Sets the description of this preview, if this preview is a manually added preview
     *
     * @param description the description of this preview
     */
    public void setDescription(@Nullable ConfigurationDescription description) {
        mDescription = description;
    }

    /**
     * Returns the description of this preview, if this preview is a manually added preview
     *
     * @return the description
     */
    @Nullable
    public ConfigurationDescription getDescription() {
        return mDescription;
    }

    @Override
    public String toString() {
        return getDisplayName() + ':' + mConfiguration;
    }

    /** Sorts render previews into increasing aspect ratio order */
    static Comparator<RenderPreview> INCREASING_ASPECT_RATIO = new Comparator<RenderPreview>() {
        @Override
        public int compare(RenderPreview preview1, RenderPreview preview2) {
            return (int) Math.signum(preview1.mAspectRatio - preview2.mAspectRatio);
        }
    };
    /** Sorts render previews into visual order: row by row, column by column */
    static Comparator<RenderPreview> VISUAL_ORDER = new Comparator<RenderPreview>() {
        @Override
        public int compare(RenderPreview preview1, RenderPreview preview2) {
            int delta = preview1.mY - preview2.mY;
            if (delta == 0) {
                delta = preview1.mX - preview2.mX;
            }
            return delta;
        }
    };
}
