// Support script for MindMapMenus
// Author: Theodore Zacharia
// Date: July 2008

var rootobject="mmitemObject0";
var mmitem = null; // object

var totmaxdid=20;	// total number of base menu items to scan for (helper variable for performance reasons)


var menuitem=0;
var armlength=120.0;
var itterations=0;
var objname;
var totmaxdid=10;


function doNothing() {
	i=0;
//	window.alert("ping");
	setTimeout("doNothing()", 2);
}




function doMove(aobj) {
  var objname;
  var mmitem;
  var xp;
  var yp;
  var xc;
  var yc
  var itterations;
  var parentobjname;
  var tm;

screewidth=findLivePageWidth();
screenheight=findLivePageHeight();
offx=screewidth/2;
offy=screenheight/2;
objname=aobj;
parentobjname=getParentObjectName(aobj);

if (debug>10)  window.alert("moving " + aobj+" with parent "+parentobjname);

if (objname == rootobject)
{
	return; // don't move this one
}

// need to get coords with origin from parent object
pmmitem = document.getElementById(parentobjname);
xorigin=parseInt(pmmitem.style.left);
yorigin=parseInt(pmmitem.style.top);

mmitem = document.getElementById(objname); // get the "mmitem" object
xp=parseInt(mmitem.style.left);
yp=parseInt(mmitem.style.top);

itterations=mmitem.varTTL;
itterations--;
mmitem.varTTL=itterations;

if (debug>10) window.alert(mmitem.varName);
if (debug>10) window.alert(mmitem.style.left);
  xc=xorigin;
  yc=yorigin;
if (debug>10) window.alert("xc="+xc+" , yc="+yc + ", xp="+xp+" , yp="+yp + " itterations="+itterations);
  angle=mmitem.varTheta;
  angle=angle+Math.PI/32.0;
if (debug>10)  window.alert("angle="+angle);
  xp=xc+armlength*Math.cos(angle);
  yp=yc+armlength*Math.sin(angle);
if (debug>10) window.alert("xp="+xp);
if (debug>10) window.alert(angle);

  mmitem.varTheta=angle;
if (debug>10) window.alert(mmitem.varTheta);

if (debug>10) window.alert(mmitem.style.left);
mmitem.style.left=xp+'px';
if (debug>10) window.alert(mmitem.style.left);
mmitem.style.top=yp+'px';

// now draw a line back to parent item
if (1==2)
{
//	line( offx-xp, offy-yp, xorigin-offx, yorigin-offy, objname, document );
//	line(xp-offx, yp-offy, xp+10-offx, yp+20-offy, objname, document );
	line(xp, yp, xp+10, yp+20, objname, document );

}

//var g = new Graphics();
//g.paint();

// a lot of messing with varName so can pass to next itteration
	if (itterations > 0)
	{
		if (debug>10) window.alert("calling setTimeout for "+mmitem.varName);
		//setTimeout("doMove(aobj)", 10);
		//setTimeout("doNothing()", 1);
		tm = setTimeout("doMove(mmitem.varName)", 25);
		//tm = setInterval("doMove(mmitem.varName)", 25);
	}

	else
	{
		//clearInterval(tm);
		;
	}


}



// opens a menu item next level decendant items
function doOpen(aobjname) {
	var mmitem;
	var theta;
	var levelprefix;
	var did;
	var objname;

	mmitem = document.getElementById(aobjname);
	mmitem.varIsOpen=1;
	xc=parseInt(mmitem.style.left);
	yc=parseInt(mmitem.style.top);

	levelprefix=getLevelPrefix(aobjname);
	maxdid = getLevelCount(levelprefix);

	if (aobjname == rootobject)
		maxdid--;

	deltatheta = 2.0*Math.PI/maxdid;
	theta = 0.2 ;	// first element always in this position


if (debug>9) window.alert('opening '+aobjname+", nodeName "+mmitem.nodeName +', levelobjname '+levelobjname+" with max of "+maxdid);

	// to declutter close any open from other branches
	declutter(aobjname);
	setOpacity(aobjname, 8);

	// just open the next level
	for (did=1; did<totmaxdid; did++)
	{
  		objname=levelprefix+did;
  		mmitem = document.getElementById(objname); // get the "mmitem" object
if (debug>9) window.alert('checking '+objname+" with "+mmitem);
		if ((mmitem == null) || (mmitem == undefined))
			continue;


		xp=xc+armlength*Math.cos(theta);
		yp=yc+armlength*Math.sin(theta);
		theta=theta+deltatheta;
		mmitem.varTheta=theta;
if (debug>9) window.alert('moving for open '+objname + " to " + xp + ","+yp);

  		mmitem.style.left = xp;
  		mmitem.style.top = yp;
		mmitem.style.visibility="visible";

		mmitem.varTTL=20;	// number of animation itterations

		setOpacity(objname, 10);
		//doMove(objname);
		//doLine(objname);
	}

}


// close all decendant items upto the level indicated
// atop is set if you are at the top level only, when it recurses to the
// lower level it is not set, used as indicated for visual cue controls like opacity
function doClose(aobjname, atop) {
	var mmitem;
	var xp;
	var yp;
	var did;
	var subdid;
	var objname;
	var levelprefix;

	mmitem = document.getElementById(aobjname);
	if ((mmitem == null) || (mmitem == undefined))
		return;

//	xp=mmitem.style.left;
//	yp=mmitem.style.top;
	mmitem.varIsOpen=0;
	levelprefix=getLevelPrefix(aobjname);

if (debug>9) window.alert('closing '+aobjname+" = "+aobjname + " levelprefix="+levelprefix);

	// change opacity for parent and all at same level
	setOpacity(aobjname, 10);
	if (atop != null || atop != undefined)
		refocus(aobjname);

	// close all decendant levels
	for (did=1; did<totmaxdid; did++)
	{
  		objname=levelprefix+did;

if (debug>9) window.alert('checking for close '+objname);
  		mmitem = document.getElementById(objname); // get the "mmitem" object
		if ((mmitem == null) || (mmitem == undefined))
			continue;

		doClose(objname);	// close decendants by recurrsing back down

if (debug>9) window.alert('hiding for close '+objname);
//  	mmitem.style.left = xp;
//  	mmitem.style.top = yp;
  		if (objname != rootobject)
  			mmitem.style.visibility="hidden";

	}	// end of for did


}




// returns the parent object to the one supplied
function getParentObjectName(aobj) {
  var aid=aobj.lastIndexOf('_');
  if (aid < 0)
  {
  	parentobjname=rootobject;
  }
  else
  {
  	parentobjname=aobj.substring(0,aid);
  }

  return parentobjname;
}

// returns a string ready for use in building menuitem names at a given level
function getLevelPrefix(tobjname)
{
	len=tobjname.length;
	if (tobjname == rootobject)
	{
		levelobjname=tobjname.substring(0, len-1);
		levelconnect="";
	}
	else
	{
		levelobjname=tobjname;
		levelconnect="_";
	}
	return levelprefix=levelobjname+levelconnect;;
}

// count number of items at this level, handles non-contiguous
function getLevelCount(aobj) {

	var mmitem;
	var objname;

	maxlevelcount=0;

	// in case we are non-contiguous, continue on missing ones rather than break
	for (did=0; did<totmaxdid; did++)
	{
  		objname=aobj+did;
		if (debug>9) window.alert('getLevelCount::checking '+objname+" with "+mmitem);
		mmitem = document.getElementById(objname); // get the "mmitem" object
		
		if ((mmitem == null) || (mmitem == undefined))
			continue;
			
		maxlevelcount++;
	}

	return maxlevelcount;
}


// declutters the currently open objects to make menu more usable
// by closing all out of focus submenus
function declutter(exceptname) {

	var maxdid = getLevelCount(levelprefix);
	var parentobjname = getParentObjectName(exceptname);
	var levelprefix=getLevelPrefix(parentobjname);
//	var levelprefix=getLevelPrefix(rootobject);
	var did;
	var objname;
	
	for (did=1; did<totmaxdid; did++)
	{
  		objname=levelprefix+did;

		if ((objname != parentobjname) && (objname != exceptname))
		{
			doClose(objname);
			setOpacity(objname, 3);
		}
	}

	if (parentobjname == rootobject)
		setOpacity(parentobjname, 3);

	// special case logic for my intro page
	if (exceptname == rootobject)
	{
		setOpacity("introTop", 4);
		setOpacity("introBottom", 4);
	}
}

// sets the opacity back to full of all objects at the same level
// as the one specified 
function refocus(aobjname) {

	var parentobjname = getParentObjectName(aobjname);
	var levelprefix=getLevelPrefix(parentobjname);
	var maxdid = getLevelCount(levelprefix);
	var did;
	var objname;

	for (did=1; did<=maxdid; did++)
	{
  		objname=levelprefix+did;
		setOpacity(objname, 10);
	}

	// special case logic for my intro page
	if (aobjname == rootobject)
	{
		setOpacity("introTop", 10);
		setOpacity("introBottom", 10);
	}
}


// sets the visual opacity of the object to the value specified
function setOpacity(aobjname, aopacity) {

	var titem;

	titem = document.getElementById(aobjname); // get the object
	if ((titem == null) || (titem == undefined))
		return;

	// try to set opacity for various browser types, if fail just will not happen
	if (titem.style.opacity != null)
		titem.style.opacity = aopacity/10;				// standard browsers
	else if (titem.style.filter != null)
		titem.style.filter = 'alpha(opacity=' + aopacity*10 + ')';	// IE browsers
	else if (titem.style.MozOpacity != null)
		titem.style.MozOpacity = (aopacity / 10);			// older Mozilla browsers
	else if ( titem.style.KhtmlOpacity != null)
		titem.style.KhtmlOpacity = (aopacity / 10);			// older Gecko browsers

}



function initItem(objname) {

	var mmitem;

	if (debug > 10) window.alert("initItem:"+objname);

	screewidth=findLivePageWidth();
	screenheight=findLivePageHeight();
	xorigin=screewidth/2;
	yorigin=screenheight/2;


  	mmitem = document.getElementById(objname); // get the "mmitem" object
	if ((mmitem == null) || (mmitem == undefined))
	{
		;	// nothing to do yet
	}
	else
	{
/*
		if (objname == rootobject)
		{
			mmitem.varOriginalHTML = mmitem.innerHTML;
		}
*/


//	window.alert("mmitem.zz="+mmitem.style.top);
  		mmitem.varName=objname;	// easy access for name
  		mmitem.varIsOpen=0;		// is this menu open, can you see the decendants
		mmitem.varTheta=0;		// angle from parent
		mmitem.varTTL=0;		// time for the animation to live
  		// move to centre
  		mmitem.style.left = xorigin - 100;
  		mmitem.style.top = yorigin - 40;
  		if (objname != rootobject)
  			mmitem.style.visibility="hidden";
  	}
}



function init(aobjname) {

	var objname;
	var aobjname;
	var levelprefix;
	var did;

	if (debug > 10) window.alert("init:"+aobjname);

	levelprefix = getLevelPrefix(aobjname);
	initItem(aobjname);

	// init all at same level
	for (did=1; did<totmaxdid; did++)
	{
  		objname=levelprefix+did;
  		mmitem = document.getElementById(objname); // get the "mmitem" object
		if ((mmitem == null) || (mmitem == undefined))
			continue;

		init(objname);	// init decendants by recurrsing back down
	}

}


function findLivePageHeight() {
  if (debug) window.alert("findLivePageHeight.1");

  if ((window.innerHeight != null) && (window.innerHeight != undefined))
  {
     if (debug) window.alert("findLivePageHeight.2="+window.innerHeight);
  	return window.innerHeight;
  }

  if (document.body.clientHeight != null)
  {
     if (debug) window.alert("findLivePageHeight.3="+document.body.clientHeight);
    return document.body.clientHeight;    
}
     if (debug) window.alert("findLivePageHeight.4");
return (-1);
}

function findLivePageWidth() {
     if (debug) window.alert("findLivePageWidth.1");
  if ((window.innerWidth != null) && (window.innerWidth != undefined))
  {
     if (debug) window.alert("findLivePageWidth.2="+window.innerWidth);
	return window.innerWidth;
  }
  	
  if (document.body.clientWidth != null)
{
     if (debug) window.alert("findLivePageWidth.3="+document.body.clientWidth);
  	return document.body.clientWidth;
}
     if (debug) window.alert("findLivePageWidth.4");
return (-1);

}









function line(x1,y1,x2,y2,divi,document)
{
//window.alert("line.1="+x1);
var bla;
var m;
var startx;
var starty;
	
//document.getElementById(rootobject).innerHTML = divi.varOriginalHTML;

bla = "";
m = Math.round(Math.sqrt( (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2) ));
startx = x1;
starty = y1;
bla += '<div style="z-index:0;position:absolute;left:'+ startx +'px;top:'+ starty+'px;width:1px;height:1px;background:#ff0000"></div>';

for( i=0; i<m; i++ )
{
  startx = Math.round( x1+(x2-x1)*i/m);
  starty =  Math.round( y1+(y2-y1)*i/m);
  bla += '<div style="z-index:0;position:absolute;left:'+ startx +'px;top:'+ starty+'px;width:1px;height:1px;background:#ff0000"></div>';  
}
t1 = document.getElementById(divi).innerHTML;
   // window.alert(bla);
document.getElementById(divi).innerHTML = t1 + bla;

}



function doLine(aobj) {
  var objname;
  var mmitem;
  var xp;
  var yp;
  var xc;
  var yc
  var itterations;
  var parentobjname;
  var tm;

screewidth=findLivePageWidth();
screenheight=findLivePageHeight();
offx=screewidth/2-100;
offy=screenheight/2-40;
objname=aobj;
parentobjname=getParentObjectName(aobj);

if (debug>10)  window.alert("drawing line " + aobj+" with parent "+parentobjname);

if (objname == rootobject)
{
	return; // don't move this one
}

// need to get coords with origin from parent object
pmmitem = document.getElementById(parentobjname);
xorigin=parseInt(pmmitem.style.left);
yorigin=parseInt(pmmitem.style.top);

mmitem = document.getElementById(objname); // get the "mmitem" object
xp=parseInt(mmitem.style.left);
yp=parseInt(mmitem.style.top);


if (debug>10) window.alert(mmitem.varName);
if (debug>10) window.alert(mmitem.style.left);
  xc=xorigin;
  yc=yorigin;
if (debug>10) window.alert("xc="+xc+" , yc="+yc + ", xp="+xp+" , yp="+yp + " itterations="+itterations);
if (debug>10) window.alert(mmitem.varTheta);

if (debug>10) window.alert(mmitem.style.left);
mmitem.style.left=xp+'px';
if (debug>10) window.alert(mmitem.style.left);
mmitem.style.top=yp+'px';

// now draw a line back to parent item
if (1==2)
{
//	line( offx-xp, offy-yp, xorigin-offx, yorigin-offy, objname, document );
//	line(xp-offx, yp-offy, xp+10-offx, yp+20-offy, objname, document );
//	line(xp, yp, xc, yc, "mindmapMenuDiv", document );
	line(xp-offx, yp-offy, xc-offx, yc-offy, "mmitemObject0", document );

}

}






/*
function getWindowCoords(aobj) {
    aobj.canvasX = (document.documentElement.clientWidth||document.body.clientWidth||document.body.scrollWidth);
    aobj.canvasY = (document.documentElement.clientHeight||document.body.clientHeight||document.body.scrollHeight);
    aobj.screenY = self.canvasY;
    aobj.scrollY = parseInt(window.scrollY||document.documentElement.scrollTop||document.body.scrollTop);
    aobj.canvasY += self.scrollY;

	// or for Safari and Opera
    aobj.canvasX = window.innerWidth;
    aobj.canvasY = window.innerHeight;
    aobj.screenY = self.canvasY;
    aobj.scrollY = parseInt(window.scrollY||document.documentElement.scrollTop||document.body.scrollTop);
    aobj.canvasY += self.scrollY;
}
*/



/*

// will use single timer for max performance var timer = setInterval(animateAllMitterationsenuItems,20);
// or one per object
function animateAllMenuItems() {
  for (var i=objectsToAnimate.length; i--;) {
    objectsToAnimate[i].move();
  }
}

function drawLine( lineObjectHandle, Ax, Ay, Bx, By, lineImgPath )
{
	//	lineObjectHandle = an IMG tag with position:absolute
	var
		xMin		= Math.min( Ax, Bx ),
		yMin		= Math.min( Ay, By ),
		xMax		= Math.max( Ax, Bx ),
		yMax		= Math.max( Ay, By ),
		boxWidth	= Math.max( xMax-xMin, 1 ),
		boxHeight	= Math.max( yMax-yMin, 1 ),
		tmp		= Math.min( boxWidth, boxHeight ),
		smallEdge	= 1,
		newSrc


	while( tmp>>=1 )
		smallEdge<<=1

	newSrc = lineImgPath+ smallEdge +( (Bx-Ax)*(By-Ay)<0?"1up.gif":"1down.gif" )
	if( lineObjectHandle.src.indexOf( newSrc )==-1 )
		lineObjectHandle.src = newSrc

	with( lineObjectHandle.style )
	{
		width	= boxWidth	+"px"
		height	= boxHeight	+"px"
		left	= xMin		+"px"
		top	= yMin		+"px"
	}
}
*/

/*
	bla = "";
	lineLength = Math.sqrt( (xp-x0)*(xp-x0)+(yp-y0)*(yp-y0) );
	for( i=0; i<lineLength; i++ )
	{
		bla += "<div style='position:absolute;left:"+ Math.round( xp+(x0-xp)*i/lineLength  ) +"px;top:"+ Math.round( yp+(y0-yp)*i/lineLength  ) +"px;width:1px;height:1px;background:#000'></div>";
	}
	document.body.innerHTML += bla;
*/




