/*
 * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer. 
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution. 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#import <WebKit/WebDynamicScrollBarsView.h>

#import <WebKit/WebDocument.h>
#import <WebKitSystemInterface.h>

@implementation WebDynamicScrollBarsView

- (void)setSuppressLayout: (BOOL)flag;
{
    suppressLayout = flag;
}

- (void)setScrollBarsSuppressed:(BOOL)suppressed repaintOnUnsuppress:(BOOL)repaint
{
    suppressScrollers = suppressed;

    // This code was originally changes for a Leopard performance imporvement. We decided to 
    // ifdef it to fix correctness issues on Tiger documented in <rdar://problem/5441823>.
#ifndef BUILDING_ON_TIGER
    if (suppressed) {
        [[self verticalScroller] setNeedsDisplay:NO];
        [[self horizontalScroller] setNeedsDisplay:NO];
    }
        
    if (!suppressed && repaint)
        [super reflectScrolledClipView:[self contentView]];
#else
    if (suppressed || repaint) { 
        [[self verticalScroller] setNeedsDisplay: !suppressed]; 
        [[self horizontalScroller] setNeedsDisplay: !suppressed]; 
    }
#endif
}

- (void)updateScrollers
{
    // We need to do the work below twice in the case where a scroll bar disappears,
    // making the second layout have a wider width than the first. Doing it more than
    // twice would indicate some kind of infinite loop, so we do it at most twice.
    // It's quite efficient to do this work twice in the normal case, so we don't bother
    // trying to figure out of the second pass is needed or not.
    if (inUpdateScrollers)
        return;
    
    inUpdateScrollers = true;

    int pass;
    BOOL hasVerticalScroller = [self hasVerticalScroller];
    BOOL hasHorizontalScroller = [self hasHorizontalScroller];
    BOOL oldHasVertical = hasVerticalScroller;
    BOOL oldHasHorizontal = hasHorizontalScroller;

    for (pass = 0; pass < 2; pass++) {
        BOOL scrollsVertically;
        BOOL scrollsHorizontally;

        if (!suppressLayout && !suppressScrollers && (hScroll == WebCoreScrollbarAuto || vScroll == WebCoreScrollbarAuto)) {
            // Do a layout if pending, before checking if scrollbars are needed.
            // This fixes 2969367, although may introduce a slowdown in live resize performance.
            NSView *documentView = [self documentView];
            if (!documentView) {
                scrollsHorizontally = NO;
                scrollsVertically = NO;
            } else {
                if ((hasVerticalScroller != oldHasVertical ||
                    hasHorizontalScroller != oldHasHorizontal || [documentView inLiveResize]) && [documentView conformsToProtocol:@protocol(WebDocumentView)]) {
                    [(id <WebDocumentView>)documentView setNeedsLayout: YES];
                    [(id <WebDocumentView>)documentView layout];
                }

                NSSize documentSize = [documentView frame].size;
                NSSize frameSize = [self frame].size;

                scrollsVertically = (vScroll == WebCoreScrollbarAlwaysOn) ||
                    (vScroll == WebCoreScrollbarAuto && documentSize.height > frameSize.height);
                if (scrollsVertically)
                    scrollsHorizontally = (hScroll == WebCoreScrollbarAlwaysOn) ||
                        (hScroll == WebCoreScrollbarAuto && documentSize.width + [NSScroller scrollerWidth] > frameSize.width);
                else {
                    scrollsHorizontally = (hScroll == WebCoreScrollbarAlwaysOn) ||
                        (hScroll == WebCoreScrollbarAuto && documentSize.width > frameSize.width);
                    if (scrollsHorizontally)
                        scrollsVertically = (vScroll == WebCoreScrollbarAlwaysOn) ||
                            (vScroll == WebCoreScrollbarAuto && documentSize.height + [NSScroller scrollerWidth] > frameSize.height);
                }
            }
        } else {
            scrollsHorizontally = (hScroll == WebCoreScrollbarAuto) ? hasHorizontalScroller : (hScroll == WebCoreScrollbarAlwaysOn);
            scrollsVertically = (vScroll == WebCoreScrollbarAuto) ? hasVerticalScroller : (vScroll == WebCoreScrollbarAlwaysOn);
        }

        if (hasVerticalScroller != scrollsVertically) {
            [self setHasVerticalScroller:scrollsVertically];
            hasVerticalScroller = scrollsVertically;
        }

        if (hasHorizontalScroller != scrollsHorizontally) {
            [self setHasHorizontalScroller:scrollsHorizontally];
            hasHorizontalScroller = scrollsHorizontally;
        }
    }

    if (suppressScrollers) {
        [[self verticalScroller] setNeedsDisplay: NO];
        [[self horizontalScroller] setNeedsDisplay: NO];
    }

    inUpdateScrollers = false;
}

// Make the horizontal and vertical scroll bars come and go as needed.
- (void)reflectScrolledClipView:(NSClipView *)clipView
{
    if (clipView == [self contentView]) {
        // FIXME: This hack here prevents infinite recursion that takes place when we
        // gyrate between having a vertical scroller and not having one. A reproducible
        // case is clicking on the "the Policy Routing text" link at
        // http://www.linuxpowered.com/archive/howto/Net-HOWTO-8.html.
        // The underlying cause is some problem in the NSText machinery, but I was not
        // able to pin it down.
        if (!inUpdateScrollers && [[NSGraphicsContext currentContext] isDrawingToScreen])
            [self updateScrollers];
    }

    // This code was originally changed for a Leopard performance imporvement. We decided to 
    // ifdef it to fix correctness issues on Tiger documented in <rdar://problem/5441823>.
#ifndef BUILDING_ON_TIGER
    // Update the scrollers if they're not being suppressed.
    if (!suppressScrollers)
        [super reflectScrolledClipView:clipView];
#else
    [super reflectScrolledClipView:clipView]; 
  
    // Validate the scrollers if they're being suppressed. 
    if (suppressScrollers) { 
        [[self verticalScroller] setNeedsDisplay: NO]; 
        [[self horizontalScroller] setNeedsDisplay: NO]; 
    }
#endif
}

- (void)setAllowsScrolling:(BOOL)flag
{
    if (hScrollModeLocked && vScrollModeLocked)
        return;

    if (flag && vScroll == WebCoreScrollbarAlwaysOff)
        vScroll = WebCoreScrollbarAuto;
    else if (!flag && vScroll != WebCoreScrollbarAlwaysOff)
        vScroll = WebCoreScrollbarAlwaysOff;

    if (flag && hScroll == WebCoreScrollbarAlwaysOff)
        hScroll = WebCoreScrollbarAuto;
    else if (!flag && hScroll != WebCoreScrollbarAlwaysOff)
        hScroll = WebCoreScrollbarAlwaysOff;

    [self updateScrollers];
}

- (BOOL)allowsScrolling
{
    // Returns YES if either horizontal or vertical scrolling is allowed.
    return hScroll != WebCoreScrollbarAlwaysOff || vScroll != WebCoreScrollbarAlwaysOff;
}

- (void)setAllowsHorizontalScrolling:(BOOL)flag
{
    if (hScrollModeLocked)
        return;
    if (flag && hScroll == WebCoreScrollbarAlwaysOff)
        hScroll = WebCoreScrollbarAuto;
    else if (!flag && hScroll != WebCoreScrollbarAlwaysOff)
        hScroll = WebCoreScrollbarAlwaysOff;
    [self updateScrollers];
}

- (void)setAllowsVerticalScrolling:(BOOL)flag
{
    if (vScrollModeLocked)
        return;
    if (flag && vScroll == WebCoreScrollbarAlwaysOff)
        vScroll = WebCoreScrollbarAuto;
    else if (!flag && vScroll != WebCoreScrollbarAlwaysOff)
        vScroll = WebCoreScrollbarAlwaysOff;
    [self updateScrollers];
}

- (BOOL)allowsHorizontalScrolling
{
    return hScroll != WebCoreScrollbarAlwaysOff;
}

- (BOOL)allowsVerticalScrolling
{
    return vScroll != WebCoreScrollbarAlwaysOff;
}

-(WebCoreScrollbarMode)horizontalScrollingMode
{
    return hScroll;
}

-(WebCoreScrollbarMode)verticalScrollingMode
{
    return vScroll;
}

- (void)setHorizontalScrollingMode:(WebCoreScrollbarMode)mode
{
    [self setHorizontalScrollingMode:mode andLock:NO];
}

- (void)setHorizontalScrollingMode:(WebCoreScrollbarMode)mode andLock:(BOOL)lock
{
    if (mode == hScroll || hScrollModeLocked)
        return;

    hScroll = mode;

    if (lock)
        [self setHorizontalScrollingModeLocked:YES];

    [self updateScrollers];
}

- (void)setVerticalScrollingMode:(WebCoreScrollbarMode)mode
{
    [self setVerticalScrollingMode:mode andLock:NO];
}

- (void)setVerticalScrollingMode:(WebCoreScrollbarMode)mode andLock:(BOOL)lock
{
    if (mode == vScroll || vScrollModeLocked)
        return;

    vScroll = mode;

    if (lock)
        [self setVerticalScrollingModeLocked:YES];

    [self updateScrollers];
}

- (void)setScrollingMode:(WebCoreScrollbarMode)mode
{
    [self setScrollingMode:mode andLock:NO];
}

- (void)setScrollingMode:(WebCoreScrollbarMode)mode andLock:(BOOL)lock
{
    if ((mode == vScroll && mode == hScroll) || (vScrollModeLocked && hScrollModeLocked))
        return;

    BOOL update = NO;
    if (mode != vScroll && !vScrollModeLocked) {
        vScroll = mode;
        update = YES;
    }

    if (mode != hScroll && !hScrollModeLocked) {
        hScroll = mode;
        update = YES;
    }

    if (lock)
        [self setScrollingModesLocked:YES];

    if (update)
        [self updateScrollers];
}

- (void)setHorizontalScrollingModeLocked:(BOOL)locked
{
    hScrollModeLocked = locked;
}

- (void)setVerticalScrollingModeLocked:(BOOL)locked
{
    vScrollModeLocked = locked;
}

- (void)setScrollingModesLocked:(BOOL)locked
{
    hScrollModeLocked = vScrollModeLocked = locked;
}

- (BOOL)horizontalScrollingModeLocked
{
    return hScrollModeLocked;
}

- (BOOL)verticalScrollingModeLocked
{
    return vScrollModeLocked;
}

- (BOOL)autoforwardsScrollWheelEvents
{
    return YES;
}

- (void)scrollWheel:(NSEvent *)event
{
    float deltaX;
    float deltaY;
    BOOL isContinuous;
    WKGetWheelEventDeltas(event, &deltaX, &deltaY, &isContinuous);

    if (fabsf(deltaY) > fabsf(deltaX)) {
        if (![self allowsVerticalScrolling]) {
            [[self nextResponder] scrollWheel:event];
            return;
        }
    } else if (![self allowsHorizontalScrolling]) {
        [[self nextResponder] scrollWheel:event];
        return;
    }

    [super scrollWheel:event];
}

@end
