/*
 * Copyright (C) 2009 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.ide.eclipse.adt.internal.editors.layout.gle2.ImageUtils.SHADOW_SIZE;

import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.ScrollBar;

/**
 * Helper class to convert between control pixel coordinates and canvas coordinates.
 * Takes care of the zooming and offset of the canvas.
 */
public class CanvasTransform {
    /**
     * Default margin around the rendered image, reduced
     * when the contents do not fit.
     */
    public static final int DEFAULT_MARGIN = 25;

    /**
     * The canvas which controls the zooming.
     */
    private final LayoutCanvas mCanvas;

    /** Canvas image size (original, before zoom), in pixels. */
    private int mImgSize;

    /** Full size being scrolled (after zoom), in pixels */
    private int mFullSize;;

    /** Client size, in pixels. */
    private int mClientSize;

    /** Left-top offset in client pixel coordinates. */
    private int mTranslate;

    /** Current margin */
    private int mMargin = DEFAULT_MARGIN;

    /** Scaling factor, > 0. */
    private double mScale;

    /** Scrollbar widget. */
    private ScrollBar mScrollbar;

    public CanvasTransform(LayoutCanvas layoutCanvas, ScrollBar scrollbar) {
        mCanvas = layoutCanvas;
        mScrollbar = scrollbar;
        mScale = 1.0;
        mTranslate = 0;

        mScrollbar.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                // User requested scrolling. Changes translation and redraw canvas.
                mTranslate = mScrollbar.getSelection();
                CanvasTransform.this.mCanvas.redraw();
            }
        });
        mScrollbar.setIncrement(20);
    }

    /**
     * Sets the new scaling factor. Recomputes scrollbars.
     * @param scale Scaling factor, > 0.
     */
    public void setScale(double scale) {
        if (mScale != scale) {
            mScale = scale;
            resizeScrollbar();
        }
    }

    /** Recomputes the scrollbar and view port settings */
    public void refresh() {
        resizeScrollbar();
    }

    /**
     * Returns current scaling factor.
     *
     * @return The current scaling factor
     */
    public double getScale() {
        return mScale;
    }

    /**
     * Returns Canvas image size (original, before zoom), in pixels.
     *
     * @return Canvas image size (original, before zoom), in pixels
     */
    public int getImgSize() {
        return mImgSize;
    }

    /**
     * Returns the scaled image size in pixels.
     *
     * @return The scaled image size in pixels.
     */
    public int getScaledImgSize() {
        return (int) (mImgSize * mScale);
    }

    /**
     * Changes the size of the canvas image and the client size. Recomputes
     * scrollbars.
     *
     * @param imgSize the size of the image being scaled
     * @param fullSize the size of the full view area being scrolled
     * @param clientSize the size of the view port
     */
    public void setSize(int imgSize, int fullSize, int clientSize) {
        mImgSize = imgSize;
        mFullSize = fullSize;
        mClientSize = clientSize;
        mScrollbar.setPageIncrement(clientSize);
        resizeScrollbar();
    }

    private void resizeScrollbar() {
        // scaled image size
        int sx = (int) (mScale * mFullSize);

        // Adjust margin such that for zoomed out views
        // we don't waste space (unless the viewport is
        // large enough to accommodate it)
        int delta = mClientSize - sx;
        if (delta < 0) {
            mMargin = 0;
        } else if (delta < 2 * DEFAULT_MARGIN) {
            mMargin = delta / 2;

            ImageOverlay imageOverlay = mCanvas.getImageOverlay();
            if (imageOverlay != null && imageOverlay.getShowDropShadow()
                    && delta >= SHADOW_SIZE / 2) {
                mMargin -= SHADOW_SIZE / 2;
                // Add a little padding on the top too, if there's room. The shadow assets
                // include enough padding on the bottom to not make this look clipped.
                if (mMargin < 4) {
                    mMargin += 4;
                }
            }
        } else {
            mMargin = DEFAULT_MARGIN;
        }

        if (mCanvas.getPreviewManager().hasPreviews()) {
            // Make more room for the previews
            mMargin = 2;
        }

        // actual client area is always reduced by the margins
        int cx = mClientSize - 2 * mMargin;

        if (sx < cx) {
            mTranslate = 0;
            mScrollbar.setEnabled(false);
        } else {
            mScrollbar.setEnabled(true);

            int selection = mScrollbar.getSelection();
            int thumb = cx;
            int maximum = sx;

            if (selection + thumb > maximum) {
                selection = maximum - thumb;
                if (selection < 0) {
                    selection = 0;
                }
            }

            mScrollbar.setValues(selection, mScrollbar.getMinimum(), maximum, thumb, mScrollbar
                    .getIncrement(), mScrollbar.getPageIncrement());

            mTranslate = selection;
        }
    }

    public int getMargin() {
        return mMargin;
    }

    public int translate(int canvasX) {
        return mMargin - mTranslate + (int) (mScale * canvasX);
    }

    public int scale(int canwasW) {
        return (int) (mScale * canwasW);
    }

    public int inverseTranslate(int screenX) {
        return (int) ((screenX - mMargin + mTranslate) / mScale);
    }

    public int inverseScale(int canwasW) {
        return (int) (canwasW / mScale);
    }
}
