function initTreeScrolling() {
  //alert('x');
	
  var pane = $('tree');
	
	if (!pane || typeof(pane) == 'undefined') {
		return;
	}
	
	
  document.documentElement.style.overflow = 'scroll';
  document.documentElement.style.height = '100%';
	
  //document.documentElement.style.background = 'red';
  pane.style.overflow = '';
  pane.style.height = '';
  
  var clientH = document.documentElement.offsetHeight;
  var totalH  = document.documentElement.scrollHeight;
	
  var treeH  = pane.offsetHeight;
	
	if (pane.offsetTop + treeH < clientH) {
		treeH = clientH - pane.offsetTop;
	}
	
  var frameH = totalH - treeH;
  var paneH  = clientH - frameH;
	
	
  
  //alert([clientH, totalH, treeH, frameH, paneH].join('\n'));
  
  var imgUrl = document.getElementsByTagName('script')[0].src.replace(/^(.*)\/js\//, '$1/img');
  
  if (paneH > 0) {
		//document.body.style.overflow = 'hidden';
  	document.documentElement.style.overflow = 'hidden';
  	pane.style.height = paneH + 'px';
  	pane.style.width = '100%';
    pane.style.overflow = 'scroll';
    
    var tmp = $('minimap');
    if (tmp) {
      tmp.parentNode.removeChild(tmp);
      tmp = null;
    }
    
    var minimap = document.createElement('div');
    $(minimap).id = 'minimap';
    minimap.style.top = (pane.offsetTop + 10) + 'px';
    minimap.style.right = (30) + 'px';
    
    var w = 300; // px
    var pct = (w-5) / pane.scrollWidth;
    var h = (w * (pane.scrollHeight / pane.scrollWidth));
    minimap.style.height = h + 'px';
    
    $$('#tree .node').each(function(el) {
      var newEl = el.cloneNode(false);
			
			var parent = el;
      try {
			while (parent && parent.parentNode && !parent.hasClass('marriage-holder') && parent.id != 'tree') {
				parent = parent.parentNode;
			}
			if (parent && parent.hasClass('marriage-holder') && parent.getStyle('visibility')=='hidden') {
				return;
			}
      
      }			
      catch (e) {
        //alert(parent);
      }
      newEl.style.width  = Math.floor(0.5 + el.offsetWidth  * pct) + 'px';
      newEl.style.height = Math.floor(0.5 + el.offsetHeight * pct) + 'px';
      newEl.style.left   = Math.floor(0.5 + el.offsetLeft   * pct) + 'px';
      newEl.style.top    = Math.floor(0.5 + el.offsetTop    * pct) + 'px';
      minimap.appendChild(newEl);
    });
		
		var w1 = Math.floor((w-4) * (pane.offsetWidth  / pane.scrollWidth ));
		var h1 = Math.floor((h-4) * (pane.offsetHeight / pane.scrollHeight));
    
    var viewport = document.createElement('div');
    viewport.id = 'viewport';
    viewport.style.width  = w1 + 'px';
    viewport.style.height = h1 + 'px';

    minimap.appendChild(viewport);
		
		var faders = {};
		faders['n'] = document.createElement('div'); faders['n'].className = 'n fader';	minimap.appendChild(faders['n']);
		faders['e'] = document.createElement('div'); faders['e'].className = 'e fader';	minimap.appendChild(faders['e']);
		faders['s'] = document.createElement('div'); faders['s'].className = 's fader';	minimap.appendChild(faders['s']);
		faders['w'] = document.createElement('div'); faders['w'].className = 'w fader';	minimap.appendChild(faders['w']);
                                                                                                       
/*
    $(minimap).addEvent('scroll', function() {
      viewport.style.left   = (w * (pane.scrollLeft   / (pane.scrollWidth -0*pane.offsetWidth ))) + 'px';
      viewport.style.top    = (h * (pane.scrollTop    / (pane.scrollHeight-0*pane.offsetHeight))) + 'px';
    });
*/

		var updateFn = function() {
			var x1 = Math.floor((w-4) * (pane.scrollLeft   / (pane.scrollWidth -0*pane.offsetWidth )));
			var y1 = Math.floor((h-4) * (pane.scrollTop    / (pane.scrollHeight-0*pane.offsetHeight)));
			
			var x2 = x1 + w1;
			var y2 = y1 + h1;
		
      viewport.style.left   = x1 + 'px';
      viewport.style.top    = y1 + 'px';
			
			try {
				faders['n'].style.left   = (x1) + 'px';
				faders['n'].style.width  = (w-x1) + 'px';
				faders['n'].style.top    = '0px';
				faders['n'].style.height = (y1) + 'px';
				faders['n'].style.visibility = 'visible';
			}
			catch (e) {
				faders['n'].style.visibility = 'hidden';
			}
			
			try {
				faders['e'].style.left   = (4+x2) + 'px';
				faders['e'].style.width  = (w-x2-4) + 'px';
				faders['e'].style.top    = (y1) + 'px';
				faders['e'].style.height = (1+h-y1) + 'px';
				faders['e'].style.visibility = 'visible';
			}
			catch (e) {
				faders['e'].style.visibility = 'hidden';
			}
				
			try {
				faders['s'].style.left   = '0px';
				faders['s'].style.width  = (4+x2) + 'px';
				faders['s'].style.top    = (4+y2) + 'px';
				faders['s'].style.height = (h-y2-3) + 'px';
				faders['s'].style.visibility = 'visible';
			}
			catch (e) {
				faders['s'].style.visibility = 'hidden';
			}
				
			try {
				faders['w'].style.left   = '0px';
				faders['w'].style.width  = (x1) + 'px';
				faders['w'].style.top    = '0px';
				faders['w'].style.height = (y2+4) + 'px';
				faders['w'].style.visibility = 'visible';
			}
			catch (e) {
				faders['w'].style.visibility = 'hidden';
			}
		};
		
		updateFn();
    
    window.setInterval(updateFn, 100);
		
		pane.addEvent('scroll', updateFn);
		
		minimap.addEvent('mousedown', (function(event) {
			
			$(minimap).addClass('moving');
			
      var x = (event.client.x - minimap.offsetLeft) - viewport.offsetWidth / 2;
      var y = (event.client.y - minimap.offsetTop)  - viewport.offsetHeight / 2;
      
      x = (x / w) * (pane.scrollWidth -2-0*pane.offsetWidth );
      y = (y / h) * (pane.scrollHeight -2-0*pane.offsetHeight );
      
      //alert([x, y].join('\n'));
      
      pane.scrollLeft = x;
      pane.scrollTop = y;
      
    }).bindWithEvent(minimap));
		
		minimap.addEvent('mouseup', function() {
			$(minimap).removeClass('moving');
		});
    
    minimap.addEvent('click', (function(event) {
      var x = (event.client.x - minimap.offsetLeft) - viewport.offsetWidth / 2;
      var y = (event.client.y - minimap.offsetTop)  - viewport.offsetHeight / 2;
      
      x = (x / w) * (pane.scrollWidth -2-0*pane.offsetWidth );
      y = (y / h) * (pane.scrollHeight -2-0*pane.offsetHeight );
      
      //alert([x, y].join('\n'));
      
      pane.scrollLeft = x;
      pane.scrollTop = y;
      
    }).bindWithEvent(minimap));

    
    pane.parentNode.appendChild(minimap);

  }
  else {
    document.documentElement.style.height = '';
  }
}

var oldEmSize = null;
var resizeTriggers = [];

function checkEmSize() {
	try {
  var newEmSize = $('em').offsetWidth;
  if (oldEmSize != newEmSize) {
    oldEmSize = newEmSize;
    for (var i=0; i<resizeTriggers.length; i++) {
			(function(fn) { fn(); })(resizeTriggers[i]);
		}
  }
	}
	catch (e) {
		//
	}
}

window.addEvent('domready', function() {
  initTreeScrolling();
  window.setInterval(checkEmSize, 250);
}	);