/*
 * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */
package com.sun.hotspot.igv.view;

import java.awt.Container;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.JComponent;
import javax.swing.JScrollPane;
import org.netbeans.api.visual.action.WidgetAction;
import org.netbeans.api.visual.action.WidgetAction.State;
import org.netbeans.api.visual.action.WidgetAction.WidgetMouseWheelEvent;
import org.netbeans.api.visual.animator.SceneAnimator;
import org.netbeans.api.visual.widget.Scene;
import org.netbeans.api.visual.widget.Widget;

/**
 *
 * @author Thomas Wuerthinger
 */
public class BoundedZoomAction extends WidgetAction.Adapter {

    private double minFactor = 0.0;
    private double maxFactor = Double.MAX_VALUE;
    private double zoomMultiplier;
    private boolean useAnimator;

    public BoundedZoomAction(double zoomMultiplier, boolean useAnimator) {
        assert zoomMultiplier > 1.0;
        this.zoomMultiplier = zoomMultiplier;
        this.useAnimator = useAnimator;
    }

    public double getMinFactor() {
        return minFactor;
    }

    public void setMinFactor(double d) {
        minFactor = d;
    }

    public double getMaxFactor() {
        return maxFactor;
    }

    public void setMaxFactor(double d) {
        maxFactor = d;
    }

    private JScrollPane findScrollPane(JComponent component) {
        for (;;) {
            if (component == null) {
                return null;
            }
            if (component instanceof JScrollPane) {
                return ((JScrollPane) component);
            }
            Container parent = component.getParent();
            if (!(parent instanceof JComponent)) {
                return null;
            }
            component = (JComponent) parent;
        }
    }

    @Override
    public State mouseWheelMoved(Widget widget, WidgetMouseWheelEvent event) {
        final Scene scene = widget.getScene();
        int amount = event.getWheelRotation();
        JScrollPane scrollPane = findScrollPane(scene.getView());
        Point viewPosition = null;
        Point mouseLocation = scene.convertSceneToView(event.getPoint());
        int xOffset = 0;
        int yOffset = 0;
        Rectangle bounds = new Rectangle(scene.getBounds());
        Dimension componentSize = new Dimension(scene.getView().getPreferredSize());
        if (scrollPane != null) {
            viewPosition = new Point(scrollPane.getViewport().getViewPosition());
            xOffset = (mouseLocation.x - viewPosition.x);
            yOffset = (mouseLocation.y - viewPosition.y);
            viewPosition.x += xOffset;
            viewPosition.y += yOffset;
        }

        if (useAnimator) {
            SceneAnimator sceneAnimator = scene.getSceneAnimator();
            synchronized (sceneAnimator) {
                double zoom = sceneAnimator.isAnimatingZoomFactor() ? sceneAnimator.getTargetZoomFactor() : scene.getZoomFactor();
                while (amount > 0 && zoom / zoomMultiplier >= minFactor) {
                    zoom /= zoomMultiplier;
                    if (viewPosition != null) {
                        viewPosition.x /= zoomMultiplier;
                        viewPosition.y /= zoomMultiplier;
                        bounds.width /= zoomMultiplier;
                        bounds.height /= zoomMultiplier;
                        componentSize.width /= zoomMultiplier;
                        componentSize.height /= zoomMultiplier;
                    }
                    amount--;
                }
                while (amount < 0 && zoom * zoomMultiplier <= maxFactor) {
                    zoom *= zoomMultiplier;
                    if (viewPosition != null) {
                        viewPosition.x *= zoomMultiplier;
                        viewPosition.y *= zoomMultiplier;
                        bounds.width *= zoomMultiplier;
                        bounds.height *= zoomMultiplier;
                        componentSize.width *= zoomMultiplier;
                        componentSize.height *= zoomMultiplier;
                    }
                    amount++;
                }
                sceneAnimator.animateZoomFactor(zoom);
            }
        } else {
            double zoom = scene.getZoomFactor();
            while (amount > 0 && zoom / zoomMultiplier >= minFactor) {
                zoom /= zoomMultiplier;
                if (viewPosition != null) {
                    viewPosition.x /= zoomMultiplier;
                    viewPosition.y /= zoomMultiplier;
                    bounds.width /= zoomMultiplier;
                    bounds.height /= zoomMultiplier;
                    componentSize.width /= zoomMultiplier;
                    componentSize.height /= zoomMultiplier;
                }
                amount--;
            }
            while (amount < 0 && zoom * zoomMultiplier <= maxFactor) {
                zoom *= zoomMultiplier;
                if (viewPosition != null) {
                    viewPosition.x *= zoomMultiplier;
                    viewPosition.y *= zoomMultiplier;
                    bounds.width *= zoomMultiplier;
                    bounds.height *= zoomMultiplier;
                    componentSize.width *= zoomMultiplier;
                    componentSize.height *= zoomMultiplier;
                }
                amount++;
            }
            scene.setZoomFactor(zoom);
        }

        if (scrollPane != null) {
            viewPosition.x -= xOffset;
            viewPosition.y -= yOffset;
            scrollPane.getViewport().setViewPosition(viewPosition);
        }


        return WidgetAction.State.CONSUMED;
    }
}
