/* 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.
 */
#import "tTextView.h"

@interface NSObject (bs)
- (void)backSpace;
@end

@interface NSString (capsAdditions)
- (int)capitalization;
@end

@implementation NSString (capsAdditions)

// 0 = all lower, 1 = both, 2 = all upper, -1 = none

- (int)capitalization
{
    unichar uch = 0;
    BOOL lower = NO, upper = NO;
    int i, n = [self length];
    for (i=0;i<n;i++) {
        uch = [self characterAtIndex:i];
        if (!lower && uch >= 'a' && uch <= 'z') lower = YES;
        else if (!upper && uch >= 'A' && uch <= 'Z') upper = YES;
        if (lower && upper) return 1;
    }
    if (lower && upper) return 1;
    if (lower) return 0;
    if (upper) return 2;
    return -1;
}

@end

@implementation tTextView

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

- (BOOL)becomeFirstResponder
{
    BOOL result = [super becomeFirstResponder];
    if ([[self delegate] respondsToSelector:@selector(textViewBecameFirstResponder:)])
        [[self delegate] textViewBecameFirstResponder:self];
    return result;
}

- (void) display
{
    [[NSColor blackColor] set];
    [self setTextColor:[NSColor blackColor]];
    [super display];
}

- (void)keyDown:(NSEvent *)theEvent
{
    unichar uch = [[theEvent characters] characterAtIndex:0];
    if (uch == 127) {
    	//[tPlaylist backSpace];
        if ([[self delegate] respondsToSelector:@selector(backSpace)])
            [[self delegate] backSpace];
    } else if (uch == 3 || uch == 13) { // enter and return, respectively
        id d = [self delegate];
        if ([d isKindOfClass:[NSTableView class]]) {
            if ([d isKindOfClass:[iTableView class]] &&
                !([theEvent modifierFlags] & NSAlternateKeyMask)) {
                [d reloadData];
            } else {
                int row = [d editedRow] + 1;
                int col = [d editedColumn];
                if (row >= [d numberOfRows]) row = 0;
                if ([[d delegate] respondsToSelector:@selector(tableView:shouldSelectRow:)])
                    [[d delegate] tableView:d shouldSelectRow:row];
                [d selectRow:row byExtendingSelection:NO];
                [d editColumn:col row:row withEvent:theEvent select:YES];
            }
        } else [super keyDown:theEvent];
        return;
    } else if (uch == '\t' || uch == 25 /* shift tab */) {
        id d = [self delegate];
        if ([d isKindOfClass:[NSTableView class]]) {
            int row = [d editedRow];
            int col, oCol = [d editedColumn];
            if (uch == '\t') col = oCol + 1;
            else col = oCol - 1;
            if (col >= [d numberOfColumns]) col = 0;
            if (col < 0) col = [d numberOfColumns] - 1;
            [d reloadData];
            if ([[d delegate] respondsToSelector:@selector(tableView:shouldEditTableColumn:row:)]) {
                while (![[d delegate] tableView:d shouldEditTableColumn:[[d tableColumns] objectAtIndex:col] row:row]) {
                    if (uch == '\t') col++;
                    else col--;
                    if (col >= [d numberOfColumns]) col = 0;
                    if (col < 0) col = [d numberOfColumns]-1;
                    if (col == oCol) return;
                }
            }
            [d editColumn:col row:row withEvent:nil select:YES];
            return;
        } else {
            [super keyDown:theEvent];
        }
    } else if (uch == 27) { // escape
        NSTableView *d = [self delegate];
        if ([d isKindOfClass:[NSTableView class]]) {
            id oldDataSource = [d dataSource];
            id oldDelegate = [d delegate];
            [d setDataSource:self];
            [d setDelegate:self];
            
            [d reloadData];
            
            [d setDataSource:oldDataSource];
            [d setDelegate:oldDelegate];
        } else {
            [super keyDown:theEvent];
        }
    } else if (uch == NSUpArrowFunctionKey && [theEvent modifierFlags] & NSCommandKeyMask) {
        NSString *newString = nil;
        switch ([[self string] capitalization]) {
            case 0: newString = [[self string] capitalizedString]; break;
            case 1: newString = [[self string] uppercaseString]; break;
            default: break;
        }
        if (newString)
            [self setString:newString];
    } else if (uch == NSDownArrowFunctionKey && [theEvent modifierFlags] & NSCommandKeyMask) {
        NSString *newString = nil;
        switch([[self string] capitalization]) {
            case 1: newString = [[self string] lowercaseString]; break;
            case 2: newString = [[self string] capitalizedString]; break;
            default: break;
        }
        if (newString)
            [self setString:newString];
    }
    [super keyDown:theEvent];
}

- (void)setDelegate2:(id)anObject
{
    delegate2 = anObject;
}

- (id) delegate2
{
    return delegate2;
}

- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
    return 0;
}

- (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
    return nil;
}

@end
