//
//  XTMainTextView.m
//  TadsTerp
//
//  Created by Rune Berg on 13/06/14.
//  Copyright (c) 2014 Rune Berg. All rights reserved.
//

#import "XTMainTextView.h"
#import "XTGameWindowController.h"
#import "XTMainTextHandler.h"
#import "XTPrefs.h"
#import "XTLogger.h"
#import "XTAllocDeallocCounter.h"
#import "XTTabStopUtils.h"


@interface XTMainTextView ()

@property BOOL hasDoneCustomInit;

@end


@implementation XTMainTextView

static XTLogger* logger;

+ (void)initialize
{
	logger = [XTLogger loggerForClass:[XTMainTextView class]];
}

OVERRIDE_ALLOC_FOR_COUNTER
OVERRIDE_DEALLOC_FOR_COUNTER

- (id)init
{
    self = [super init];
    if (self) {
        [self customInit];
    }
    return self;
}

- (id)initWithFrame:(NSRect)frameRect textContainer:(NSTextContainer *)container
{
	self = [super initWithFrame:frameRect textContainer:container];
    if (self) {
        [self customInit];
    }
    return self;
}

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self customInit];
    }
    return self;
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
	self = [super initWithCoder:aDecoder];
    if (self) {
        [self customInit];
    }
    return self;
}

- (void)customInit
{
	if (_hasDoneCustomInit) {
		return;
	}
	
	[super customInit];

	_showCursor = YES;
	
	// don't propagate our font to NSFontPanel
	[self setUsesFontPanel:NO];
	
	[self setAutomaticSpellingCorrectionEnabled:NO];

	[self syncWithPrefs];

	_hasDoneCustomInit = YES;
}

- (BOOL)displaysLinkToolTips
{
	return self.prefs.linksShowToolTips.value.boolValue;
}

- (void)syncWithPrefs
{
	BOOL spellCheck = self.prefs.spellCheckGameText.value.boolValue;
	[self setContinuousSpellCheckingEnabled:spellCheck];

	BOOL gramCheck = self.prefs.grammarCheckGameText.value.boolValue;
	[self setGrammarCheckingEnabled:gramCheck];
}

- (void)paste:(id)sender
{
	/* Make sure we only paste plain text:
	 http://stackoverflow.com/questions/7101920/when-i-paste-text-to-a-nstextview-how-to-paste-plain-text-only
	 http://stackoverflow.com/questions/8198767/how-can-you-intercept-pasting-into-a-nstextview-to-remove-unsupported-formatting
	 http://stackoverflow.com/questions/11937726/nstextview-paste-how-to-paste-bar-instead-when-foo-is-pasted
	 */
	NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
	NSString *pastedText = [pasteboard readObjectsForClasses: @[[NSString class],[NSAttributedString class]] options:nil].lastObject;
	if ([pastedText isKindOfClass:[NSAttributedString class]]) {
		// get rid of any colours, fonts, etc.
		pastedText = [(NSAttributedString *)pastedText string];
	}

	// We don't have the information to format the pasted text
	// according to the selected input font, but our XTMainTextHandler does,
	// so let that object handle it.
	// (Ideally, we should intercept the paste event a higher level,
	// so that we wouldn't need to call back to our XTMainTextHandler.)
	
	[self.mainTextHandler appendInput:pastedText];
}

- (BOOL)shouldDrawInsertionPoint
{
	return self.showCursor;
}

- (void)complete:(id)sender
{
	// nothing - prevent Esc / F5 from showing auto-complete popup menu
}

- (NSArray *)completionsForPartialWordRange:(NSRange)charRange indexOfSelectedItem:(NSInteger *)index
{
	return nil;
}

- (void)selectAll:(id)sender
{
	//TODO? when waiting for event / single key press...
	BOOL handled = NO;
	if ([self.mainTextHandler cursorIsInCommand]) {
		NSUInteger minInsertionPoint = self.mainTextHandler.minInsertionPoint;
		NSUInteger endOfOutputPosition = [self endOfOutputPosition];
		NSRange selectedTextRange = NSMakeRange(minInsertionPoint, endOfOutputPosition - minInsertionPoint);
		[self setSelectedRange:selectedTextRange];
		handled = YES;
	} else {
		[super selectAll:sender];
	}
	
	//TODO why couldn't this be handled in controller's textView:doCommandBySelector ?
}

- (void)changeFont:(id)sender
{
	// Nothing - we don't want NSFontPanel to directly change our font
}

- (CGFloat)findTotalWidth
{
	CGFloat res = self.frame.size.width;
	return res;
}

- (void)unselectText
{
	NSUInteger len = self.textStorage.length;	
	[self setSelectedRange:NSMakeRange(len, 0)];
}

- (BOOL)shouldLogDodgyReturnFromFindYCoordOfInsertionPoint
{
	return YES; // shouldn't happen for main output area
}

- (BOOL)recalcsTabsInLiveResize
{
	return NO;
}

@end
