/*
HMToolHeaderView.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 "HMToolHeaderView.h"

@implementation HMToolHeaderButtonCell

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

- (id)initWithHeaderView:(HMToolHeaderView*)headerView 
        headerCell:(NSTableHeaderCell*)headerCell
{
    self = [super init];
    if (!self) {
        return nil;
    }
    
    // Initialize instance variables
    _headerView = headerView;
    _headerCell = [headerCell retain];
    
    return self;
}

- (void)dealloc
{
    [_headerCell release];
    
    [super dealloc];
}

- (BOOL)startTrackingAt:(NSPoint)startPoint 
        inView:(NSView*)controlView
{
    // Make header cell ON state
    [_headerCell setState:NSOnState];
    
    [_headerView setNeedsDisplayInRect:[_headerView cellFrameOfControl:(NSControl*)controlView]];
    
    return YES;
}

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

- (void)stopTracking:(NSPoint)lastPoint 
        at:(NSPoint)stopPoint 
        inView:(NSView*)controlView 
        mouseIsUp:(BOOL)flag
{
    // Make header cell OFF state
    [_headerCell setState:NSOffState];
    
    [_headerView setNeedsDisplayInRect:[_headerView cellFrameOfControl:(NSControl*)controlView]];
}

@end

#pragma mark -

static int  _HMToolHeaderViewHeight = 17;
static int  _HMToolHeaderCellMargin = 1;

@implementation HMToolHeaderView

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

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (!self) {
        return nil;
    }
    
    // Initialize instance variables
    _extraHeaderCell = [[NSTableHeaderCell alloc] initTextCell:@""];
    _headerCells = [[NSMutableArray array] retain];
    _controls = [[NSMutableArray array] retain];
    _controlDict = [[NSMutableDictionary dictionary] retain];
    
	return self;
}

- (void)dealloc
{
    [_extraHeaderCell release];
    [_headerCells release];
    [_controls release];
    [_controlDict release];
    
    [super dealloc];
}

//--------------------------------------------------------------//
#pragma mark -- Item management --
//--------------------------------------------------------------//

- (NSRect)cellFrameOfControl:(NSControl*)control
{
    // Get control frame
    NSRect  frame;
    frame = [control frame];
    
    // For popup
    if ([control isKindOfClass:[NSControl class]]) {
        frame.origin.x -= _HMToolHeaderCellMargin;
        frame.size.width += _HMToolHeaderCellMargin * 2 + 4;
    }
    
    // Other
    else {
        frame.origin.x -= _HMToolHeaderCellMargin;
        frame.size.width += _HMToolHeaderCellMargin * 2;
    }
    
    return frame;
}

- (void)addButtonWithImage:(NSImage*)image identifier:(id)identifier
{
    // Create table header cell
    NSTableHeaderCell*  headerCell;
    headerCell = [[NSTableHeaderCell alloc] initTextCell:@""];
    [headerCell autorelease];
    [_headerCells addObject:headerCell];
    
    // Create header button cell
    HMToolHeaderButtonCell* buttonCell;
    buttonCell = [[HMToolHeaderButtonCell alloc] initWithHeaderView:self headerCell:headerCell];
    [buttonCell autorelease];
    
    // Get last control and its frame
    NSControl*  lastControl;
    NSRect      lastFrame = NSZeroRect;
    lastControl = [_controls lastObject];
    if (lastControl) {
        lastFrame = [self cellFrameOfControl:lastControl];
    }
    
    // Create button
    NSRect  frame;
    if (NSIsEmptyRect(lastFrame)) {
        frame.origin.x = _HMToolHeaderCellMargin;
    }
    else {
        frame.origin.x = lastFrame.origin.x + lastFrame.size.width + _HMToolHeaderCellMargin;
    }
    frame.origin.y = 0;
    frame.size.width = [image size].width + 20;
    frame.size.height = _HMToolHeaderViewHeight;
    
    NSButton*   button;
    button = [[NSButton alloc] initWithFrame:frame];
    [button autorelease];
    [button setCell:buttonCell];
    [button setTitle:@""];
    [button setImage:image];
    [button setBordered:NO];
    [button setButtonType:NSMomentaryChangeButton];
    [button setBezelStyle:NSRegularSquareBezelStyle];
    [button setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
    [button setAutoresizingMask:NSViewMaxXMargin | NSViewMinYMargin];
    
    // Add button
    [self addSubview:button];
    [_controls addObject:button];
    [_controlDict setObject:button forKey:identifier];
}

- (void)addPopupWithMenu:(NSMenu*)menu width:(float)width identifier:(id)identifier
{
    // Create table header cell
    NSTableHeaderCell*  headerCell;
    headerCell = [[NSTableHeaderCell alloc] initTextCell:@""];
    [headerCell autorelease];
    [_headerCells addObject:headerCell];
    
    // Get last control and its frame
    NSControl*  lastControl;
    NSRect      lastFrame = NSZeroRect;
    lastControl = [_controls lastObject];
    if (lastControl) {
        lastFrame = [self cellFrameOfControl:lastControl];
    }
    
    // Create popup
    NSRect  frame;
    if (NSIsEmptyRect(lastFrame)) {
        frame.origin.x = _HMToolHeaderCellMargin;
    }
    else {
        frame.origin.x = lastFrame.origin.x + lastFrame.size.width + _HMToolHeaderCellMargin;
    }
    frame.origin.y = 0;
    frame.size.width = width;
    frame.size.height = _HMToolHeaderViewHeight;
    
    NSPopUpButton*  popup;
    popup = [[NSPopUpButton alloc] initWithFrame:frame];
    [popup autorelease];
    [popup setBordered:NO];
    [popup setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
    [[popup cell] setControlSize:NSSmallControlSize];
    if (menu) {
        [popup setMenu:menu];
    }
    
    // Add popup
    [self addSubview:popup];
    [_controls addObject:popup];
    [_controlDict setObject:popup forKey:identifier];
}

- (NSControl*)itemWithIdentifier:(id)identifier
{
    return [_controlDict objectForKey:identifier];
}

//--------------------------------------------------------------//
#pragma mark -- NSView methods --
//--------------------------------------------------------------//

- (BOOL)isFlipped
{
    return YES;
}

- (void)drawRect:(NSRect)frame
{
    // Draw header cells
    NSRect  cellFrame;
    cellFrame.origin = frame.origin;
    cellFrame.size.width = 0;
    
    int     i;
    for (i = 0; i < [_headerCells count]; i++) {
        // Get header cell and control
        NSTableHeaderCell*  headerCell;
        NSControl*          control;
        headerCell = [_headerCells objectAtIndex:i];
        control = [_controls objectAtIndex:i];
        
        // Draw header  cell
        cellFrame = [self cellFrameOfControl:control];
        [headerCell drawWithFrame:cellFrame inView:self];
    }
    
    // Fill rest area
    if (cellFrame.origin.x + cellFrame.size.width < frame.origin.x + frame.size.width) {
        // Draw extra header  cell
        cellFrame.origin.x += cellFrame.size.width;
        cellFrame.size.width = frame.size.width - frame.origin.x - cellFrame.origin.x + 1;
        
        [_extraHeaderCell drawWithFrame:cellFrame inView:self];
    }
}

@end
