/*
  SRTBISafariStyleCell.m
Author: Hetima Computer

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 <objc/objc-runtime.h>
#import "SRTBISafariStyleCell.h"




#define kHTTabBarIndicatorWidth 16
#define kHTTabBarIndicatorRightMargin 2
#define kHTTabBarIndicatorYActive   2//1.5
#define kHTTabBarIndicatorYInactive 2//1.5




#pragma mark -

#define MARGIN_X        3
#define kPaddingLeft    2
#define kPaddingRight   4
#define MARGIN_Y        4

@implementation SRTBISafariStyleCell



+(NSString*)name
{
    return @"Safari Style";
}


+(float)displayWidthOfString:(NSString*)label withCloseButton:(BOOL)flag
{
    NSMutableAttributedString*  attrStr;
    attrStr=[[[NSMutableAttributedString alloc]initWithString:label]autorelease];
    NSRange range=NSMakeRange(0, [label length]);

    // Add font attribute
    [attrStr addAttribute:NSFontAttributeName value:[NSFont systemFontOfSize:11.0]/*[self font]*/ range:range];
    [attrStr addAttribute:NSParagraphStyleAttributeName value:gTruncatingTailParagraphStyle range:range];

    float   resultWidth=[attrStr size].width;
    if (flag) {
        resultWidth+=[gHTTabBarGeneralCloseBtn size].width;
    }
    resultWidth+=MARGIN_X+MARGIN_Y+kPaddingLeft+kPaddingRight+kPaddingRight;
    return ceilf(resultWidth);
}

+(float)cellHeight
{
    return 22;
}
+(float)cellTopMargin
{
    return 0;
}
+(float)cellBottomMargin
{
    return 0;
}

-(id)initWithKeeperView:(id)keeperView contentView:(id)webView
{
    self = [super initWithKeeperView:keeperView contentView:webView];
    if (self) {

    }
    return self;
}

- (NSString *)description
{
    return [self stringValue];
}



#pragma mark -
#pragma mark ---- draw ----
+(BOOL)canHaveCloseButton
{
    return YES;
}

-(NSRect)closeBtnRectForFrame:(NSRect)cellFrame
{
    NSRect  result;
    
    if(!_hasCloseButton)return NSZeroRect;
    result.size=[gHTTabBarGeneralCloseBtn size];

    result.origin.x =cellFrame.origin.x + MARGIN_X+kPaddingLeft;
    result.origin.y =cellFrame.origin.y + MARGIN_Y;
    return result;

}

+(BOOL)canHaveIndicator
{
    return YES;
}
-(NSRect)indicatorRectForFrame:(NSRect)cellFrame
{
    NSRect  resultRect=cellFrame;
    
    resultRect.size.height=kHTTabBarIndicatorWidth;
    resultRect.size.width=kHTTabBarIndicatorWidth;

    resultRect.origin.x+=(cellFrame.size.width-kHTTabBarIndicatorWidth-(kHTTabBarIndicatorRightMargin*2));
    resultRect.origin.y+=kHTTabBarIndicatorYActive;

    return resultRect;
}

-(void)drawBackgroundRect:(NSRect)rect inView:(HTSRTabBarView *)controlView
{
    NSColor*    lineColor;
    float   alpha;
    float x=rect.origin.x;
    float y=rect.origin.y;
    NSRect  fillRect=rect;
    //hilite bottom 1 pixel
    fillRect.size.height-=1.5;
    //fillRect.origin.y+=0.5;

    if([[controlView window]styleMask]&NSTexturedBackgroundWindowMask){
        lineColor=[NSColor darkGrayColor];
        alpha=0.2;
    }else{
        lineColor=[NSColor controlShadowColor];
        alpha=0.08;
    }
    
    [[NSColor colorWithCalibratedWhite:0.0 alpha:alpha]set];
    NSRectFillUsingOperation(fillRect, NSCompositeSourceAtop);
    
    // Get tab view type
    HTSRTabViewType tabViewType;
    tabViewType = [controlView tabViewType];
    
    //frame
    [lineColor set];
    [NSBezierPath strokeLineFromPoint:NSMakePoint(x,y+0.5) toPoint:NSMakePoint(x+rect.size.width,y+0.5)];
    [NSBezierPath strokeLineFromPoint:NSMakePoint(x,y+rect.size.height-0.5) toPoint:NSMakePoint(x+rect.size.width,y+rect.size.height-0.5)];
    
    if (tabViewType == HTSRLeftTabsBezelBorder || 
        tabViewType == HTSRRightTabsBezelBorder)
    {
        [NSBezierPath strokeLineFromPoint:NSMakePoint(x+0.5,y) toPoint:NSMakePoint(x+0.5,y+rect.size.height)];
        [NSBezierPath strokeLineFromPoint:NSMakePoint(x+rect.size.width-0.5,y) toPoint:NSMakePoint(x+rect.size.width-0.5,y+rect.size.height)];
    }
}


- (void)drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
{
    // Cretae bezier path
    NSBezierPath*   bezier = [NSBezierPath bezierPath];
    
    // Decide line color
    NSColor*    lineColor;
    if ([[controlView window]styleMask]&NSTexturedBackgroundWindowMask) {
        lineColor = [NSColor darkGrayColor];
    } else {
        lineColor = [NSColor controlShadowColor];
    }
    
    // Get tab view type
    HTSRTabViewType tabViewType;
    tabViewType = [_keeperView tabViewType];
    
    // When tab is selected
    if ([self state] == NSOnState) {
        // Decide rect
        NSRect  aRect = NSZeroRect;
        switch (tabViewType) {
        case HTSRTopTabsBezelBorder: {
            aRect=NSMakeRect(cellFrame.origin.x, cellFrame.origin.y,
                                cellFrame.size.width, cellFrame.size.height-3.0);
            break;
        }
        case HTSRLeftTabsBezelBorder: {
            aRect=NSMakeRect(cellFrame.origin.x + 2.0, cellFrame.origin.y,
                                cellFrame.size.width - 3.0, cellFrame.size.height);
            break;
        }
        case HTSRRightTabsBezelBorder: {
            aRect=NSMakeRect(cellFrame.origin.x, cellFrame.origin.y,
                                cellFrame.size.width - 5.0, cellFrame.size.height);
        }
        case HTSRBottomTabsBezelBorder: {
        }
        }
        
        // Draw background
        if ([controlView inLiveResize] && 
            ([[controlView window]styleMask]&NSTexturedBackgroundWindowMask) && 
            [[controlView window] respondsToSelector:@selector(_scaledBackground)] && 
            [[controlView window] respondsToSelector:@selector(_texturePattern)])
        {
            [objc_msgSend([controlView window],@selector(_scaledBackground)) set];
            NSRectFillUsingOperation(aRect, NSCompositeCopy);
            
            [objc_msgSend([controlView window],@selector(_texturePattern)) set];
            NSRectFillUsingOperation(aRect, NSCompositeSourceOver);

        } else {
            NSDrawWindowBackground(aRect);
        }
        
        // Draw frame
        [lineColor set];
        switch (tabViewType) {
        case HTSRTopTabsBezelBorder: {
            aRect.size.height+=0.5;
            aRect.origin.x+=0.5;
            
            [bezier moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y)];

            [bezier lineToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y+aRect.size.height-1.5)];
            [bezier lineToPoint:NSMakePoint(aRect.origin.x+1.5, aRect.origin.y+aRect.size.height)];

            [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width-1.5, aRect.origin.y+aRect.size.height)];
            [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width, aRect.origin.y+aRect.size.height-1.5)];

            [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width, aRect.origin.y)];
            break;
        }
        case HTSRLeftTabsBezelBorder: {
            aRect.origin.x-=0.5;
            aRect.size.width+=0.5;
            aRect.origin.y+=0.5;
            
            [bezier moveToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y)];

            [bezier lineToPoint:NSMakePoint(aRect.origin.x + 1.5, aRect.origin.y)];
            [bezier lineToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y + 1.5)];
            
            [bezier lineToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y + aRect.size.height - 1.5)];
            [bezier lineToPoint:NSMakePoint(aRect.origin.x + 1.5, aRect.origin.y + aRect.size.height)];
            
            [bezier lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width, aRect.origin.y + aRect.size.height)];
            break;
        }
        case HTSRRightTabsBezelBorder: {
            aRect.origin.x+=0.5;
            aRect.size.width-=0.5;
            aRect.origin.y+=0.5;
            
            [bezier moveToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y)];

            [bezier lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width - 1.5, aRect.origin.y)];
            [bezier lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width , aRect.origin.y + 1.5)];
            
            [bezier lineToPoint:NSMakePoint(aRect.origin.x + aRect.size.width , aRect.origin.y + aRect.size.height - 1.5)];
            [bezier lineToPoint:NSMakePoint(aRect.origin.x  + aRect.size.width - 1.5, aRect.origin.y + aRect.size.height)];
            
            [bezier lineToPoint:NSMakePoint(aRect.origin.x, aRect.origin.y + aRect.size.height)];
            break;
        }
        case HTSRBottomTabsBezelBorder: {
        }
        }
        [bezier stroke];
    }
    // When tab is not selected
    else {
        // Decide rect
        NSRect  aRect=NSMakeRect(cellFrame.origin.x,cellFrame.origin.y,cellFrame.size.width,cellFrame.size.height);
        switch (tabViewType) {
        case HTSRTopTabsBezelBorder: {
            aRect.origin.y+=0.5;
            aRect.origin.x+=1.5;
            aRect.size.width-=1;
            break;
        }
        case HTSRLeftTabsBezelBorder: {
            aRect.origin.x-=0.5;
            aRect.origin.y+=1.5;
            aRect.size.height-=1;
            break;
        }
        case HTSRRightTabsBezelBorder: {
            aRect.origin.x+=0.5;
            aRect.origin.y+=1.5;
            aRect.size.height-=1;
            break;
        }
        }
        
        // Draw background
        if(_trackingMode == track_normal && _trackingHilite) {
            int tabState=[self tabState];
            float   x=aRect.origin.x;
            float alpha;
            if([[controlView window]styleMask]&NSTexturedBackgroundWindowMask){
                alpha=0.2;
            }else{
                alpha=0.1;
            }
            if (tabState & HTSRTab_PositionLeftMask) {
                aRect.size.width += [(HTSRTabBarView*)controlView leftMargin];
                aRect.origin.x = 0;
                x = 1.5;
            }
            [[NSColor colorWithCalibratedWhite:0.0 alpha:alpha] set];
            NSRectFillUsingOperation(aRect, NSCompositeSourceAtop); 
            aRect.origin.x=x;
        }
        
        switch (tabViewType) {
        case HTSRTopTabsBezelBorder: {
            aRect.origin.x-=1;
            aRect.size.width+=1;
            break;
        }
        case HTSRLeftTabsBezelBorder: {
            aRect.origin.y-=1;
            aRect.size.height+=1;
            break;
        }
        case HTSRRightTabsBezelBorder: {
            aRect.origin.y-=1;
            aRect.size.height+=1;
            break;
        }
        }
        
        // Draw frame
        [lineColor set];
        switch (tabViewType) {
        case HTSRTopTabsBezelBorder: {
            [bezier moveToPoint:NSMakePoint(aRect.origin.x,aRect.origin.y)];
            [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width,aRect.origin.y)];
            if(!([self tabState] & HTSRTab_RightIsSelectedMask)){
                [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width,aRect.origin.y+aRect.size.height)];
            }
            break;
        }
        case HTSRLeftTabsBezelBorder:
        case HTSRRightTabsBezelBorder: {
            [bezier moveToPoint:NSMakePoint(aRect.origin.x+aRect.size.width,aRect.origin.y)];
            [bezier lineToPoint:NSMakePoint(aRect.origin.x+aRect.size.width,aRect.origin.y+aRect.size.height)];
            if(!([self tabState] & HTSRTab_RightIsSelectedMask)){
                [bezier lineToPoint:NSMakePoint(aRect.origin.x,aRect.origin.y+aRect.size.height)];
            }
            break;
        }
        }
        [bezier stroke];
        
        // Light highlight
        if(![self isHighlighted]){
            float   shadowAlpha=0.1;
            [[NSColor colorWithCalibratedWhite:1.0 alpha:shadowAlpha]set];
            
            switch (tabViewType) {
            case HTSRTopTabsBezelBorder: {
                if(!([self tabState] & HTSRTab_RightIsSelectedMask)){
                    [NSBezierPath strokeLineFromPoint: NSMakePoint(aRect.origin.x+aRect.size.width-1,aRect.origin.y+0.5)
                            toPoint:NSMakePoint(aRect.origin.x+aRect.size.width-1,aRect.origin.y+aRect.size.height-0.5)];
                }
                if(!([self tabState] & (HTSRTab_LeftIsSelectedMask | HTSRTab_PositionLeftMask))){
                    [NSBezierPath strokeLineFromPoint: NSMakePoint(aRect.origin.x+1,aRect.origin.y+0.5)
                            toPoint:NSMakePoint(aRect.origin.x+1,aRect.origin.y+aRect.size.height-1.5)];
                }
            }
            }
        }
    }
    
    [self drawInteriorWithFrame:cellFrame inView:controlView];
}



- (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView*)controlView
{
    NSSize  iconSize = NSZeroSize;

    HTSRTabViewType tabViewType;
    tabViewType = [_keeperView tabViewType];
    
    // Draw Image
    if (_hasCloseButton) {
        NSRect  iconRect=[self closeBtnRectForFrame:cellFrame];
        NSImage*    icon=gHTTabBarGeneralCloseBtn;
        if(_trackingMode==track_ROver_close_btn)icon=gHTTabBarGeneralCloseROver;
        if(_trackingMode==track_close_btn && _trackingHilite)icon=gHTTabBarGeneralClosePress;
        iconSize=[icon size];
        
        if([controlView isFlipped]) {
            iconRect.origin.y += iconSize.height;
        }
        float alpha;
        if([[controlView window]styleMask]&NSTexturedBackgroundWindowMask){
            alpha=1.0;
        }else{
            alpha=0.66;
        }
        [icon compositeToPoint:iconRect.origin operation:NSCompositeSourceOver fraction:alpha];
    }

    // calc size
    NSRect  pathRect;

    switch (tabViewType) {
    case HTSRTopTabsBezelBorder:
    case HTSRBottomTabsBezelBorder: {
        pathRect.origin.x = cellFrame.origin.x + MARGIN_X+kPaddingLeft;
        if(iconSize.width > 0) {
            pathRect.origin.x += iconSize.width + MARGIN_X;
        }
        pathRect.size.width = cellFrame.size.width - (pathRect.origin.x - cellFrame.origin.x)-kPaddingRight;
        pathRect.size.height = cellFrame.size.height;
        pathRect.origin.y = cellFrame.origin.y+MARGIN_Y ;

        if(_isLoading){
            float   canvasWidth=pathRect.size.width-kHTTabBarIndicatorWidth-kHTTabBarIndicatorRightMargin;
            if(_stringSize.width>=canvasWidth)
                pathRect.size.width=canvasWidth;
        }
        
        break;
    }
    case HTSRLeftTabsBezelBorder: {
        pathRect.origin.y = cellFrame.origin.y + MARGIN_X+kPaddingLeft;
        if(iconSize.width > 0) {
            pathRect.origin.y += iconSize.width + MARGIN_X;
        }
        pathRect.size.height = cellFrame.size.height - (pathRect.origin.y - cellFrame.origin.y)-kPaddingRight;
        pathRect.size.width = cellFrame.size.width;
        pathRect.origin.x = cellFrame.origin.x+MARGIN_Y ;

        break;
    }
    case HTSRRightTabsBezelBorder: {
        pathRect.origin.y = cellFrame.origin.y + MARGIN_X+kPaddingLeft;
        if(iconSize.width > 0) {
            pathRect.origin.y += iconSize.width + MARGIN_X;
        }
        pathRect.size.height = cellFrame.size.height - (pathRect.origin.y - cellFrame.origin.y)-kPaddingRight;
        pathRect.size.width = cellFrame.size.width - MARGIN_Y;
        pathRect.origin.x = cellFrame.origin.x;

        break;
    }
    }

    [self _drawLabelInRect:pathRect offScreen:NO];
}

-(void)_drawLabelInRect:(NSRect)aRect offScreen:(BOOL)flag
{
    NSRect  frame;
    frame = [_keeperView frame];
    
    HTSRTabViewType tabViewType;
    tabViewType = [_keeperView tabViewType];
    
    // Draw text
    NSMutableAttributedString*  attrStr=[[[NSMutableAttributedString alloc]initWithAttributedString:
                                        [self attributedStringValue]]autorelease];
    if (attrStr) {
        NSRange range=NSMakeRange(0, [attrStr length]);

        // Add shadow attribute
        if ([[_keeperView window] styleMask] & NSTexturedBackgroundWindowMask) {
            NSShadow*   shadow;
            shadow = [[[NSShadow alloc] init] autorelease];
            float   shadowAlpha;
            if([self state]==NSOnState||[self isHighlighted])shadowAlpha=0.8;
            else shadowAlpha=0.5;

            [shadow setShadowColor:[NSColor colorWithCalibratedWhite:1.0 alpha:shadowAlpha]];
            [shadow setShadowOffset:NSMakeSize(0, -1)];
            [shadow setShadowBlurRadius:1.0];
            [attrStr addAttribute:NSShadowAttributeName value:shadow range:range];
        }
        
        switch (tabViewType) {
        case HTSRTopTabsBezelBorder:
        case HTSRBottomTabsBezelBorder: {
            [attrStr drawInRect:aRect];
            break;
        }
        case HTSRLeftTabsBezelBorder: {
            [[NSGraphicsContext currentContext] saveGraphicsState];
            
            NSAffineTransform*  affine;
            affine = [NSAffineTransform transform];
            [affine translateXBy:aRect.size.width / 2.0f 
                    yBy:frame.size.height - aRect.origin.y];
//            [affine translateXBy:10 + aRect.size.width / 2.0f 
//                    yBy:frame.size.height - aRect.origin.y];
            [affine rotateByDegrees:-90.0f];
            [affine set];
            
            NSImage*    image;
            image = [[NSImage alloc] initWithSize:[attrStr size]];
            [image autorelease];
            
            [image lockFocus];
            [attrStr drawAtPoint:NSZeroPoint];
            [image unlockFocus];
            
            NSRect  srcRect;
            srcRect.origin = NSZeroPoint;
            srcRect.size = [image size];
            [image drawAtPoint:NSZeroPoint fromRect:srcRect operation:NSCompositeSourceOver fraction:1.0f];
            
            [[NSGraphicsContext currentContext] restoreGraphicsState];
            break;
        }
        case HTSRRightTabsBezelBorder: {
            [[NSGraphicsContext currentContext] saveGraphicsState];
            
            NSAffineTransform*  affine;
            affine = [NSAffineTransform transform];
            [affine translateXBy:frame.origin.x + aRect.size.width / 2.0f 
                    yBy:frame.size.height - aRect.origin.y];
            [affine rotateByDegrees:-90.0f];
            [affine set];
            
            NSImage*    image;
            image = [[NSImage alloc] initWithSize:[attrStr size]];
            [image autorelease];
            
            [image lockFocus];
            [attrStr drawAtPoint:NSZeroPoint];
            [image unlockFocus];
            
            NSRect  srcRect;
            srcRect.origin = NSZeroPoint;
            srcRect.size = [image size];
            [image drawAtPoint:NSZeroPoint fromRect:srcRect operation:NSCompositeSourceOver fraction:1.0f];
            
            [[NSGraphicsContext currentContext] restoreGraphicsState];
            break;
        }
        }
    }

}


-(NSImage*)dragImageForRect:(NSRect)cellFrame
{
    NSImage* resultImage=[[[NSImage alloc]initWithSize:cellFrame.size]autorelease];
    if(resultImage){
        cellFrame.origin=NSZeroPoint;
        [resultImage lockFocus];
        //draw frame
        [[NSColor colorWithCalibratedWhite:0.1 alpha:0.16]set];
        NSRectFillUsingOperation(cellFrame, NSCompositeSourceAtop);
        NSRectFill(cellFrame);
        [[NSColor grayColor]set];
        NSFrameRect(cellFrame);
        
        //draw label
        cellFrame.origin.y+=MARGIN_Y;
        cellFrame.size.height = _stringSize.height;
        [self _drawLabelInRect:cellFrame offScreen:YES];

        [resultImage unlockFocus];
    }
    return resultImage;
    
}
#pragma mark -



- (void)setStringValue:(NSString *)aString
{
    NSMutableAttributedString*  attrStr;
    attrStr=[[[NSMutableAttributedString alloc]initWithString:aString] autorelease];
    NSRange range=NSMakeRange(0, [aString length]);

    // Add font attribute
    if ([self font]) {
        [attrStr addAttribute:NSFontAttributeName value:[self font] range:range];
    }
    else {
        [attrStr addAttribute:NSFontAttributeName value:[NSFont boldSystemFontOfSize:11.0] range:range];
    }
    [attrStr addAttribute:NSForegroundColorAttributeName value:
                        [[NSColor textColor]colorWithAlphaComponent:0.75] range:range];
    [attrStr addAttribute:NSParagraphStyleAttributeName value:gTruncatingTailParagraphStyle range:range];

    [self setAttributedStringValue:attrStr];
    _stringSize=[attrStr size];
}



-(float)stringWidth
{
    return _stringSize.width;
}

#pragma mark -- Tab view type --

+ (BOOL)supportTabViewType:(HTSRTabViewType)tabViewType
{
    return tabViewType == HTSRTopTabsBezelBorder || 
           tabViewType == HTSRLeftTabsBezelBorder || 
           tabViewType == HTSRRightTabsBezelBorder;
}


@end
