//
//  VLCHUDPopUpButtonCell.m
//  BGHUDAppKit
//
//  Created by BinaryGod on 5/31/08.
//
//  Copyright (c) 2008, Tim Davis (BinaryMethod.com, binary.god@gmail.com)
//  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 "VLCHUDPopUpButtonCell.h"
#import "CompatibilityFixes.h"
#import "NSGradient+VLCAdditions.h"

@implementation VLCHUDPopUpButtonCell

+ (void)load
{
    /* On 10.10+ we do not want custom drawing, therefore we swap out the implementation
     * of the selectors below with their original implementations.
     * Just calling super in the overridden methods is not enough, to get the same drawin
     * a non-subclassed cell would use.
     */
    if (OSX_YOSEMITE_AND_HIGHER) {
        swapoutOverride([VLCHUDPopUpButtonCell class], @selector(initWithCoder:));
        swapoutOverride([VLCHUDPopUpButtonCell class], @selector(drawWithFrame:inView:));
    }
}

- (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];
        _darkStrokeColor = [NSColor colorWithDeviceRed:0.141f green:0.141f blue:0.141f alpha:0.5f];
        _disabledStrokeColor = [NSColor colorWithDeviceRed:0.749f green:0.761f blue:0.788f alpha:0.2f];
        _selectionTextActiveColor = [NSColor whiteColor];
        _selectionTextInActiveColor = [NSColor whiteColor];
        _cellTextColor = [NSColor whiteColor];
        _disabledCellTextColor = [NSColor colorWithDeviceRed:1 green:1 blue:1 alpha:0.2f];

        _normalGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.251f green:0.251f blue:0.255f alpha:0.5f]
                                                        endingColor:[NSColor colorWithDeviceRed:0.118f green:0.118f blue:0.118f alpha:0.5f]];
        _disabledNormalGradient = [[NSGradient alloc] initWithStartingColor:[NSColor colorWithDeviceRed:0.251f green:0.251f blue:0.255f alpha:0.2f]
                                                                endingColor:[NSColor colorWithDeviceRed:0.118f green:0.118f blue:0.118f alpha:0.2f]];
    }
    return self;
}

#pragma mark Drawing Functions

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView {

    NSRect frame = cellFrame;

    // Adjust frame by .5 so lines draw true
    frame.origin.x += .5f;
    frame.origin.y += .5f;
    frame.size.height = [self cellSize].height;

    // Make Adjustments to Frame based on Cell Size
    switch ([self controlSize]) {

        case NSRegularControlSize:
            frame.origin.x += 3;
            frame.size.width -= 7;
            frame.origin.y += 2;
            frame.size.height -= 7;
            break;

        case NSSmallControlSize:
            frame.origin.y += 1;
            frame.size.height -= 6;
            frame.origin.x += 3;
            frame.size.width -= 7;
            break;

        case NSMiniControlSize:
            frame.origin.x += 1;
            frame.size.width -= 4;
            frame.size.height -= 2;
            break;
    }

    if ([self isBordered]) {
        NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:frame xRadius: 4 yRadius: 4];

        [NSGraphicsContext saveGraphicsState];
        [_dropShadow set];
        [_darkStrokeColor set];
        [path stroke];
        [NSGraphicsContext restoreGraphicsState];

        if ([self isEnabled]) {
            [_normalGradient vlc_safeDrawInBezierPath: path angle: 90];
            [_strokeColor set];
        } else {
            [_disabledNormalGradient vlc_safeDrawInBezierPath: path angle: 90];
            [_disabledStrokeColor set];
        }

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

    // Draw the arrows
    [self drawArrowsInRect: frame];

    // Adjust rect for title drawing
    switch ([self controlSize]) {

        case NSRegularControlSize:

            frame.origin.x += 8;
            frame.origin.y += 1;
            frame.size.width -= 29;
            break;

        case NSSmallControlSize:

            frame.origin.x += 8;
            frame.origin.y += 2;
            frame.size.width -= 29;
            break;

        case NSMiniControlSize:

            frame.origin.x += 8;
            frame.origin.y += .5f;
            frame.size.width -= 26;
            break;
    }

    NSMutableAttributedString *aTitle = [[self attributedTitle] mutableCopy];

    // Make sure aTitle actually contains something
    if (aTitle.length > 0) {
        [aTitle beginEditing];
        [aTitle removeAttribute:NSForegroundColorAttributeName range:NSMakeRange(0, aTitle.length)];

        if (self.isEnabled) {
            if (self.isHighlighted) {

                if (self.controlView.window.isKeyWindow) {
                    [aTitle addAttribute:NSForegroundColorAttributeName
                                   value:_selectionTextActiveColor
                                   range:NSMakeRange(0, aTitle.length)];
                } else {
                    [aTitle addAttribute:NSForegroundColorAttributeName
                                   value:_selectionTextInActiveColor
                                   range:NSMakeRange(0, aTitle.length)];
                }
            } else {
                [aTitle addAttribute:NSForegroundColorAttributeName
                               value:_cellTextColor
                               range:NSMakeRange(0, aTitle.length)];
            }
        } else {
            [aTitle addAttribute:NSForegroundColorAttributeName
                           value:_disabledCellTextColor
                           range:NSMakeRange(0, aTitle.length)];
        }
        [aTitle endEditing];
    }

    int arrowAdjustment = 0;

    cellFrame.size.height -= 2;
    if (self.isBordered) {
        cellFrame.origin.x += 5;
    }

    switch (self.controlSize) {
        case NSRegularControlSize:
            arrowAdjustment = 21;
            break;

        case NSSmallControlSize:
            arrowAdjustment = 18;
            break;

        case NSMiniControlSize:
            arrowAdjustment = 15;
            break;
    }

    NSRect titleFrame = NSMakeRect(cellFrame.origin.x + 5, NSMidY(cellFrame) - ([aTitle size].height/2), cellFrame.size.width - arrowAdjustment, [aTitle size].height);
    NSRect imageFrame = NSMakeRect(cellFrame.origin.x, cellFrame.origin.y, cellFrame.size.width - arrowAdjustment, cellFrame.size.height);

    if([self image]) {

        switch ([self imagePosition]) {

            case NSImageLeft:
            case NSNoImage:

                titleFrame.origin.x += 6;
                titleFrame.origin.x += [[self image] size].width;
                break;

            case NSImageOnly:
                titleFrame.size.width = 0;
                break;

            default:
                break;
        }
    }

    if([self imagePosition] != NSImageOnly) {
        [super drawTitle:aTitle withFrame:titleFrame inView:controlView];
    }


    if([self imagePosition] != NSNoImage) {
        [self drawImage:[self image] withFrame:imageFrame inView:controlView];
    }
}

- (void)drawArrowsInRect:(NSRect) frame {

    CGFloat arrowsWidth;
    CGFloat arrowsHeight;
    CGFloat arrowWidth;
    CGFloat arrowHeight;

    int arrowAdjustment = 0;

    //Adjust based on Control size
    switch ([self controlSize]) {
        default: // Silence uninitialized variable warnings
        case NSRegularControlSize:

            if ([self isBordered]) {

                arrowAdjustment = 21;
            } else {

                arrowAdjustment = 11;
            }

            arrowWidth = 3.5f;
            arrowHeight = 2.5f;
            arrowsHeight = 2;
            arrowsWidth = 2.5f;
            break;

        case NSSmallControlSize:

            if ([self isBordered]) {

                arrowAdjustment = 18;
            } else {

                arrowAdjustment = 8;
            }

            arrowWidth = 3.5f;
            arrowHeight = 2.5f;
            arrowsHeight = 2;
            arrowsWidth = 2.5f;

            break;

        case NSMiniControlSize:

            if ([self isBordered]) {

                arrowAdjustment = 15;
            } else {

                arrowAdjustment = 5;
            }

            arrowWidth = 2.5f;
            arrowHeight = 1.5f;
            arrowsHeight = 1.5f;
            arrowsWidth = 2;
            break;
    }

    frame.origin.x += (frame.size.width - arrowAdjustment);
    frame.size.width = arrowAdjustment;

    if ([self pullsDown]) {

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

        NSPoint points[3];

        points[0] = NSMakePoint(frame.origin.x + ((frame.size.width /2) - arrowWidth), frame.origin.y + ((frame.size.height /2) - arrowHeight));
        points[1] = NSMakePoint(frame.origin.x + ((frame.size.width /2) + arrowWidth), frame.origin.y + ((frame.size.height /2) - arrowHeight));
        points[2] = NSMakePoint(frame.origin.x + (frame.size.width /2), frame.origin.y + ((frame.size.height /2) + arrowHeight));

        [arrow appendBezierPathWithPoints: points count: 3];
        
        if ([self isEnabled]) {
            
            if ([self isHighlighted]) {
                
                if ([[[self controlView] window] isKeyWindow]) {
                    
                    [_selectionTextActiveColor set];
                } else {
                    
                    [_selectionTextInActiveColor set];
                }
            } else {
                
                [_cellTextColor set];
            }
        } else {
            
            [_disabledCellTextColor set];
        }
        
        [arrow fill];
    } else {
        
        NSBezierPath *topArrow = [[NSBezierPath alloc] init];
        
        NSPoint topPoints[3];
        
        topPoints[0] = NSMakePoint(frame.origin.x + ((frame.size.width /2) - arrowsWidth), frame.origin.y + ((frame.size.height /2) - arrowsHeight));
        topPoints[1] = NSMakePoint(frame.origin.x + ((frame.size.width /2) + arrowsWidth), frame.origin.y + ((frame.size.height /2) - arrowsHeight));
        topPoints[2] = NSMakePoint(frame.origin.x + (frame.size.width /2), frame.origin.y + ((frame.size.height /2) - ((arrowsHeight * 2) + 2)));
        
        [topArrow appendBezierPathWithPoints: topPoints count: 3];
        
        if([self isEnabled]) {
            
            if([self isHighlighted]) {
                
                if([[[self controlView] window] isKeyWindow])
                {
                    
                    [_selectionTextActiveColor set];
                } else {
                    
                    [_selectionTextInActiveColor set];
                }
            } else {
                
                [_cellTextColor set];
            }
        } else {
            
            [_disabledCellTextColor set];
        }
        [topArrow fill];
        
        NSBezierPath *bottomArrow = [[NSBezierPath alloc] init];
        
        NSPoint bottomPoints[3];
        
        bottomPoints[0] = NSMakePoint(frame.origin.x + ((frame.size.width /2) - arrowsWidth), frame.origin.y + ((frame.size.height /2) + arrowsHeight));
        bottomPoints[1] = NSMakePoint(frame.origin.x + ((frame.size.width /2) + arrowsWidth), frame.origin.y + ((frame.size.height /2) + arrowsHeight));
        bottomPoints[2] = NSMakePoint(frame.origin.x + (frame.size.width /2), frame.origin.y + ((frame.size.height /2) + ((arrowsHeight * 2) + 2)));
        
        [bottomArrow appendBezierPathWithPoints: bottomPoints count: 3];
        
        if ([self isEnabled]) {
            
            if ([self isHighlighted]) {
                
                if ([[[self controlView] window] isKeyWindow]) {
                    
                    [_selectionTextActiveColor set];
                } else {
                    
                    [_selectionTextInActiveColor set];
                }
            } else {
                
                [_cellTextColor set];
            }
        } else {
            
            [_disabledCellTextColor set];
        }
        [bottomArrow fill];
    }
}

@end
