/*
SRBookmarkButtonCell.m

Author: Makoto Kinoshita

Copyright 2004 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 "SRDefaultsKey.h"

#import "SRBookmark.h"

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

#import "AppKitEx.h"

#define kDropDownLeftMargin 3

static const int    SRBookmarkButtonMarginWidth = 2;
static const int    SRBookmarkButtonMarginHeight = 2;
static const int    SRBookmarkButtonMinWidth = 12;
static const int    SRBookmarkButtonMaxWidth = 144;

@implementation SRBookmarkButtonCell

- (id)init
{
    self = [super init];
    if (self) {
        [self setBordered:NO];
    }
    return self;
}

- (NSMutableAttributedString*)attributedStringTitle
{
    NSString*   title;
    title = [self title];
    if (!title) {
        return nil;
    }
    
    // Create attributed string
    NSMutableAttributedString*  attrStr;
    attrStr = [[NSMutableAttributedString alloc] 
            initWithString:title 
            attributes:[NSDictionary dictionaryWithObject:[self font] 
                    forKey:NSFontAttributeName]];
    [attrStr autorelease];
    
    return attrStr;
}

- (NSMutableAttributedString*)truncatedAttributedStringTitleForWidth:(int)width
{
    NSString*   title;
    title = [self title];
    if (!title) {
        return nil;
    }
    
    // Create attributed string
    NSMutableAttributedString*  attrStr;
    attrStr = [[NSMutableAttributedString alloc] 
            initWithString:title 
            attributes:[NSDictionary dictionaryWithObject:[self font] 
                    forKey:NSFontAttributeName]];
    [attrStr autorelease];
    
    // Truncate string
    if ([attrStr size].width > width) {
        NSAttributedString* truncated;
        truncated = [attrStr truncateForWidth:width];
        
        attrStr = [[NSMutableAttributedString alloc] initWithAttributedString:truncated];
        [attrStr autorelease];
    }
    
    return attrStr;
}

- (void)drawInteriorWithFrame:(NSRect)cellFrame 
        inView:(NSView*)controlView
{
    NSUserDefaults* defaults;
    defaults = [NSUserDefaults standardUserDefaults];
    
    // Check favicon availability
    BOOL    isFaviconUsed, isFaviconUsedBookmarkBar;
    isFaviconUsed = [defaults boolForKey:SRIconUseFavicon];
    isFaviconUsedBookmarkBar = [defaults boolForKey:SRIconUseFaviconBookmarkBar];
    
    // Clip menu
    if ([(SRBookmarkButton*)[self controlView] isClipMenu]) {
        // Get clip indicator image
        static NSImage* _clipIndicator = nil;
        static NSImage* _clipIndicatorPressed = nil;
        static NSSize   _clipSize;
        if (!_clipIndicator) {
            _clipIndicator = [[NSImage imageNamed:@"ClipIndicator"] retain];
            _clipIndicatorPressed = [[NSImage imageNamed:@"ClipIndicatorPressed"] retain];
            _clipSize = [_clipIndicator size];
        }
        
        // Draw image
        NSPoint point;
        point = NSMakePoint(
                (cellFrame.size.width - _clipSize.width) / 2, 
                cellFrame.size.height - ((cellFrame.size.height - _clipSize.height) / 2));
        if (![self isHighlighted]) {
            [_clipIndicator compositeToPoint:point operation:NSCompositeSourceOver];
        }
        else {
            [_clipIndicatorPressed compositeToPoint:point operation:NSCompositeSourceOver];
        }
        
        return;
    }
    
    int imageWidth = 0;
    
    // Draw image
    NSImage*    image;
    image = [self image];
    if (image && isFaviconUsed && isFaviconUsedBookmarkBar) {
        NSSize  imageSize = [image size];
        imageWidth = imageSize.width + 3;
        
        if ([self isHighlighted]) {
            // Make tinted image
            NSImage*    newImage;
            newImage = [[[NSImage alloc] initWithSize:imageSize] autorelease];
            
            [newImage lockFocus];
            [image compositeToPoint:NSZeroPoint operation:NSCompositeSourceOver];
            
            NSColor*    tintColor;
            tintColor = [NSColor colorWithCalibratedWhite:0.0 alpha:0.5];
            [tintColor set];
            NSRectFillUsingOperation(NSMakeRect(0, 0, imageSize.width, imageSize.height), NSCompositeSourceAtop);
            [newImage unlockFocus];
            
            image = newImage;
        }
        
        // Draw image
        [image compositeToPoint:NSMakePoint(
                SRBookmarkButtonMarginWidth, 
                imageSize.height + SRBookmarkButtonMarginHeight) 
                operation:NSCompositeSourceOver];
    }
    
    int titleWidth = 0;
    
    // Draw title
    NSMutableAttributedString*  attrStr;
    attrStr = [self truncatedAttributedStringTitleForWidth:cellFrame.size.width - imageWidth];
    if (attrStr) {
        if ([self isHighlighted]) {
            NSShadow*   shadow;
            shadow = [[[NSShadow alloc] init] autorelease];
            [shadow setShadowColor:[NSColor colorWithCalibratedWhite:0.0 alpha:0.5]];
            [shadow setShadowOffset:NSMakeSize(0, -1)];
            [shadow setShadowBlurRadius:1.0];
            
            // Add shadow attribute
            [attrStr addAttribute:NSShadowAttributeName 
                    value:shadow 
                    range:NSMakeRange(0, [attrStr length])];
        }else if([[controlView window]styleMask] & NSTexturedBackgroundWindowMask){
            //etching in metal
            NSShadow*   shadow;
            shadow = [[[NSShadow alloc] init] autorelease];
            float   shadowAlpha=0.75;
            [shadow setShadowColor:[NSColor colorWithCalibratedWhite:1.0 alpha:shadowAlpha]];
            [shadow setShadowOffset:NSMakeSize(0, -1)];
            [shadow setShadowBlurRadius:1.0];
            [attrStr addAttribute:NSShadowAttributeName value:shadow range:NSMakeRange(0, [attrStr length])];
        }
        
        // Draw text
        [attrStr drawAtPoint:NSMakePoint(
                imageWidth + SRBookmarkButtonMarginWidth, SRBookmarkButtonMarginHeight)]; 
        
        titleWidth = [attrStr size].width;
    }
    
    // Draw folder marker
    SRBookmark* bookmark;
    bookmark = [(SRBookmarkButton*)[self controlView] bookmark];
    if ([bookmark isFolderType]) {
        NSImage*    markerImage = nil;
        NSSize      markerSize;
        
        // Check auto tab
        if ([bookmark isAutoTab]) {
            static NSImage* _autoTabMarker = nil;
            if (!_autoTabMarker) {
                _autoTabMarker = [[NSImage imageNamed:@"AutoTabMarker"] retain];
            }
            markerImage = _autoTabMarker;
        }
        else {
            static NSImage* _dropDownArrow = nil;
            if (!_dropDownArrow) {
                _dropDownArrow = [[NSImage imageNamed:@"DropDownArrow"] retain];
            }
            markerImage = _dropDownArrow;
        }
        markerSize = [markerImage size];
        
        // Draw marker
        [markerImage compositeToPoint:NSMakePoint(
                imageWidth + titleWidth + SRBookmarkButtonMarginWidth + kDropDownLeftMargin, 
                cellFrame.size.height - ((cellFrame.size.height - markerSize.height) / 2)) 
                operation:NSCompositeSourceOver];
    }
}

- (NSSize)cellSize
{
    NSUserDefaults* defaults;
    defaults = [NSUserDefaults standardUserDefaults];
    
    // Check favicon availability
    BOOL    isFaviconUsed, isFaviconUsedBookmarkBar;
    isFaviconUsed = [defaults boolForKey:SRIconUseFavicon];
    isFaviconUsedBookmarkBar = [defaults boolForKey:SRIconUseFaviconBookmarkBar];
    
    // Get bookmark
    SRBookmark* bookmark = nil;
    NSView*     controlView;
    controlView = [self controlView];
    if ([controlView respondsToSelector:@selector(bookmark)]) {
        bookmark = [controlView performSelector:@selector(bookmark)];
    }
    
    // Get image size
    NSImage*    image;
    NSSize      imageSize = NSZeroSize;
    image = [self image];
    if (image && isFaviconUsed && isFaviconUsedBookmarkBar) {
        imageSize = [image size];
    }
    
    // Get text size
    NSMutableAttributedString*  attrStr;
    NSSize                      textSize = NSZeroSize;
    attrStr = [self attributedStringTitle];
    if (attrStr) {
        textSize = [attrStr size];
    }
    
    // Get tab mark size
    NSSize  tabMarkSize = NSZeroSize;
    if (bookmark && [bookmark isFolderType]) {
        tabMarkSize = [(NSImage*)[NSImage imageNamed:@"DropDownArrow"] size];
        tabMarkSize.width+=kDropDownLeftMargin;
    }
    
    // Calc size
    NSSize  size;
    if (imageSize.width == 0 || textSize.width == 0) {
        size.width = imageSize.width + textSize.width + SRBookmarkButtonMarginWidth * 2;
    }
    else {
        size.width = imageSize.width + textSize.width + 3 + SRBookmarkButtonMarginWidth * 2;
    }
    size.width += tabMarkSize.width;
    if (size.width < SRBookmarkButtonMinWidth) {
        size.width = SRBookmarkButtonMinWidth;
    }
    if (size.width > SRBookmarkButtonMaxWidth) {
        size.width = SRBookmarkButtonMaxWidth;
    }
    
    size.height = imageSize.height > textSize.height ? imageSize.height : textSize.height;
    size.height += SRBookmarkButtonMarginHeight * 2;
    
    // Clip menu
    if ([(SRBookmarkButton*)[self controlView] isClipMenu]) {
        static int  _clipIndicatorWidth = -1;
        if (_clipIndicatorWidth == -1) {
            _clipIndicatorWidth = [(NSImage*)[NSImage imageNamed:@"ClipIndicator"] size].width;
        }
        size.width = _clipIndicatorWidth;
    }
    
    // Ceil value
    size.width = ceil(size.width);
    size.height = ceil(size.height);
    
    return size;
}

@end
