/* Copyright (c) 2004, Noah Sorscher
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 	• 	Redistributions of source code must retain the above copyright
 * 	notice, this list of conditions and the following disclaimer.
 * 	• 	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.
 * 	• 	Neither the name of the Noah Sorscher nor the names of its
 * 	contributors may be used to endorse or promote products derived from
 * 	this software without specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER 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.
 */
//
//  MHTableView.m
//  Hootenanny
//
//  Created by Noah Sorscher on Sat Dec 06 2003.
//  Copyright (c) 2003 __MyCompanyName__. All rights reserved.
//

#import "MHTableView.h"
#import "MHFormatter.h"
#import "tInit.h"


@interface NSObject (mhtAdditions)
- (NSArray *)defaultColumnsForTable:(NSTableView *)table;
@end

@interface NSMutableString (shorthand)
- (void)replaceOccurrencesOfString:(NSString *)target withString:(NSString *)replacement;
@end

@implementation NSMutableString (shorthand)
- (void)replaceOccurrencesOfString:(NSString *)target withString:(NSString *)replacement
{
    [self replaceOccurrencesOfString:target withString:replacement options:NSLiteralSearch range:NSMakeRange(0, [self length])];
}
@end


@interface MHTableCell : NSTextFieldCell
{
    NSTableView *myTableView;
}

- (NSSize)sizeOfString:(NSString *)string;
- (void)setTableView:(NSTableView *)table;

@end

@implementation MHTableCell

- (id)init
{
    myTableView = nil;
    return [super init];
}

- (void)selectWithFrame:(NSRect)aRect inView:(NSView *)controlView editor:(NSText *)textObj delegate:(id)anObject start:(int)selStart length:(int)selLength
{
    NSString *string = [[myTableView dataSource] tableView:myTableView objectValueForTableColumn:[[myTableView tableColumns] objectAtIndex:[myTableView selectedColumn]] row:[myTableView selectedRow]];
    NSSize size = [self sizeOfString:string];
    if (size.width > aRect.size.width) aRect.size.width = size.width;
    if (size.height > aRect.size.height) aRect.size.height = size.height;
    [self setWraps:YES];
    [super selectWithFrame:aRect inView:controlView editor:textObj delegate:anObject start:selStart length:selLength];
}


- (NSSize)sizeOfString:(NSString *)string
{
    if (!string || [string isEqualToString:@""]) return NSZeroSize;
    int threash = 60;
    NSAttributedString *aString;
    // height
    NSMutableString *mString = [NSMutableString stringWithString:string];
    [mString replaceOccurrencesOfString:@"\r\n" withString:@"\n"];
    [mString replaceOccurrencesOfString:@"\n\r" withString:@"\n"];
    [mString replaceOccurrencesOfString:@"\r" withString:@"\n"];
    NSArray *lines = [mString componentsSeparatedByString:@"\n"];
    int i, numLines = [lines count];
    for (i=0;i<[lines count];i++) {
        int length = [(NSString *)[lines objectAtIndex:i] length];
        if (length > threash)
            numLines += length / threash;
    }
    NSString *tString = string;
    if ([string length] > 1)
        tString = [string substringToIndex:1];
    aString = [[NSAttributedString alloc] initWithString:tString];
    float height = [aString size].height * numLines;
    if (numLines > 1)
        height += 5;
    [aString release];
    // width
    [mString replaceOccurrencesOfString:@"\n" withString:@""];
    tString = mString;
    if ([mString length] > threash)
        tString = [mString substringToIndex:threash];
    aString = [[NSAttributedString alloc] initWithString:tString];
    float width = [aString size].width;
    [aString release];
    
    return NSMakeSize(width, height);
}

- (void)setTableView:(NSTableView *)table
{
    myTableView = table;
}

@end


@implementation NSTableView (defaultsAdditions)

- (void)autosaveNow
{
	return;
    NSString *name = [self autosaveName];
    if (!name) return;
    NSUserDefaults *defs = [NSUserDefaults standardUserDefaults];
    NSArray *cols = [self tableColumns];
    NSMutableArray *colData = [NSMutableArray array];
    int i;
    
    for (i=0;i<[cols count];i++) {
        NSString *colName = [[cols objectAtIndex:i] identifier];
        int colWidth = [[cols objectAtIndex:i] width];
        //NSLog(@"%@: %g", colName, colWidth);
        [colData addObject:colName];
        [colData addObject:[NSNumber numberWithInt:colWidth]];
    }
    [defs setObject:colData forKey:[NSString stringWithFormat:@"MHTableView %@", name]];
    [defs synchronize];
}

- (void)restoreFromAutosave
{
    NSString *name = [self autosaveName];
    //if (!name)
		return;
    int i;
    NSTableColumn *aColumn;
    NSArray *cols = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"MHTableView %@", name]];
    if (!cols) {
        if ([[self delegate] respondsToSelector:@selector(defaultColumnsForTable:)]) {
            NSArray *newNames = [[self delegate] defaultColumnsForTable:self];
            if (newNames) {
                for (i=0;i<[newNames count];i++)
                    [self addColumnWithName:[newNames objectAtIndex:i]];
            }
        }
    } else {
        //NSArray *tcs = [self tableColumns];
        while ([[self tableColumns] count])
            [self removeTableColumn:[[self tableColumns] objectAtIndex:0]];
        for (i=0;i<[cols count];i+=2) {
            NSString *colName = [cols objectAtIndex:i];
            int colWidth = [[cols objectAtIndex:i+1] intValue];
            aColumn = [self addColumnWithName:colName];
            //[[NSTableColumn alloc] initWithIdentifier:colName];
            //[[aColumn headerCell] setStringValue:colName];
            [aColumn setWidth:colWidth];
	    //[[aColumn dataCell] setFormatter:[[MHFormatter alloc] initWithColumn:aColumn]];
            //[self addTableColumn:aColumn];
        }
    }
}

- (void)restoreFromAutosaveIfPresent
{
    NSString *colName, *name = [self autosaveName];
    if (!name) return;
    NSTableColumn *aColumn;
    NSArray *scols = [[NSUserDefaults standardUserDefaults] objectForKey:[NSString stringWithFormat:@"MHTableView %@", name]];
    if (!scols) return;
    NSArray *ccols = [self tableColumns];
    int i, j, numSaved = [scols count], numCurrent = [ccols count];
    for (i=0;i<numCurrent;i++) {
        aColumn = [ccols objectAtIndex:i];
        colName = [aColumn identifier];
        if (colName) {
            for (j=0;j<numSaved;j+=2) {
                if ([colName isEqualToString:[scols objectAtIndex:j]]) {
                    [aColumn setWidth:[[scols objectAtIndex:j+1] intValue]];
                    break;
                }
            }
        }
    }
}

- (void)removeAllColumns
{
    while ([[self tableColumns] count])
        [self removeTableColumn:[[self tableColumns] objectAtIndex:0]];
}

- (NSTableColumn *)addColumnWithName:(NSString *)aName
{
    if (!aName) aName = @"";
	//NSLog(@"add column %@", aName);
    NSTableColumn *col = [[NSTableColumn alloc] initWithIdentifier:aName];
    [[col headerCell] setStringValue:aName];
    //MHTableCell *c = [MHTableCell new];
    //[c setEditable:YES];
    //[c setTableView:self];
    [[col dataCell] setFormatter:[[MHFormatter alloc] initWithColumn:col]];
    [[col dataCell] setFont:[NSFont systemFontOfSize:[tInit doubleForKey:@"fontSize"]]];
    //[c setWraps:NO];
    //[col setDataCell:c];
    [self addTableColumn:col];
    return col;
}

- (void)selectColumnObject:(NSNumber *)aNum
{
    [self selectColumn:[aNum intValue] byExtendingSelection:NO];
}

@end
