// --------------------------------------------------------------------
//
// This is a Greasemonkey user script.
//
// To install, you need Greasemonkey: http://greasemonkey.mozdev.org/
// Then restart Firefox and revisit this script.
// Under Tools, there will be a new menu item to "Install User Script".
// Accept the default configuration and install.
//
// To uninstall, go to Tools/Manage User Scripts,
// select "planetcrap", and click Uninstall.
//
// --------------------------------------------------------------------
//
// ==UserScript==
// @name          planetcrap
// @namespace     http://www.planetcrap.com/greasemonkey/
// @description   some helper functions for planetcrap 0.14 2007-11-01 18:22
// @include       http://www.planetcrap.com/*
// @include       http://planetcrap.com/*
// @include       http://girlskissing.planetcrap.com/*
// ==/UserScript==

var KEY_QUOTESTYLE = 'planetcrapQuoteStyle';
var KEY_QUOTEBUTTONSTYLE = 'test11';
var KEY_HELPERSTYLE = 'test12';
var KEY_BLOCKQUOTESTYLE = 'test13';

var STYLE_DEFAULT = 'default';
var STYLE_MONTY = 'monty';
var STYLE_GAGGLE = 'gaggle';
var STYLE_NONE = 'none';
var STYLE_GMAN = 'gman';
var STYLE_CHEESY = 'cheesy';
var STYLE_DUM = 'dum';
var STYLE_BUTTON_ASS = 'button_ass';
var STYLE_BUTTON_DEFAULT = 'none';
var STYLE_HELPER_ASS = 'helper_ass';
var STYLE_HELPER_DEFAULT = 'none';
var STYLE_BLOCKQUOTE_ASS = 'blockquote_ass';
var STYLE_BLOCKQUOTE_DEFAULT = 'none';


// script entry point
function entryPoint() {
	
	// set our menu items
	GM_registerMenuCommand('set quote style default', function(event) {
		GM_setValue(KEY_QUOTESTYLE, STYLE_DEFAULT);
	} );
	GM_registerMenuCommand('set quote style none', function(event) {
		GM_setValue(KEY_QUOTESTYLE, STYLE_NONE);
	} );
	
	GM_registerMenuCommand('set quote style monty', function(event) {
		GM_setValue(KEY_QUOTESTYLE, STYLE_MONTY);
	} );
	
	GM_registerMenuCommand('set quote style gaggle', function(event) {
		GM_setValue(KEY_QUOTESTYLE, STYLE_GAGGLE);
	} );
	
	GM_registerMenuCommand('set quote style gman', function(event) {
		GM_setValue(KEY_QUOTESTYLE, STYLE_GMAN);
	} );
	
	GM_registerMenuCommand('set quote style CheesyPoof', function(event) {
		GM_setValue(KEY_QUOTESTYLE, STYLE_CHEESY);
	} );
	
	GM_registerMenuCommand('set quote style dumdeedum', function(event) {
		GM_setValue(KEY_QUOTESTYLE, STYLE_DUM);
	} );
	
	GM_registerMenuCommand('buttonize quote button', function(event) {
		GM_setValue(KEY_QUOTEBUTTONSTYLE, STYLE_BUTTON_ASS);
	} );
	
	GM_registerMenuCommand('linkify quote button', function(event) {
		GM_setValue(KEY_QUOTEBUTTONSTYLE, STYLE_BUTTON_DEFAULT);
	} );
	
	GM_registerMenuCommand('buttonize editor buttons', function(event) {
		GM_setValue(KEY_HELPERSTYLE, STYLE_HELPER_ASS);
	} );
	
	GM_registerMenuCommand('linkify editor buttons', function(event) {
		GM_setValue(KEY_HELPERSTYLE, STYLE_HELPER_DEFAULT);
	} );
	
	GM_registerMenuCommand('make quotes fugly', function(event) {
		GM_setValue(KEY_BLOCKQUOTESTYLE, STYLE_BLOCKQUOTE_ASS);
	} );
	
	GM_registerMenuCommand('make quotes look normal again', function(event) {
		GM_setValue(KEY_BLOCKQUOTESTYLE, STYLE_BLOCKQUOTE_DEFAULT);
	} );


	comments = getElementsByClass('comment-info');
	var numComments = comments.length;

	// install a quote button under each post info block
	for (i = 0; i < numComments; i++) {
		var quoteDiv = document.createElement("span");
		quoteDiv.setAttribute("class", "quotebutt");
		quoteDiv.setAttribute("post_id", i);
		quoteDiv.innerHTML = '<a href="#" onclick="return false;">quote</a>';
		comments[i].appendChild(quoteDiv);
	}
	
	if (! document.forms[0] ) {
		return;
	}
	
	// install bold, italic etc helper links
	var helperLinksDiv = document.createElement("span");
	helperLinksDiv.innerHTML = ' <a href="#" class="helper" id="bold" accesskey="b" onclick="return false"><strong>b</strong></a>&nbsp;<a href="#" class="helper" id="italic" accesskey="i" onclick="return false"><em>it</em></a>&nbsp;<a href="#" class="helper" id="underline" accesskey="u" onclick="return false"><u>u</u></a>&nbsp;<a href="#" class="helper" id="strike" accesskey="s" onclick="return false"><del>strike</del></a>&nbsp;<a href="#" class="helper" id="helperlink" accesskey="l" onclick="return false">url</a>&nbsp;<a href="#" class="helper" id="helperquote" accesskey="q" onclick="return false">quote</a>&nbsp;';
	commentBody = document.forms[0].elements.namedItem('comment[body]');
	commentBody.parentNode.insertBefore(helperLinksDiv, commentBody.previousSibling.previousSibling);

	// LESLIE'S CHANGES START
	var previewWindow = document.createElement("div");
	previewWindow.className = 'preview-window';
	previewWindow.style.padding = '6px';
	previewWindow.style.height = '200px';
	previewWindow.style.border = '1px solid #ccc';
	previewWindow.style.backgroundColor = '#eee';
	previewWindow.style.overflow = 'auto';
	previewWindow.innerHTML = '';
	document.forms[0].elements.namedItem('comment[body]').parentNode.appendChild(previewWindow);
	document.addEventListener('keyup', function(event) {
		if ('comment[body]' == event.target.name) {
			updatePreview(event.target.value);
		}
	}, true);
	document.addEventListener('focus', function(event) {
		if ('comment[body]' == event.target.name) {
			updatePreview(event.target.value);
		}
	doFormattingForSelection(event.target.id);
	}, true);
	// LESLIE'S CHANGES FINISH


	//all CSS should go here....?
	addStyles();
	
	// register a click event handler to do the work of quoting when it happens
	document.addEventListener('click', function(event) {
		if (event.target.parentNode.className == "quotebutt") {
			quoteText = getSelectionSafe();
			if (quoteText.length > 0) {
				// find the clicked post id and name
				// TODO!!! find the parent of selection instead of parent of clicked button
				var postId = event.target.parentNode.getAttribute('post_id');
				var posterInfoChunk = event.target.parentNode.parentNode.textContent
				//processSelectedQuoteClick(getHTMLOfSelection());
				processQuoteClick(postId, posterInfoChunk, getHTMLOfSelection());
			} else {
				// find the clicked post id and name
				var postId = event.target.parentNode.getAttribute('post_id');
				var posterInfoChunk = event.target.parentNode.parentNode.textContent
				processQuoteClick(postId, posterInfoChunk, null);
			}
		}
	}, true);
	
	
}


window.addEventListener("load", entryPoint, false);

function doFormattingForSelection(id) {
	commentBody = document.forms[0].elements.namedItem('comment[body]');
	quoteText = commentBody.value.substring(commentBody.selectionStart, commentBody.selectionEnd)
	if (quoteText.length <= 0) {
		return;
	}
	
	switch(id) {
		case 'bold':
			tagSelection(commentBody, quoteText, '[b]', '[/b]');
			break;
		case 'italic':
			tagSelection(commentBody, quoteText, '[i]', '[/i]');
			break;
		case 'underline':
			tagSelection(commentBody, quoteText, '[u]', '[/u]');
			break;
		case 'strike':
			tagSelection(commentBody, quoteText, '[s]', '[/s]');
			break;
		case 'helperlink':
			var URL = prompt('INSERT COIN' , 'http://');
		if (URL !== null) {
			tagSelection(commentBody, quoteText, '[url=' + URL + ']', '[/url]');
		}
			break;
		case 'helperquote':
			tagSelection(commentBody, quoteText, '[quote]', '[/quote]');
			break;
		default:
			return;
	}
}



function getSelectionSafe() {
	var text = window.getSelection();
	if (text.length > 0) {
		return text;
	}
	text = document.getSelection();
	if (text.length > 0) {
		return text;
	}
	return '';
}



function getHTMLOfSelection () {
	var range;
	if (document.selection && document.selection.createRange) {
		range = document.selection.createRange();
		return range.htmlText;
	}
	else if (window.getSelection) {
		var selection = window.getSelection();
		if (selection.rangeCount > 0) {
			range = selection.getRangeAt(0);
			var clonedSelection = range.cloneContents();
			var div = document.createElement('div');
			div.appendChild(clonedSelection);
			return div.innerHTML;
		}
		else {
			return '';
		}
	}
	else {
		return '';
	}
}



//function processSelectedQuoteClick(text) {
//	commentBody = document.forms[0].elements.namedItem('comment[body]');
//	if (commentBody.value.length != 0) {
//		commentBody.value += '\n';
//	}
//	commentBody.value += cleanQuote(text);
//	commentBody.focus();
//}



// a click was triggered on a quote link, so take the text of that post and
// put it into the comment box
// 0.14 - merged processSelectedQuoteClick() into it
function processQuoteClick (postId, posterInfoChunk, selection) {

	var splitChunk = posterInfoChunk.split('\n');
	var realPostId = splitChunk[1].split(' ')[0];
	var posterName = splitChunk[2];
	var quoteHeader = '';
	// add the post number and name
	quoteHeader = addQuoteHeader(realPostId, posterName);

	//create a link to comment body
	commentBody = document.forms[0].elements.namedItem('comment[body]');
	if (commentBody.value.length != 0) {
		commentBody.value += '\n';
	}

	//check if we want to quote just a selection or whole post
	if (selection !== null) {
		// put the cleaned comment body into the comment field
		commentBody.value += quoteHeader;
		commentBody.value += cleanQuote(selection);
	} else {
		// grab the clicked posts comment body
		// change the html to craptags and strip sig etc..
		var posts = getElementsByClass('comment');
		var cleanedQuoteBody = cleanQuote(posts[postId].innerHTML);
		// put the cleaned comment body into the comment field
		cleanedQuoteBody = quoteHeader + cleanedQuoteBody;
		commentBody.value += cleanedQuoteBody;
	}

	commentBody.focus();
}




function addQuoteHeader(realPostId, posterName) {
	// find the users quote style preference
	var quoteStylePreference = GM_getValue(KEY_QUOTESTYLE, STYLE_DEFAULT);

	var quoteHeader = '';
	// add the post number and name
	switch(quoteStylePreference) {
		case STYLE_DEFAULT:
			quoteHeader = realPostId + ' by [b]' + posterName + '[/b]\n\n';
			break;
		case STYLE_NONE:
			quoteHeader = '\n';
			break;
		case STYLE_MONTY: 
			quoteHeader = '[b]' + posterName + '[/b] (' + realPostId + '):\n';
			break;
		case STYLE_GAGGLE:
			quoteHeader = realPostId + ' by [b]' + posterName + '[/b]\n';
			break;
		case STYLE_GMAN:
			quoteHeader = '[b]' + posterName + ' said in ' + realPostId + ':[/b]\n';
			break;
		case STYLE_CHEESY:
			quoteHeader = '[b]' + realPostId + ' by ' + posterName + '[/b]\n';
			break;
		case STYLE_DUM:
			quoteHeader = '[b]' + posterName + '[/b]\n';
			break;
		default:
			quoteHeader = 'ERROR';
	}
	return quoteHeader;
}



function cleanQuote(text) {
	// strip the sig if there
	sigIndex = text.lastIndexOf('<div class="sign'); 
	if (sigIndex != -1) {
		text = text.substring(0, sigIndex);
	}

	// replace nbsp's
	text = text.replace(/&nbsp;/g, ' ');

	// replace <br>'s
	text = text.replace(/<br>/g, '\n');
	
	// handle inner quotes and pesky newlines
	text = text.replace(/<div class="quote">/g, '\[quote\]');
	text = text.replace(/<\/div>\n/g, '\[/quote\]');

	// replace links and emails with planetcrap markup
	text = text.replace(/<a href="/g, '\[url=');
	text = text.replace(/" target="_blank">/g, '\]');
	text = text.replace(/">/g, '\]');
	text = text.replace(/<\/a>/g, '\[/url\]');

	// replace bolds, italics, underlines and strikethrough
	text = text.replace(/<b>/g, '\[b\]');
	text = text.replace(/<\/b>/g, '\[/b\]');
	text = text.replace(/<i>/g, '\[i\]');
	text = text.replace(/<\/i>/g, '\[/i\]');
	text = text.replace(/<u>/g, '\[u\]');
	text = text.replace(/<\/u>/g, '\[/u\]');
	text = text.replace(/<s>/g, '\[s\]');
	text = text.replace(/<\/s>/g, '\[/s\]');

	// trim
	text = text.replace(/^\s+|\s+$/, '');

	// add some clean start and end quotes
	text = '[quote]' + text + '[/quote]\n';
	text = text.replace(/\n\[\/quote\]/g, '\[/quote\]');

	text = text.replace(/\n\n\n/g, '\n');

	return text;
}



function getElementsByClass(searchClass,node,tag) {

	var classElements = new Array();
	
	if ( node == null ) {
		node = document;
	}
	
	if ( tag == null ) {
		tag = '*';
	}

	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp('(^|\\s)'+searchClass+'(\\s|$)');

	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}



// LESLIE'S CHANGES START
function updatePreview(v)
{
	var preview = getElementsByClass('preview-window', null, 'div');
	if (preview) {
		var post = v;
		post = post.replace(/\n/g, '<br />');
		post = post.replace(/\[quote\]/g, '<blockquote>');
		post = post.replace(/\[\/quote\]/g, '</blockquote>');
		post = post.replace(/\[b\]/g, '<b>');
		post = post.replace(/\[\/b\]/g, '</b>');
		post = post.replace(/\[i\]/g, '<i>');
		post = post.replace(/\[\/i\]/g, '</i>');
		post = post.replace(/\[u\]/g, '<u>');
		post = post.replace(/\[\/u\]/g, '</u>');
		post = post.replace(/\[s\]/g, '<s>');
		post = post.replace(/\[\/s\]/g, '</s>');
		post = post.replace(/\[url=(.*?)\]/g, '<a href="$1" target="_blank">');
		post = post.replace(/\[\/url]/g, '</a>');
		preview[0].innerHTML = post;
	}
}
// LESLIE'S CHANGES FINISH



function addGlobalStyle(css) {
		var head, style;
		head = document.getElementsByTagName('head')[0];
		if (!head) { return; }
		style = document.createElement('style');
		style.type = 'text/css';
		style.innerHTML = css;
		head.appendChild(style);
}



function tagSelection(textArea, quote, startTag, endTag) {
	startString = textArea.value.substring(0, textArea.selectionStart);
	endString = textArea.value.substring(textArea.selectionEnd);
	setAndFocus(textArea, startString + startTag + quote + endTag + endString)
}



function setAndFocus(node, text) {
	node.value = text;
	node.focus();
}



function addStyles() {
	// find other style preferences
	var buttonStylePreference = GM_getValue(KEY_QUOTEBUTTONSTYLE, STYLE_BUTTON_DEFAULT);
	var helperStylePreference = GM_getValue(KEY_HELPERSTYLE, STYLE_HELPER_DEFAULT);
	var blockquoteStylePreference = GM_getValue(KEY_BLOCKQUOTESTYLE, STYLE_BLOCKQUOTE_DEFAULT);

	//quote button style
	switch(buttonStylePreference) {
		case STYLE_BUTTON_ASS:
			addGlobalStyle('.quotebutt { float: right; margin:0px; padding:3px 12px 5px; border: 1px #777 solid; background-color:#ccc; }\n');
			break;
		case STYLE_BUTTON_DEFAULT:
		default:
			break;
	}

	//button style to helper links
	switch(helperStylePreference) {
		case STYLE_HELPER_ASS:
			addGlobalStyle('.helper { padding: 3px 5px 5px; border: 1px #777 solid; background-color:#ccc; }\n');
			break;
		case STYLE_HELPER_DEFAULT:
		default:
			break;
	}

	//quote style to make your eyes bleed
	switch(blockquoteStylePreference) {
		case STYLE_BLOCKQUOTE_ASS:
			addGlobalStyle('.quote { border: #999 solid 1px; border-left: #77a 6px solid; background-color: #f8f8f8; }\n');
			break;
		case STYLE_BLOCKQUOTE_DEFAULT:
		default:
			break;
	}

	//default
	addGlobalStyle('.preview-window blockquote { color: #666 ! important; margin-top: 0px; margin-bottom: 0px; }');
	addGlobalStyle('#bold, #italic, #underline, #strike, #helperlink, #helperquote { font-weight: normal; color: #000; }');
}