



//initialise the docking boxes manager
var manager = new dbxManager(
	'events',				// session ID [/-_a-zA-Z0-9/]
	'yes',					// enable box-ID based dynamic groups ['yes'|'no']
	'yes',					// hide source box while dragging ['yes'|'no']
	'button'				// toggle button element type ['link'|'button']
	);


//create new docking boxes group
var purple = new dbxGroup(
	'purple', 				// container ID [/-_a-zA-Z0-9/]
	'freeform', 			// orientation ['vertical'|'horizontal'|'freeform'|'freeform-insert'|'confirm'|'confirm-insert']
	'7', 					// drag threshold ['n' pixels]
	'no',					// restrict drag movement to container/axis ['yes'|'no']
	'10', 					// animate re-ordering [frames per transition, or '0' for no effect]
	'yes', 					// include open/close toggle buttons ['yes'|'no']
	'open', 				// default state ['open'|'closed']

	'open', 										// word for "open", as in "open this box"
	'close', 										// word for "close", as in "close this box"
	'click-down and drag to move this box', 		// sentence for "move this box" by mouse
	'click to %toggle% this box', 					// pattern-match sentence for "(open|close) this box" by mouse
	'use the arrow keys to move this box. ', 		// sentence for "move this box" by keyboard
	'press the enter key to %toggle% this box. ',  	// pattern-match sentence-fragment for "(open|close) this box" by keyboard
	'%mytitle%  [%dbxtitle%]', 						// pattern-match syntax for title-attribute conflicts

	'',												// confirm dialog sentence for "selection okay"
	''												// confirm dialog sentence for "selection not okay"
	);




//a simple rule for test output
purple.setRule('NS, *');








//format ad return a time stamp
function timestamp()
{
	var now = new Date();
	var hours = now.getHours(); if(hours < 10) { hours = '0' + hours; }
	var mins = now.getMinutes(); if(mins < 10) { mins = '0' + mins; }
	var secs = now.getSeconds(); if(secs < 10) { secs = '0' + secs; }
	var mils = now.getMilliseconds(); if(mils < 100) { mils = '00' + mils; } else if(mils < 10) { mils = '0' + mils; }
	
	return hours + ':' + mins + ':' + secs + '.' + mils;
}





//events form
var frm = document.forms['events'];




//onruletest fires whenever a rule is tested
manager.onruletest = function()
{
	//the group object
	frm['rule-dbxobject'].value = this.dbxobject + '\t[' + (typeof this.dbxobject) + ']' + '\t\t[' + timestamp() + ']';

	//the group container element
	frm['rule-group'].value = this.group + '\t[' + (typeof this.group) + ']' + '\t\t[' + timestamp() + ']';

	//the box we're testing against
	frm['rule-sourcebox'].value = this.sourcebox + '\t[' + (typeof this.sourcebox) + ']' + '\t\t[' + timestamp() + ']';

	//the rule we're testing
	frm['rule-rule'].value = this.rule + '\t[' + (typeof this.rule) + ']' + '\t\t[' + timestamp() + ']';

	//the sub-pattern within this rule we're currently testing
	//(or the whole rule if it has no sub-patterns)
	frm['rule-pattern'].value = this.pattern + '\t[' + (typeof this.pattern) + ']' + '\t\t[' + timestamp() + ']';

	//the pointer to this sub-pattern within its rule
	//indicating how many steps in a multi-step rule have occurred
	//[or 0 if this rule has no sub-patterns]
	frm['rule-pointer'].value = this.pointer + '\t[' + (typeof this.pointer) + ']' + '\t\t[' + timestamp() + ']';

	//the ruleset from which this rule is taken ("global" or ID-specific)
	frm['rule-ruleset'].value = this.ruleset + '\t[' + (typeof this.ruleset) + ']' + '\t\t[' + timestamp() + ']';

	//the direction of this movement
	frm['rule-direction'].value = this.direction + '\t[' + (typeof this.direction) + ']' + '\t\t[' + timestamp() + ']';

	//the distance of this movement in whole blocks
	frm['rule-blocks'].value = this.blocks + '\t[' + (this.blocks) + ']' + '\t\t[' + timestamp() + ']';

	//the final decision after testing this rule
	frm['rule-allowed'].value = this.allowed + '\t[' + (typeof this.allowed) + ']' + '\t\t[' + timestamp() + ']';


	//return value determines whether the operation is allowed
	//returning this.allowed means we concur with whatever would have happened anyway
	return this.allowed;
};


//onbeforestatechange fires just before any group state changes
manager.onbeforestatechange = function()
{
	//the group object
	frm['before-dbxobject'].value = this.dbxobject + '\t[' + (typeof this.dbxobject) + ']' + '\t\t[' + timestamp() + ']';

	//the group container element
	frm['before-group'].value = this.group + '\t[' + (typeof this.group) + ']' + '\t\t[' + timestamp() + ']';

	//the group id
	frm['before-gid'].value = this.gid + '\t[' + (typeof this.gid) + ']' + '\t\t[' + timestamp() + ']';

	//the selected box
	frm['before-sourcebox'].value = this.sourcebox + '\t[' + (typeof this.sourcebox) + ']' + '\t\t[' + timestamp() + ']';

	//the target element [see docs for details]
	frm['before-target'].value = this.target + '\t[' + (typeof this.target) + ']' + '\t\t[' + timestamp() + ']';

	//the action [see docs for details]
	frm['before-action'].value = this.action + '\t[' + (typeof this.action) + ']' + '\t\t[' + timestamp() + ']';


	//return value determines whether the action is allowed
	return true;
};

//onstatechange fires when any group state changes
manager.onstatechange = function()
{
	//the group object
	frm['dbxobject'].value = this.dbxobject + '\t[' + (typeof this.dbxobject) + ']' + '\t\t[' + timestamp() + ']';

	//the group container element
	frm['group'].value = this.group + '\t[' + (typeof this.group) + ']' + '\t\t[' + timestamp() + ']';

	//the group id
	frm['gid'].value = this.gid + '\t[' + (typeof this.gid) + ']' + '\t\t[' + timestamp() + ']';

	//the session id
	frm['sid'].value = this.sid + '\t[' + (typeof this.sid) + ']' + '\t\t[' + timestamp() + ']';

	//the box order and state string for all groups
	frm['state'].value = this.state + '\t[' + (typeof this.state) + ']' + '\t\t[' + timestamp() + ']';


	//return value determines whether cookie is set
	return true;
};

//ondrag fires while the mouse drags a box, or when the keyboard initiates a move
manager.onboxdrag = function()
{
	//the group object
	frm['drag-dbxobject'].value = this.dbxobject + '\t[' + (typeof this.dbxobject) + ']' + '\t\t[' + timestamp() + ']';

	//the group container element
	frm['drag-group'].value = this.group + '\t[' + (typeof this.group) + ']' + '\t\t[' + timestamp() + ']';

	//the original box 
	frm['drag-sourcebox'].value = this.sourcebox + '\t[' + (typeof this.sourcebox) + ']' + '\t\t[' + timestamp() + ']';

	//the drag clone
	frm['drag-clonebox'].value = this.clonebox + '\t[' + (typeof this.clonebox) + ']' + '\t\t[' + timestamp() + ']';

	//the window event
	frm['drag-event'].value = this.event + '\t[' + (typeof this.event) + ']' + '\t\t[' + timestamp() + ']';


	//return value determines whether the operation is allowed
	return true;
};

//onopen fires when a box is opened
manager.onboxopen = function()
{
	//the group object
	frm['open-dbxobject'].value = this.dbxobject + '\t[' + (typeof this.dbxobject) + ']' + '\t\t[' + timestamp() + ']';

	//the group container element
	frm['open-group'].value = this.group + '\t[' + (typeof this.group) + ']' + '\t\t[' + timestamp() + ']';

	//the box element
	frm['open-sourcebox'].value = this.sourcebox + '\t[' + (typeof this.sourcebox) + ']' + '\t\t[' + timestamp() + ']';

	//the toggle button
	frm['open-toggle'].value = this.toggle + '\t[' + (typeof this.toggle) + ']' + '\t\t[' + timestamp() + ']';


	//return value determines whether the operation is allowed
	return true;
};

//onopen fires when a box is closed
manager.onboxclose = function()
{
	//the group object
	frm['close-dbxobject'].value = this.dbxobject + '\t[' + (typeof this.dbxobject) + ']' + '\t\t[' + timestamp() + ']';

	//the group container element
	frm['close-group'].value = this.group + '\t[' + (typeof this.group) + ']' + '\t\t[' + timestamp() + ']';

	//the box element
	frm['close-sourcebox'].value = this.sourcebox + '\t[' + (typeof this.sourcebox) + ']' + '\t\t[' + timestamp() + ']';

	//the toggle button
	frm['close-toggle'].value = this.toggle + '\t[' + (typeof this.toggle) + ']' + '\t\t[' + timestamp() + ']';


	//return value determines whether the operation is allowed
	return true;
};

//onanimate fires during animation
manager.onanimate = function()
{
	//the group object
	frm['onani-dbxobject'].value = this.dbxobject + '\t[' + (typeof this.dbxobject) + ']' + '\t\t[' + timestamp() + ']';

	//the group container element
	frm['onani-group'].value = this.group + '\t[' + (typeof this.group) + ']' + '\t\t[' + timestamp() + ']';

	//the original box
	frm['onani-sourcebox'].value = this.sourcebox + '\t[' + (typeof this.sourcebox) + ']' + '\t\t[' + timestamp() + ']';

	//the animation clone
	frm['onani-clonebox'].value = this.clonebox + '\t[' + (typeof this.clonebox) + ']' + '\t\t[' + timestamp() + ']';

	//the iterations count / total
	frm['onani-anicount'].value = (this.anicount + ' / ' + this.anilength) + '\t[' + (typeof this.anicount) + '/' + (typeof this.anilength) + ']' + '\t\t[' + timestamp() + ']';

	//return value has no effect
};

//onafteranimate fires at the end of an animation
manager.onafteranimate = function()
{
	//the group object
	frm['ani-dbxobject'].value = this.dbxobject + '\t[' + (typeof this.dbxobject) + ']' + '\t\t[' + timestamp() + ']';

	//the group container element
	frm['ani-group'].value = this.group + '\t[' + (typeof this.group) + ']' + '\t\t[' + timestamp() + ']';

	//the box that was just animated
	frm['ani-sourcebox'].value = this.sourcebox + '\t[' + (typeof this.sourcebox) + ']' + '\t\t[' + timestamp() + ']';

	//return value has no effect
};





//add a click handler to the events form
//to show/hide the div containers
frm.onclick = function(e)
{
	var target = e ? e.target : event.srcElement;
	if(/#text|a/i.test(target.nodeName))
	{
		target = target.parentNode;
	}
	if(/legend/i.test(target.nodeName))
	{
		var div = target.parentNode.getElementsByTagName('div').item(0);
		div.style.display = div.style.display == 'none' ? 'block' : 'none';
		target.className = div.style.display == 'none' ? 'closed' : 'open';
	}
};


//now pre close them
var divs = frm.getElementsByTagName('div');
for(var i=0; i<divs.length; i++)
{
	divs[i].style.display = 'none';
	divs[i].parentNode.getElementsByTagName('legend').item(0).className = 'closed';
}


