/**
 * Functions to quote multiple posts or single text passages.
 *
 * @author	Marcel Werk
 * @copyright	2001-2007 WoltLab GmbH
 * @license	WoltLab Burning Board License <http://www.woltlab.com/products/burning_board/license.php>
 */
function MultiQuote(data, count) {
	this.data = data;
	this.count = count;
	this.selectedText = '';
	this.ajaxRequest = null;
	this.singleQuoteID = 0;

	/**
	 * Initialises the quote functions.
	 */
	this.init = function() {
		// add listener to quote buttons
		for (var id in this.data) {
			var link = document.getElementById('postQuote'+id);
			if (link) {
				link.multiQuote = this;
				
				// remove href from edit link
				link.name = id;
				link.href = "javascript:void(0);";
				
				// add double click listener
				link.ondblclick = function() { multiQuote.quoteDirectly(this.name); };
				
				// get link icon
				var icon = false;
				if (link.firstChild && link.firstChild.src) {
					icon = link.firstChild;
				}
				
				// change icon
				icon.src = icon.src.replace(/postQuote(?=(?:S|M|L|XL)\.png$)/, 'postQuoteOptions');
				
				// add onclick listener
				link.onmousedown = function(e) { this.multiQuote.showMenu(e, this); };
				
				// crate popup menu div
				var menuDiv = document.createElement('div');
				menuDiv.id = 'postQuote' + id + 'Menu';
				menuDiv.className = 'hidden';
				link.parentNode.appendChild(menuDiv);
				popupMenuList.register('postQuote' + id);
			}

			if (this.data[id]['quotes']) {
				this.updateQuoteButton(id);
			}
		}
				
		// update reply buttons
		if (this.count > 0) {
			this.updateReplyButtons();
		}
	}
	
	/**
	 * Updates the status of a quote button
	 */
	this.updateQuoteButton = function(id) {
		// get button
		var link = document.getElementById('postQuote'+id);
		if (link) {
			// update (li) class name
			if (this.data[id]["quotes"] > 0) {
				link.parentNode.className = 'selected';
			}
			else {
				link.parentNode.className = '';
			}
			
			// update button text
			if (link.childNodes[2] && link.childNodes[2].firstChild) {
				var text = eval(language['wbb.thread.post.button.quoteMultiple']);
				
				link.childNodes[2].removeChild(link.childNodes[2].firstChild);
				link.childNodes[2].appendChild(document.createTextNode(text));
			}
		}
	}
	
	/**
	 * Updates status of all reply buttons.
	 */
	this.updateReplyButtons = function() {
		var i = 1;
		while (true) {
			var button = document.getElementById('replyButton'+i);
			if (!button) break;
			this.updateReplyButton(button);
			i++;
		}
	}
	
	/**
	 * Updates status of one reply button.
	 */
	this.updateReplyButton = function(button) {
		// update (li) class name
		if (this.count > 0) {
			button.parentNode.className = 'selected';
		}
		else {
			button.parentNode.className = '';
		}
		
		// update button text
		if (button.childNodes[2] && button.childNodes[2].firstChild) {
			var text = eval(language['wbb.thread.button.replyWithQuotes']);
			
			button.childNodes[2].removeChild(button.childNodes[2].firstChild);
			button.childNodes[2].appendChild(document.createTextNode(text));
		}
	}
	
	/**
	 * Gets the selected text passage.
	 */
	this.getSelectedText = function(id) {
		this.selectedText = '';
		var selectedText = '';
		
		// get selected text
		if (window.getSelection) {
			selectedText = window.getSelection().toString();
			if (selectedText == undefined) { // safari fix
				selectedText = new String(window.getSelection());
			}
		}
		else if (document.getSelection) {
			selectedText = document.getSelection().toString();
		}
		else if (document.selection) {
			selectedText = document.selection.createRange().text;
		}
		
		// check whether the selected text is contained by the text div
		if (selectedText != '') {
			var availableText = this.getAvailableText(id);
			availableText = availableText.replace(/\s+/g, '');
			var text = new String(selectedText).replace(/\s+/g, '');
			if (availableText.indexOf(text) != -1) {
				this.selectedText = new String(selectedText);
			}
		}
	}
	
	/**
	 * Returns the complete text of a post.
	 */
	this.getAvailableText = function(id) {
		var element = document.getElementById('postText'+id);
		if (!element) return '';
		return this.getNodeText(element);
	}
	
	/**
	 * Returns the text of a node and his children.
	 */
	this.getNodeText = function(node) {
		var nodeText = '';
		
		for (var i = 0; i < node.childNodes.length; i++) {
			if (node.childNodes[i].nodeType == 3) {
				// text node
				nodeText += node.childNodes[i].nodeValue;
			}
			else {
				// fix for mozilla smiley bug
				if (IS_MOZILLA && node.childNodes[i].nodeName.toLowerCase() == 'img' && node.childNodes[i].alt) {
					nodeText += node.childNodes[i].alt;
				}
				nodeText += this.getNodeText(node.childNodes[i]);
			}
		}
		
		return nodeText;
	}
	
	/**
	 * Returns a list of quote options.
	 */
	this.getQuoteOptions = function(id) {
		var options = new Array();
		var i = 0;
		this.getSelectedText(id);
		
		// quote directly
		options[i] = new Object();
		options[i]['function'] = 'multiQuote.quoteDirectly('+id+');';
		options[i]['text'] = (this.selectedText != '' ? language['wbb.thread.post.quote.quoteTextDirectly'] : language['wbb.thread.post.quote.quotePostDirectly']);
		i++;
		
		// mark to quote
		options[i] = new Object();
		options[i]['function'] = 'multiQuote.markToQuote('+id+');';
		options[i]['text'] = (this.selectedText != '' ? language['wbb.thread.post.quote.markTextToQuote'] : language['wbb.thread.post.quote.markPostToQuote']);
		i++;
		
		// remove quotes
		if (this.data[id]['quotes']) {
			options[i] = new Object();
			options[i]['function'] = 'multiQuote.removeQuotes('+id+');';
			options[i]['text'] = language['wbb.thread.post.quote.removeQuotes'];
			i++;
		}
		
		return options;
	}
	
	/**
	 * Show the quote menu.
	 */
	this.showMenu = function(event, element) {
		var id = element.id.replace(/[^\d]+/, '');
		var options = this.getQuoteOptions(id);
		this.createMenu(options, element, 'postQuote' + id + 'Menu');
	}
	
	/**
	 * Creates a new quote menu.
	 */
	this.createMenu = function(options, parentElement, id) {
		// get menu div
		var menuDiv = document.getElementById(id);
		
		// remove old elements
		while (menuDiv.hasChildNodes()) {
			menuDiv.removeChild(menuDiv.firstChild);
		}
		
		// menu ul
		var menuUL = document.createElement('ul');
		menuDiv.appendChild(menuUL);
		
		// menu elements
		for (var i = 0; i < options.length; i++) {
			var menuLI = document.createElement('li');
			menuUL.appendChild(menuLI);
			
			var menuA = document.createElement('a');
			menuA.href = 'javascript:'+options[i]['function'];
			menuLI.appendChild(menuA);
			menuA.appendChild(document.createTextNode(options[i]['text']));
		}
	}
	
	/**
	 * Quotes one post directly.
	 */
	this.quoteDirectly = function(id) {
		if (this.selectedText == '') {
			document.location.href = fixURL('index.php?form=PostAdd&postID='+id+'&action=quote'+SID_ARG_2ND);
		}
		else {
			this.singleQuoteID = id;
			this.saveQuote(id, this.selectedText, true);
		}
	}
	
	/**
	 * Marks a post to quote.
	 */
	this.markToQuote = function(id) {
		this.saveQuote(id, this.selectedText, false);
				
		// update button
		this.data[id]['quotes']++;
		this.updateQuoteButton(id);
		
		// update global button
		this.count++;
		this.updateReplyButtons();
	}
	
	/**
	 * Removes all quotes from a marked post.
	 */
	this.removeQuotes = function(id) {
		var ajaxRequest = new AjaxRequest();
		ajaxRequest.openPost('index.php?page=PostAction'+SID_ARG_2ND, 'action=removeQuotes&postID='+id);
		
		// update global button
		this.count -= this.data[id]['quotes'];
		this.updateReplyButtons();
		
		// update button
		this.data[id]['quotes'] = 0;
		this.updateQuoteButton(id);
	}
	
	/**
	 * Saves a quote via ajax.
	 */
	this.saveQuote = function(id, text, singleQuote) {
		this.ajaxRequest = new AjaxRequest();
		this.ajaxRequest.openPost('index.php?page=PostAction'+SID_ARG_2ND, 'action=quote&postID='+id+'&text='+encodeURIComponent(text), (singleQuote ? function() { multiQuote.receiveResponse(); } : false));
	}
	
	/**
	 * Receives the ajax response.
	 */
	this.receiveResponse = function() {
		if (this.ajaxRequest && this.ajaxRequest.xmlHttpRequest.readyState == 4/* && this.ajaxRequest.xmlHttpRequest.status == 200*/) {
			document.location.href = fixURL('index.php?form=PostAdd&postID='+this.singleQuoteID+SID_ARG_2ND);
		}
	}
	
	this.init();
}
