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

// Notification
NSString*   SRPrefViewPreferenceSelected = @"SRPrefViewPreferenceSelected";

// Constant
int SRPrefColumnNumber = 6;

@implementation SRPrefView

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

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (!self) {
        return nil;
    }
    
    // Initialize instance variables
    _buttons = [[NSMutableArray array] retain];
    _textFields = [[NSMutableArray array] retain];
    _width = frame.size.width;
    
    return self;
}

- (void)dealloc
{
    [_buttons release];
    [_textFields release];
    [_prefBundleIds release];
    [_prefIcons release];
    [_prefLabels release];
    
    [super dealloc];
}

//--------------------------------------------------------------//
#pragma mark -- Preference info --
//--------------------------------------------------------------//

- (void)setPreferenceIds:(NSArray*)prefIds icons:(NSArray*)prefIcons labels:(NSArray*)prefLabels
{
    // Copy preference info
    [_prefBundleIds release];
    _prefBundleIds = [[NSArray arrayWithArray:prefIds] retain];
    [_prefIcons release];
    _prefIcons = [[NSArray arrayWithArray:prefIcons] retain];
    [_prefLabels release];
    _prefLabels = [[NSArray arrayWithArray:prefLabels] retain];
    
    // Update layout
    [self createButtons];
    [self updateButtonsLayout];
}

//--------------------------------------------------------------//
#pragma mark -- Layout --
//--------------------------------------------------------------//

- (void)createButtons
{
    // Remove all subviews
    [[self subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
    [_buttons removeAllObjects];
    [_textFields removeAllObjects];
    
    // Create buttons
    int i;
    for (i = 0; i < [_prefIcons count]; i++) {
        // Get image
        NSImage*    image;
        image = [_prefIcons objectAtIndex:i];
        
        // Get bundle ID
        NSString*   bundleId;
        bundleId = [_prefBundleIds objectAtIndex:i];
        
        // Create button
        NSButton*   button;
        button = [[NSButton alloc] initWithFrame:NSZeroRect];
        [button setButtonType:NSMomentaryChangeButton];
        if (![image isEqual:[NSNull null]]) {
            [button setImage:image];
        }
        [button setImagePosition:NSImageOnly];
        [button setBordered:NO];
        [[button cell] setRepresentedObject:bundleId];
        [button setTarget:self];
        [button setAction:@selector(selectPreferenceAction:)];
        
        [self addSubview:button];
        [_buttons addObject:button];
        [button release];
    }
    
    // Create text fields
    NSEnumerator*   enumerator;
    NSString*       label;
    enumerator = [_prefLabels objectEnumerator];
    while (label = [enumerator nextObject]) {
        NSTextField*    textField;
        textField = [[NSTextField alloc] initWithFrame:NSZeroRect];
        [textField setFont:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]]];
        [textField setAlignment:NSCenterTextAlignment];
        [textField setBordered:NO];
        [textField setEditable:NO];
        [textField setSelectable:NO];
        [textField setDrawsBackground:NO];
        if (![label isEqual:[NSNull null]]) {
            [textField setStringValue:label];
        }
        
        [self addSubview:textField];
        [_textFields addObject:textField];
        [textField release];
    }
}

static float    SRPrefViewXMargin = 8.0f;
static float    SRPrefViewYMargin = 8.0f;
static float    SRPrefViewButtonSize = 32.0f;
static float    SRPrefViewTextFieldWidth = 88.0f;
static float    SRPrefViewTextFieldHeight = 36.0f;
static float    SRPrefViewYMarginBetweenButtonAndText = 8.0f;

- (void)updateButtonsLayout
{
    // Decide column and row
    int column, row;
    column = (_width - SRPrefViewYMargin) / (SRPrefViewTextFieldWidth + SRPrefViewYMargin);
    row = [_buttons count] / column + ([_buttons count] % column > 0 ? 1 : 0);
    
    // Set frame
    NSRect  frame;
    frame.origin = NSZeroPoint;
    frame.size.width = _width;
    frame.size.height = (SRPrefViewYMargin + SRPrefViewButtonSize + 
            SRPrefViewYMarginBetweenButtonAndText + SRPrefViewTextFieldHeight) * row - 1;
    [self setFrame:frame];
    
    // Set start position
    float   x, y;
    x = SRPrefViewXMargin;
    y = frame.size.height - SRPrefViewYMargin;
    
    // Update layout
    int i;
    for (i = 0; i < [_buttons count]; i++) {
        // Get button and text field
        NSButton*       button;
        NSTextField*    textField;
        button = [_buttons objectAtIndex:i];
        textField = [_textFields objectAtIndex:i];
        
        // Decide button frame
        NSRect  buttonFrame;
        buttonFrame.origin.x = x + (SRPrefViewTextFieldWidth - SRPrefViewButtonSize) / 2.0f;
        buttonFrame.origin.y = y - SRPrefViewButtonSize;
        buttonFrame.size.width = SRPrefViewButtonSize;
        buttonFrame.size.height = SRPrefViewButtonSize;
        
        [button setFrame:buttonFrame];
        
        // Decide text field frame
        NSRect  textFrame;
        textFrame.origin.x = x;
        textFrame.origin.y = y - SRPrefViewButtonSize - 
                SRPrefViewYMarginBetweenButtonAndText - SRPrefViewTextFieldHeight;
        textFrame.size.width = SRPrefViewTextFieldWidth;
        textFrame.size.height = SRPrefViewTextFieldHeight;
        
        [textField setFrame:textFrame];
        
        // Move position
        x += SRPrefViewTextFieldWidth + SRPrefViewXMargin;
        
        // Check wrap
        if (x + SRPrefViewTextFieldWidth + SRPrefViewXMargin > frame.size.width) {
            x = SRPrefViewXMargin;
            y -= SRPrefViewButtonSize + SRPrefViewYMarginBetweenButtonAndText + 
                    SRPrefViewTextFieldHeight + SRPrefViewYMargin;
        }
    }
}

//--------------------------------------------------------------//
#pragma mark -- Action --
//--------------------------------------------------------------//

- (void)selectPreferenceAction:(id)sender
{
    // Get bundle ID
    NSString*   bundleId;
    bundleId = [[sender cell] representedObject];
    if (!bundleId) {
        return;
    }
    
    // Notify preference selection
    NSDictionary*   userInfo;
    userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
            bundleId, @"bundleID", nil];
    [[NSNotificationCenter defaultCenter] 
            postNotificationName:SRPrefViewPreferenceSelected object:self userInfo:userInfo];
}

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

- (void)drawRect:(NSRect)rect
{
    // Fill with window background
    NSDrawWindowBackground(rect);
    
    // Get frame
    NSRect  frame;
    frame = [self frame];
    
    // Prepare background color
    static NSColor* _altBackgroundColor = nil;
    static NSColor* _altGridColor = nil;
    if (!_altBackgroundColor) {
        _altBackgroundColor = [[[NSColor blackColor] colorWithAlphaComponent:0.05f] retain];
        _altGridColor = [[[NSColor blackColor] colorWithAlphaComponent:0.1f] retain];
    }
    
    // Fill background
    NSRect  fillRect;
    BOOL    alt = NO;
    fillRect.size.width = frame.size.width;
    fillRect.size.height = SRPrefViewYMargin + SRPrefViewButtonSize + 
            SRPrefViewYMarginBetweenButtonAndText + SRPrefViewTextFieldHeight;
    fillRect.origin.x = 0;
    fillRect.origin.y = frame.origin.y + frame.size.height - fillRect.size.height;
    while (fillRect.origin.y + fillRect.size.height > 0) {
        if (NSIntersectsRect(rect, frame)) {
            if (alt) {
                [_altBackgroundColor set];
                NSRectFillUsingOperation(fillRect, NSCompositeSourceOver);
                
                [_altGridColor set];
                
                NSRect  gridRect;
                gridRect.origin.x = fillRect.origin.x;
                gridRect.origin.y = fillRect.origin.y;
                gridRect.size.width = fillRect.size.width;
                gridRect.size.height = 1.0f;
                NSRectFillUsingOperation(gridRect, NSCompositeSourceOver);
                
                gridRect.origin.x = fillRect.origin.x;
                gridRect.origin.y = fillRect.origin.y + fillRect.size.height;
                gridRect.size.width = fillRect.size.width;
                gridRect.size.height = 1.0f;
                NSRectFillUsingOperation(gridRect, NSCompositeSourceOver);
            }
        }
        
        fillRect.origin.y -= fillRect.size.height;
        alt = !alt;
    }
}

@end
