/*
* DiceRoller.js
*
* Javascript functions associated with the DiceRoller extension
*
*
Copyright 2006 Arturo Gonzalez-Escribano
This file is part of Lussumo's Software Library.
Lussumo's Software Library is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
Lussumo's Software Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with Vanilla; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
The latest source code is available at www.lussumo.com
Contact Arturo González-Escribano at arturo [at] infor [dot] uva [dot] es

*
*/


/*
* DR_beb: DiceRoller 'block edit button'
*
*	Invoked just after the Comment options has been rendered, it searchs and
*	blocks the edit button for that comment.
*
*	For eficiency, the php code should include the call to this script
*	only when the AuthUserID is the UserID, but if the button does not exist 
*	the script does not complain.
*
*/
function DR_beb( id, editText ) {
	var scriptElement=document.getElementById(id); 
	var parentElement=scriptElement.parentNode; 
	var i=0; 
	var sibling=parentElement.childNodes[0]; 

	/* Locate an anchor sibling with the text of the edit button */
	while(sibling!=null) {
		if (sibling.nodeType==1 
					&& sibling.nodeName == "A" 
					&& sibling.innerHTML == editText ) {
			// Eliminate the link
			parentElement.removeChild( sibling );
			break;
		} 
		i=i+1; 
		sibling=parentElement.childNodes[i]; 
	}
} 


/*
* Functions for presentation of dice-roll results
*
* Several functions associated with the presentation of dice results in the
* comment text, and with the selection of options through a context menu.
*/


/*
* On-load of the page, if javascript is active and the main show/hide
* functions will work, hide all the rolls. I let the rolls visible on load
* only for browsers which do not have javascript active.
*/
var DR_oldOnload = window.onload;
window.onload = DR_hideRolls;

/*
* DR_hideRolls: Hide all the rolls in the page (to be activated on page load)
*/
function DR_hideRolls() {
	var allRolls = document.getElementsByName("DR_rolls");
	for (i=0; i<allRolls.length; i++) {
		allRolls[i].innerHTML = "";
	}
	DR_oldOnload;
}

/*
* Global variables for the context menu
*/
var DR_menu = null;
// This array is filled with language dependent definitions from the PHP code
var DR_options = new Array(4);  

/*
* DR_joinMenu: Joins the hidden menu to an element. It creates it the first
*	time.
*/
function DR_joinMenu( event ) {
	// Create it the first time
	if (DR_menu == null) {
		DR_menu = document.createElement("div");
		DR_menu.className = "DR_menu";

		for (i=0; i<DR_options.length; i++) {
			// New lines for all except first
			if (i!==0) {
				br = document.createElement("br");
				DR_menu.appendChild( br );
			}
			// Create and add option
			option = document.createElement("a");
			option.className = "DR_menuOption";
			option.onmouseup = DR_menuOption;

			// Trick to simulate correct CSS hover behaviour in IExplorer
			option.onmouseover = new Function("this.className = 'DR_menuOptionOver'");
			option.onmouseout = new Function("this.className = 'DR_menuOption'");

			option.innerHTML = DR_options[i];
			option.setAttribute( "numOpt", i );

			DR_menu.appendChild( option );
		}
	}
	// Join it	
	var parentElem = this.parentNode;
	parentElem.appendChild( DR_menu );

	var pos = DR_getMousePos( event );
	DR_menu.style.left= pos.x + "px";
	DR_menu.style.top= pos.y + "px";

	// Stop selecting text
	document.onmousedown = new Function("return false;"); // NE browser family
	document.onselectstart = new Function("return false;"); // IE browser family

	// Close menu when releasing the button outside of the menu options 
	document.onmouseup = DR_closeMenu; // NE browser family
}


/*
* DR_getMousePos: Adapter to get mouse position on as many browses as possible
*/
function DR_getMousePos(e) {
	var result = new Object();

	if (!e) e = window.event;
	if (e.pageX) {
		result.x = e.pageX;
		result.y = e.pageY;
		}
	else if (e.clientX) {
		result.x = e.clientX;
		result.y = e.clientY;
		if ( ! document.documentElement.scrollLeft )
			result.x += document.body.scrollLeft;
		else result.x += document.documentElement.scrollLeft;

		if ( ! document.documentElement.scrollTop ) 
			result.y += document.body.scrollTop;
		else result.y += document.documentElement.scrollTop;
	}
	else return null;

	return result;
}


/*
* DR_diceShow: Show dice-roll information
*/
function DR_diceShow( elem ) {
	var parentElem = elem.parentNode;
	var rollText = parentElem.childNodes[1];

	elem.setAttribute("task","hide");
	rollText.style.margin = "0 4px 0 4px";
	rollText.style.padding = "0 8px 0 8px";
	rollText.onmousedown = DR_joinMenu;
	rollText.onmouseup = DR_closeMenu;
//	rollText.setAttribute("onmouseover", "DR_rollShow(this)" );
	DR_rollShow( rollText );
}

/*
* DR_diceToggle: Toggle (hide/show) dice-roll information
*/
function DR_diceToggle( elem ) {
	var parentElem = elem.parentNode;
	var rollText = parentElem.childNodes[1];
	var taskValue = elem.getAttribute("task");

	if (taskValue == "hide") {
		elem.setAttribute("task","show");
		rollText.innerHTML = "";
		rollText.style.margin = "0px";
		rollText.style.padding = "0px";
	}
	else {
		elem.setAttribute("task","hide");
		DR_rollShow ( rollText );
		rollText.style.margin = "0 4px 0 4px";
		rollText.style.padding = "0 8px 0 8px";
	}
}


/*
* DR_rollShow: Update content when mouse over rolls
*/
function DR_rollShow( elem ) {
	var parentElem = elem.parentNode;
	var diceSpec = parentElem.childNodes[0];
	var sortValue = diceSpec.getAttribute("sort");
	var rollValue = diceSpec.getAttribute("roll");
	var sumValue = diceSpec.getAttribute("sum");
	elem.innerHTML = DR_rollString( rollValue, sortValue, sumValue );
}


/*
* DR_rollString: Build the roll string, sorting if necessary
*/
function DR_rollString( rollValue, sortValue, sumValue ) {
	var rollString;

	// Split array of numbers
	var arr = rollValue.split(" ");

	// Sorting
	if ( sortValue != "no" ) {
		arr.sort();
		if ( sortValue == "down" ) arr.reverse();
		}

	// Sum	
	if ( sumValue=="yes" && arr.length>1) {
		var total = 0;
		
		for (i=0; i<arr.length; i++) {
			// v0.4 patch:
			// Force base 10 parsing, to avoid 08 and 09 to be incorrectly 
			// parsed as base 8 numbers
			total += parseInt(arr[i], 10); 

			// v0.4: Mark modifiers with brackets in the sum
			if (arr[i][0]=='+' || arr[i][0]=='-')  arr[i] = "[" + arr[i] + "]"; 
		}
		rollString = arr.join(" + ");
 		rollString += " = " + total;
	}
	else rollString = arr.join(", ");

	return rollString;
}


/*
* DR_menuOption: Actions associated with the options of the menu
*/
function DR_menuOption( ) {
	elem = this;
	var parentElem = elem.parentNode;
	var ancestorElem = parentElem.parentNode;
	var diceElem = ancestorElem.childNodes[0];
	var rollElem = ancestorElem.childNodes[1];

	opt = elem.getAttribute("numOpt");
	if ( opt==0 ) {
		diceElem.setAttribute( "sort", "no" );
		DR_rollShow( rollElem );
	}
	else if ( opt==1 ) {
		diceElem.setAttribute( "sort", "up" );
		DR_rollShow( rollElem );
	}
	else if ( opt==2 ) {
		diceElem.setAttribute( "sort", "down" );
		DR_rollShow( rollElem );
	}
	else if ( opt==3 ) {
		var sum = diceElem.getAttribute("sum");
		sum = (sum=="no") ? "yes":"no";
		diceElem.setAttribute( "sum", sum );
		DR_rollShow( rollElem );
	}

	// Trick to simulate pseudoclass :hover normal behaviour in IExplorer 
	// (back to non-highlighted class)
	elem.className = "DR_menuOption";

	// Any option chosen: Hide menu
	DR_closeMenu();
}

/*
* DR_closeMenu: Hide menu removing it from the document hierarchy
*/
function DR_closeMenu() {
	var parentElem = DR_menu.parentNode;
	parentElem.removeChild( DR_menu );

	// Normal mouse behaviour
	document.onmousedown = null; // NE browser family;
	document.onmouseup = null; // NE browser family;
	document.onselectstart = null; // IE browser family;
}


