#import "ControllerButton.h"

@implementation ControllerButton

- (void)awakeFromNib {
    _state = NSOffState;
    _normalImage = [[self image] retain];
    _altImage = [[self alternateImage] retain];
    _normalOverImage = [[NSImage imageNamed:
        [[_normalImage name] stringByAppendingString:@"_over"]] retain];
    _normalDownImage = [[NSImage imageNamed:
        [[_normalImage name] stringByAppendingString:@"_down"]] retain];
    _pulseImage = [[NSImage imageNamed:
        [[_normalImage name] stringByAppendingString:@"_pulse"]] retain];
    if (_altImage != nil) {
        _altOverImage = [[NSImage imageNamed:
            [[_altImage name] stringByAppendingString:@"_over"]] retain];
        _altDownImage = [[NSImage imageNamed:
            [[_altImage name] stringByAppendingString:@"_down"]] retain];
        _toggle = TRUE;
    } else {
        _toggle = FALSE;
        _altOverImage = nil;
        _altDownImage = nil;
    }
    if (_normalDownImage != nil) {
        [self setAlternateImage:_normalDownImage];
    } else if (_altImage != nil && _altDownImage == nil) {
        [self setAlternateImage:_altImage];
    }
    [self setFocusRingType:NSFocusRingTypeNone];
    if (_normalOverImage != nil || _altOverImage != nil) {
        /*NSPoint mouseLoc = [self convertPoint:[[self window] mouseLocationOutsideOfEventStream]
         fromView:nil];
        BOOL isInside = [self mouse:mouseLoc inRect:[self bounds]];
        printf("isInside: %d\n", (int)isInside);
        if (isInside) {
            [self mouseEntered:nil];
        }*/
        [self addTrackingRect:[self bounds] owner:self userData:nil assumeInside:NO];
    }
    _inside = NO;
    _pulseOpacity = 0;
    _pulseTick = 0.1;
}

- (void)mouseEntered:(NSEvent *)theEvent {
    if (_state == NSOffState) {
        if (_normalOverImage != nil) {
            [self setImage:_normalOverImage];
            [self setNeedsDisplay:YES];
        }
    } else {
        if (_altOverImage != nil) {
            [self setImage:_altOverImage];
            [self setNeedsDisplay:YES];
        }
    }
    _inside = YES;
}

- (void)mouseExited:(NSEvent *)theEvent {
    if (_state == NSOffState) {
        if (_normalOverImage != nil) {
            [self setImage:_normalImage];
            [self setNeedsDisplay:YES];
        }
    } else {
        if (_altOverImage != nil) {
            [self setImage:_altImage];
            [self setNeedsDisplay:YES];
        }
    }
    _inside = NO;
}

- (BOOL)sendAction:(SEL)theAction to:(id)theTarget {
    if (_toggle) {
        if (_state == NSOnState) {
            if (_pulseTimer != nil) {
                [_pulseTimer invalidate];
                _pulseTimer = nil;
            }
            _state = NSOffState;
            [self setImage:(_normalOverImage != nil && _inside ? _normalOverImage : _normalImage)];
            [self setNeedsDisplay:YES];
        } else {
            if (_pulseTimer == nil) {
                _pulseTimer = [NSTimer scheduledTimerWithTimeInterval: 0.1
                                       target: self
                                       selector: @selector(pulse:)
                                       userInfo: nil
                                       repeats: YES];
            }
            _state = NSOnState;
            [self setImage:(_altOverImage != nil && _inside ? _altOverImage : _altImage)];
            [self setNeedsDisplay:YES];
        }
    }
    BOOL retVal = [super sendAction:theAction to:theTarget];
    if (_toggle) {
        if (_state == NSOnState) {
            if (_altDownImage != nil) {
                [self setAlternateImage:_altDownImage];
            } else if (_normalImage != nil && _normalDownImage == nil) {
                [self setAlternateImage:_normalImage];
            }
            [self setNeedsDisplay:YES];
        } else {
            if (_normalDownImage != nil) {
                [self setAlternateImage:_normalDownImage];
            } else if (_altImage != nil && _altDownImage == nil) {
                [self setAlternateImage:_altImage];
            }
            [self setNeedsDisplay:YES];
        }
    }
    return retVal;
}

- (void)mouseDown:(NSEvent *)theEvent {
    _inside = YES;
    [super mouseDown:theEvent];
}

- (int)state {
    return _state;
}

- (void)drawRect:(NSRect)rect {
    [super drawRect:rect];
    if (_pulseImage != nil && _pulseTimer != nil) {
        [_pulseImage setFlipped:[self isFlipped]];
        [_pulseImage drawInRect:[self bounds]
         fromRect:NSMakeRect(0, 0, [_pulseImage size].width, [_pulseImage size].height)
         operation:NSCompositeSourceOver fraction:_pulseOpacity];
    }
}

- (void)pulse:(NSTimer *)timer {
    _pulseOpacity += _pulseTick;
    if (_pulseOpacity < 0 || _pulseOpacity > 1) {
        _pulseTick = -_pulseTick;
        _pulseOpacity += _pulseTick*2;
    }
    [self setNeedsDisplay:YES];
}

@end
