//
//  VLCHUDStepperCell.m
//  BGHUDAppKit
//
//  Created by BinaryGod on 4/6/09.
//
//  Copyright 2009 Tyler Bunnell and Steve Audette
//	All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without modification,
//  are permitted provided that the following conditions are met:
//
//		Redistributions of source code must retain the above copyright notice, this
//	list of conditions and the following disclaimer.
//
//		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.
//
//		Neither the name of the BinaryMethod.com 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT OWNER OR 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 "VLCHUDStepperCell.h"
#import "CompatibilityFixes.h"
#import "NSGradient+VLCAdditions.h"

@interface VLCHUDStepperCell () {
    int topButtonFlag;
    int bottomButtonFlag;

    BOOL topPressed;
    BOOL bottomPressed;
    BOOL isTopDown;
    BOOL isBottomDown;
}

@end

@implementation VLCHUDStepperCell

- (instancetype)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        _dropShadow = [[NSShadow alloc] init];
        [_dropShadow setShadowColor: [NSColor blackColor]];
        [_dropShadow setShadowBlurRadius: 2];
        [_dropShadow setShadowOffset: NSMakeSize( 0, -1)];

        _strokeColor = [NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha: 1.0f];
        _disabledStrokeColor = [NSColor colorWithDeviceRed: 0.749f green: 0.761f blue: 0.788f alpha:0.2f];

        _normalGradient    = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.251f green:0.251f blue:0.255f alpha:1.0f]
                                                           endingColor:[NSColor colorWithDeviceRed:0.118f green:0.118f blue:0.118f alpha:1.0f]];
        _disabledNormalComplexGradient = [[NSGradient alloc] initWithColorsAndLocations: [NSColor colorWithDeviceRed: 0.324f green: 0.331f blue: 0.347f alpha:0.5f],
                                           (CGFloat)0, [NSColor colorWithDeviceRed: 0.245f green: 0.253f blue: 0.269f alpha: 0.5f], (CGFloat).5,
                                           [NSColor colorWithDeviceRed: 0.206f green: 0.214f blue: 0.233f alpha: 0.5f], (CGFloat).5,
                                           [NSColor colorWithDeviceRed: 0.139f green: 0.147f blue: 0.167f alpha: 0.5f], (CGFloat)1.0f, nil];
        _pushedSolidFill = [NSColor colorWithDeviceRed: 0.941f green: 0.941f blue: 0.941f alpha: 0.5f];
        _darkStrokeColor = [NSColor colorWithDeviceRed: 0.141f green: 0.141f blue: 0.141f alpha: 0.5f];
    }
    return self;
}

-(void)drawWithFrame:(NSRect) frame inView:(NSView *) controlView {
    if (OSX_YOSEMITE_AND_HIGHER) {
        return [super drawWithFrame:frame inView:controlView];
    }
    [self drawRoundRectButtonInFrame:frame];
    [self drawArrowsInRect:frame];
}

-(NSRect)adjustFrame:(NSRect)frame
{
    frame.origin.x += 3.5f;
    frame.origin.y += 2.0f;
    frame.size.width -= 7.0f;
    frame.size.height -= 4.0f;
    return frame;
}

-(BOOL)startTrackingAt:(NSPoint)startPoint inView:(NSView *)controlView
{
    if (OSX_YOSEMITE_AND_HIGHER) {
        return [super startTrackingAt:startPoint inView:controlView];
    }
    NSRect frame = [controlView bounds];

    NSRect bottomRect = NSMakeRect(frame.origin.x,frame.origin.y,frame.size.width,frame.size.height/2);
    NSRect topRect = NSMakeRect(frame.origin.x,frame.origin.y+(frame.size.height/2),frame.size.width,frame.size.height/2);

    if(NSPointInRect(startPoint,topRect))
    {
        topPressed = isTopDown = YES;
    }
    if(NSPointInRect(startPoint,bottomRect))
    {
        bottomPressed = isBottomDown = YES;
    }
    [[self controlView] setNeedsDisplay:YES];

    return [super startTrackingAt:startPoint inView:controlView];
}
-(BOOL)continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint inView:(NSView *)controlView
{
    if (OSX_YOSEMITE_AND_HIGHER) {
        return [super continueTracking:lastPoint at:currentPoint inView:controlView];
    }
    NSRect frame = [controlView bounds];

    NSRect bottomRect = NSMakeRect(frame.origin.x,frame.origin.y,frame.size.width,frame.size.height/2);
    NSRect topRect = NSMakeRect(frame.origin.x,frame.origin.y+(frame.size.height/2),frame.size.width,frame.size.height/2);

    if(isTopDown && topPressed && !NSPointInRect(currentPoint,topRect))
    {
        isTopDown = NO;
        [[self controlView] setNeedsDisplay:YES];
    }
    if(!isTopDown && topPressed && NSPointInRect(currentPoint,topRect))
    {
        isTopDown = YES;
        [[self controlView] setNeedsDisplay:YES];
    }
    if(isBottomDown && bottomPressed && !NSPointInRect(currentPoint,bottomRect))
    {
        isBottomDown = NO;
        [[self controlView] setNeedsDisplay:YES];
    }
    if(!isBottomDown && bottomPressed && NSPointInRect(currentPoint,bottomRect))
    {
        isBottomDown = YES;
        [[self controlView] setNeedsDisplay:YES];
    }

    return [super continueTracking:lastPoint at:currentPoint inView:controlView];
}
-(void)stopTracking:(NSPoint)lastPoint at:(NSPoint)stopPoint inView:(NSView *)controlView mouseIsUp:(BOOL)flag
{
    if (OSX_YOSEMITE_AND_HIGHER) {
        return [super stopTracking:lastPoint at:stopPoint inView:controlView mouseIsUp:flag];
    }
    isTopDown = isBottomDown = topPressed = bottomPressed = NO;
    [[self controlView] setNeedsDisplay:YES];
    [super stopTracking:lastPoint at:stopPoint inView:controlView mouseIsUp:flag];
}

-(void)drawRoundRectButtonInFrame:(NSRect)frame {

    frame = [self adjustFrame:frame];

    float cornerRadius = 4.0f;

    //Draw the complete button

    //Create Path
    NSBezierPath *path = [[NSBezierPath alloc] init];

    //Bottom Right Corner
    [path moveToPoint:NSMakePoint(NSMaxX(frame), NSMinY(frame) + cornerRadius)];

    //Right Edge
    [path lineToPoint:NSMakePoint(NSMaxX(frame), NSMaxY(frame) - cornerRadius)];

    //Top Right Curve
    [path appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(frame) - cornerRadius, NSMaxY(frame) - cornerRadius)
                                     radius: cornerRadius
                                 startAngle: 0
                                   endAngle: 90];

    //Top Edge
    [path lineToPoint:NSMakePoint(NSMinX(frame) + cornerRadius, NSMaxY(frame))];

    //Top Left Curve
    [path appendBezierPathWithArcWithCenter:NSMakePoint(NSMinX(frame) + cornerRadius, NSMaxY(frame) - cornerRadius)
                                     radius: cornerRadius
                                 startAngle: 90
                                   endAngle: 180];

    //Left Edge
    [path lineToPoint:NSMakePoint(NSMinX(frame), NSMinY(frame) + cornerRadius)];

    //Left Bottom Curve
    [path appendBezierPathWithArcWithCenter: NSMakePoint(NSMinX(frame) + cornerRadius, NSMinY(frame) + cornerRadius)
                                     radius: cornerRadius
                                 startAngle: 180
                                   endAngle: 270];

    //Bottom Edge
    [path lineToPoint:NSMakePoint(NSMaxX(frame) - cornerRadius, NSMinY(frame))];

    //Right Bottom Curve
    [path appendBezierPathWithArcWithCenter:NSMakePoint(NSMaxX(frame) - cornerRadius, NSMinY(frame) + cornerRadius)
                                     radius: cornerRadius
                                 startAngle: 270
                                   endAngle: 0];

    [path closePath];


    if([self isEnabled]) {

        [_normalGradient vlc_safeDrawInBezierPath:path relativeCenterPosition:NSZeroPoint];

    } else {

        [_disabledNormalComplexGradient vlc_safeDrawInBezierPath:path relativeCenterPosition:NSZeroPoint];
    }



    //Check for anything being pushed
    if([self isEnabled])
    {
        if(isTopDown)
        {
            NSRect topRect = NSMakeRect(frame.origin.x,frame.origin.y+(frame.size.height/2),frame.size.width,frame.size.height/2);
            NSBezierPath *path = [[NSBezierPath alloc] init];
            [path moveToPoint:NSMakePoint(NSMaxX(topRect), NSMinY(topRect))];
            [path lineToPoint:NSMakePoint(NSMaxX(topRect), NSMaxY(topRect) - cornerRadius)];
            [path appendBezierPathWithArcWithCenter: NSMakePoint(NSMaxX(topRect) - cornerRadius, NSMaxY(topRect) - cornerRadius)
                                             radius: cornerRadius
                                         startAngle: 0
                                           endAngle: 90];
            [path lineToPoint:NSMakePoint(NSMinX(topRect) + cornerRadius, NSMaxY(topRect))];
            [path appendBezierPathWithArcWithCenter:NSMakePoint(NSMinX(topRect) + cornerRadius, NSMaxY(topRect) - cornerRadius)
                                             radius: cornerRadius
                                         startAngle: 90
                                           endAngle: 180];
            [path lineToPoint:NSMakePoint(NSMinX(topRect), NSMinY(topRect))];

            [path closePath];

            [_pushedSolidFill set];
            [path fill];
        }
        else if(isBottomDown)
        {
            NSRect bottomRect = NSMakeRect(frame.origin.x,frame.origin.y,frame.size.width,frame.size.height/2);
            NSBezierPath* path = [[NSBezierPath alloc] init];

            [path moveToPoint:NSMakePoint(NSMinX(bottomRect), NSMaxY(bottomRect))];
            [path lineToPoint:NSMakePoint(NSMinX(bottomRect), NSMinY(bottomRect) + cornerRadius)];
            [path appendBezierPathWithArcWithCenter: NSMakePoint(NSMinX(bottomRect) + cornerRadius, NSMinY(bottomRect) + cornerRadius)
                                             radius: cornerRadius
                                         startAngle: 180
                                           endAngle: 270];
            [path lineToPoint:NSMakePoint(NSMaxX(bottomRect) - cornerRadius, NSMinY(bottomRect))];
            [path appendBezierPathWithArcWithCenter:NSMakePoint(NSMaxX(bottomRect) - cornerRadius, NSMinY(bottomRect) + cornerRadius)
                                             radius: cornerRadius
                                         startAngle: 270
                                           endAngle: 0];
            [path lineToPoint:NSMakePoint(NSMaxX(bottomRect), NSMaxY(bottomRect))];

            [path closePath];
            [_pushedSolidFill set];
            [path fill];
        }
    }

    [NSGraphicsContext saveGraphicsState];

    //Draw dark border color
    if([self isEnabled]) {

        [_dropShadow set];
    }
    [_darkStrokeColor set];
    [path stroke];

    [NSGraphicsContext restoreGraphicsState];

    if([self isEnabled]) {

        [_strokeColor set];
    } else {

        [_disabledStrokeColor set];
    }

    [path setLineWidth: 1.0f];
    [path stroke];


}

-(void)drawArrowsInRect:(NSRect) frame {

    CGFloat arrowWidth = 2.5f;
    CGFloat arrowHeight = 2.0f;

    frame = [self adjustFrame:frame];

    NSRect bottomRect = NSMakeRect(frame.origin.x,frame.origin.y,frame.size.width,frame.size.height/2);
    NSRect topRect = NSMakeRect(frame.origin.x,frame.origin.y+(frame.size.height/2),frame.size.width,frame.size.height/2);

    NSBezierPath *arrow = [[NSBezierPath alloc] init];

    NSPoint points[3];

    points[0] = NSMakePoint(topRect.origin.x + (topRect.size.width /2), topRect.origin.y + ((topRect.size.height /2) + arrowHeight));
    points[1] = NSMakePoint(topRect.origin.x + ((topRect.size.width /2) - arrowWidth), topRect.origin.y + ((topRect.size.height /2)-arrowHeight));
    points[2] = NSMakePoint(topRect.origin.x + ((topRect.size.width /2) + arrowWidth), topRect.origin.y + ((topRect.size.height /2)-arrowHeight));
    
    
    [arrow appendBezierPathWithPoints: points count: 3];
    
    if([self isEnabled]) {
        if(isTopDown)
            [_darkStrokeColor set];
        else
            [_strokeColor set];
    } else {
        [_disabledStrokeColor set];
    }
    
    
    [arrow fill];
    
    
    arrow = [[NSBezierPath alloc] init];
    
    points[0] = NSMakePoint(bottomRect.origin.x + ((bottomRect.size.width /2) - arrowWidth), bottomRect.origin.y + ((bottomRect.size.height /2)+arrowHeight));
    points[1] = NSMakePoint(bottomRect.origin.x + ((bottomRect.size.width /2) + arrowWidth), bottomRect.origin.y + ((bottomRect.size.height /2)+arrowHeight));
    points[2] = NSMakePoint(bottomRect.origin.x + (bottomRect.size.width /2), frame.origin.y + ((bottomRect.size.height /2) - arrowHeight));
    
    [arrow appendBezierPathWithPoints: points count: 3];
    
    if([self isEnabled]) {
        if(isBottomDown)
            [_darkStrokeColor set];
        else
            [_strokeColor set];
    } else {
        [_disabledStrokeColor set];
    }
    
    [arrow fill];
}

@end
