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

#import "XTOutputTextView.h"
#import "XTGameWindowController.h"
#import "XTOutputTextHandler.h"
#import "XTPrefs.h"
#import "XTLogger.h"
#import "XTAllocDeallocCounter.h"


@interface XTOutputTextView ()

@property BOOL hasDoneCustomInit;
@property XTPrefs *prefs;

@end


@implementation XTOutputTextView

static XTLogger* logger;

+ (void)initialize
{
	logger = [XTLogger loggerForClass:[XTOutputTextView 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];
	
	_prefs = [XTPrefs prefs];

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

	[self syncWithPrefs];

	[_prefs startObservingChangesToAll:self];
	
	_hasDoneCustomInit = YES;
}

- (void)teardown
{
	[_prefs stopObservingChangesToAll:self];
	
	NSAttributedString *noText = [NSAttributedString new];
	[self.textStorage setAttributedString:noText];
	
	self.delegate = nil;
}

- (void)observeValueForKeyPath:(NSString *)keyPath
					  ofObject:(id)object
						change:(NSDictionary *)change
					   context:(void *)context
{
	XT_DEF_SELNAME;
	XT_TRACE_1(@"keyPath=\"%@\"", keyPath);
	
	if (object == self.prefs) {
		[self syncWithPrefs];
	} else {
		XT_TRACE_0(@"%@ OTHER");
	}
}

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

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

	BOOL gramCheck = self.prefs.grammarCheckGameText.boolValue;
	[self setGrammarCheckingEnabled:gramCheck];
	
	//TODO unless set by game:
	self.backgroundColor = self.prefs.outputAreaBackgroundColor;
}

- (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 XTOutputTextHandler 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 XTOutputTextHandler.)
	
	[self.outputTextHandler 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
{
	XTGameWindowController *delegate = (XTGameWindowController*)self.delegate;
	BOOL handled = [delegate handleSelectAll];
	if (! handled) {
		[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;
}

- (CGFloat)findTotalHeight
{
	CGFloat res = self.frame.size.height;
	return res;
}

- (CGFloat)findVisibleHeight
{
	[self ensureLayoutForTextContainer];
	
	CGFloat res = self.enclosingScrollView.documentVisibleRect.size.height;
	return res;
}

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

@end
