/*
SRBookmarkButtonCell.m

Author: Makoto Kinoshita

Copyright 2004-2006 The Shiira Project. 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.

THIS SOFTWARE IS PROVIDED BY THE SHIIRA PROJECT ``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 SHIIRA PROJECT 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 "SRBookmark.h"
#import "SRConstants.h"

#import "SRBookmarkButton.h"
#import "SRBookmarkButtonCell.h"

@implementation SRBookmarkButtonCell

//--------------------------------------------------------------//
#pragma mark -- Initialize --
//--------------------------------------------------------------//

- (id)initTextCell:(NSString*)string
{
    self = [super initTextCell:string];
    if (!self) {
        return nil;
    }
    
    // Configure itself
    [self setBezelStyle:NSRegularSquareBezelStyle];
    [self setBordered:NO];
    [self setButtonType:NSMomentaryChangeButton];
    [self setImagePosition:NSImageRight];
    [self setFont:[NSFont boldSystemFontOfSize:11]];
    
    return self;
}

//--------------------------------------------------------------//
#pragma mark -- Appearance --
//--------------------------------------------------------------//

- (NSDictionary*)_textAttributes
{
    // Get text attributes
    NSMutableDictionary*    attrs;
    attrs = [NSMutableDictionary dictionaryWithDictionary:[super _textAttributes]];
    
    // Decide attributes
    NSColor*    foregroundColor = nil;
    NSShadow*   shadow = nil;
    
    // For highlight on
    if ([self isHighlighted]) {
        foregroundColor = [NSColor whiteColor];
        
        static NSShadow*    _highlightedShadow = nil;
        if (!_highlightedShadow) {
            _highlightedShadow = [[NSShadow alloc] init];
            [_highlightedShadow setShadowColor:[NSColor colorWithCalibratedWhite:0.2f alpha:1.0f]];
            [_highlightedShadow setShadowOffset:NSMakeSize(0, -1)];
            [_highlightedShadow setShadowBlurRadius:1.0];
        }
        
        shadow = _highlightedShadow;
    }
    // For highlight off
    else {
        static NSColor* _defaultForegroundColor = nil;
        if (!_defaultForegroundColor) {
            _defaultForegroundColor = [[NSColor colorWithCalibratedWhite:0.2f alpha:1.0f] retain];
        }
        
        foregroundColor = _defaultForegroundColor;
        
        static NSShadow*    _defaultShadow = nil;
        if (!_defaultShadow) {
            _defaultShadow = [[NSShadow alloc] init];
            [_defaultShadow setShadowColor:[NSColor whiteColor]];
            [_defaultShadow setShadowOffset:NSMakeSize(0, -1)];
            [_defaultShadow setShadowBlurRadius:1.0f];
        }
        
        shadow = _defaultShadow;
    }
    
    // Set attributes
    if (foregroundColor) {
        [attrs setObject:foregroundColor forKey:NSForegroundColorAttributeName];
    }
    if (shadow) {
        [attrs setObject:shadow forKey:NSShadowAttributeName];
    }
    
    return attrs;
}

//--------------------------------------------------------------//
#pragma mark -- Bookmark --
//--------------------------------------------------------------//

- (void)setBookmark:(SRBookmark*)bookmark
{
    [_bookmark release];
    _bookmark = [bookmark retain];
    
    // Set title
    NSString*   title;
    title = [bookmark title];
    if (!title) {
        title = @"";
    }
    
    if ([title length] > 14) {
        title = HMTruncateString(title, 14, NSLineBreakByTruncatingTail);
    }
    [self setTitle:title];
    
    // Set image
    NSImage*    image = nil;
    NSImage*    altImage = nil;
    if ([[bookmark isFolder] boolValue]) {
        if ([[bookmark isAutoTab] boolValue]) {
            image = [NSImage imageNamed:@"bookmarkBind"];
            altImage = [NSImage imageNamed:@"bookmarkBindSelected"];
        }
        else {
            image = [NSImage imageNamed:@"bookmarkDisc"];
            altImage = [NSImage imageNamed:@"bookmarkDiscSelected"];
        }
    }
    else if ([[bookmark type] isEqualToString:SRBookmarkTypeJavaScript]) {
        image = [NSImage imageNamed:@"bookmarkGear"];
        altImage = [NSImage imageNamed:@"bookmarkGearSelected"];
    }
    
    if (image) {
        [image setScalesWhenResized:YES];
        [altImage setScalesWhenResized:YES];
        
        [self setImage:image];
        [self setAlternateImage:altImage];
    }
}

- (SRBookmark*)bookmark
{
    return _bookmark;
}

//--------------------------------------------------------------//
#pragma mark -- Mouse event handling --
//--------------------------------------------------------------//

- (void)mouseEntered:(NSEvent*)event
{
    [[self controlView] setNeedsDisplay:YES];
}

- (void)mouseExited:(NSEvent*)event
{
    [[self controlView] setNeedsDisplay:YES];
}

//--------------------------------------------------------------//
#pragma mark -- Dragging --
//--------------------------------------------------------------//

#if 0
- (BOOL)continueTracking:(NSPoint)lastPoint at:(NSPoint)currentPoint inView:(NSView*)controlView
{
    return YES;
}
#endif

//--------------------------------------------------------------//
#pragma mark -- NSDraggingSourceOperation protocol --
//--------------------------------------------------------------//

- (void)draggedImage:(NSImage*)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
{
    // Post mouse drag and up event
    NSEvent*    mouseDownEvent;
    mouseDownEvent = [(SRBookmarkButton*)[self controlView] mouseDownEvent];
    
    NSEvent*    event;
    event = [NSEvent mouseEventWithType:NSLeftMouseDragged 
            location:NSZeroPoint 
            modifierFlags:[mouseDownEvent modifierFlags] 
            timestamp:[mouseDownEvent timestamp] 
            windowNumber:[mouseDownEvent windowNumber] 
            context:[mouseDownEvent context] 
            eventNumber:[mouseDownEvent eventNumber] 
            clickCount:[mouseDownEvent clickCount] 
            pressure:[mouseDownEvent pressure]];
    [NSApp postEvent:event atStart:NO];
    
    event = [NSEvent mouseEventWithType:NSLeftMouseUp 
            location:NSZeroPoint 
            modifierFlags:[mouseDownEvent modifierFlags] 
            timestamp:[mouseDownEvent timestamp] 
            windowNumber:[mouseDownEvent windowNumber] 
            context:[mouseDownEvent context] 
            eventNumber:[mouseDownEvent eventNumber] 
            clickCount:[mouseDownEvent clickCount] 
            pressure:[mouseDownEvent pressure]];
    [NSApp postEvent:event atStart:NO];
}

//--------------------------------------------------------------//
#pragma mark -- Drawing --
//--------------------------------------------------------------//

- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView*)controlView
{
    // Draw selected background
    if ([self isHighlighted]) {
        NSImage*    leftImage;
        NSImage*    rightImage;
        NSImage*    middleImage;
        leftImage = [NSImage imageNamed:@"bookmarkSelectedL"];
        [leftImage setFlipped:[controlView isFlipped]];
        rightImage = [NSImage imageNamed:@"bookmarkSelectedR"];
        [rightImage setFlipped:[controlView isFlipped]];
        middleImage = [NSImage imageNamed:@"bookmarkSelectedM"];
        [middleImage setFlipped:[controlView isFlipped]];
        
        // Draw left image
        NSRect  srcRect;
        NSRect  destRect;
        srcRect.origin = NSZeroPoint;
        srcRect.size = [leftImage size];
        destRect.origin.x = 0;
        destRect.origin.y = 1;
        destRect.size = srcRect.size;
        [leftImage drawInRect:destRect fromRect:srcRect 
                operation:NSCompositeSourceOver fraction:1.0f];
        
        // Draw right image
        srcRect.origin = NSZeroPoint;
        srcRect.size = [rightImage size];
        destRect.origin.x = cellFrame.size.width - srcRect.size.width;
        destRect.origin.y = 1;
        destRect.size = srcRect.size;
        [rightImage drawInRect:destRect fromRect:srcRect 
                operation:NSCompositeSourceOver fraction:1.0f];
        
        // Draw middle image
        srcRect.origin = NSZeroPoint;
        srcRect.size = [middleImage size];
        destRect.origin.x = [leftImage size].width;
        destRect.origin.y = 1;
        destRect.size.width = cellFrame.size.width - [leftImage size].width - [rightImage size].width;
        destRect.size.height = srcRect.size.height;
        [middleImage drawInRect:destRect fromRect:srcRect 
                operation:NSCompositeSourceOver fraction:1.0f];
    }
    else {
        // Check dragging event
        NSEventType eventType;
        eventType = [[NSApp currentEvent] type];
        if (eventType == NSLeftMouseDragged || eventType == NSRightMouseDragged) {
            // Clear hovered
            [(SRBookmarkButton*)controlView setHovered:NO];
        }
        else {
            // Draw hoverd background
            NSPoint point;
            point = [[controlView window] mouseLocationOutsideOfEventStream];
            point = [controlView convertPoint:point fromView:nil];
            if (NSPointInRect(point, cellFrame)) {
                NSBezierPath*   path;
                path = [NSBezierPath ellipseInRect:NSInsetRect(cellFrame, 0.0f, 1.0f) withRadius:4.0f];
                
                [[NSColor colorWithCalibratedWhite:0.0f alpha:0.075f] set];
                [path fill];
                
                // Set hovered
                [(SRBookmarkButton*)controlView setHovered:YES];
            }
            else {
                // Clear hovered
                [(SRBookmarkButton*)controlView setHovered:NO];
            }
        }
    }
    
    // Draw title and image
    cellFrame.origin.x += 2;
    cellFrame.size.width -= 4;
    [self drawInteriorWithFrame:cellFrame inView:controlView];
}

@end
