////////////////////////////////////////////////////////////////////////////////////
// SVG Nodetree
//
// A drag-and-drop discoverable tree of menu nodes
//
// @author René Lantzsch
// @version 0.6a
//
////////////////////////////////////////////////////////////////////////////////////

// SETUP
var settings = {
	showpath:	true,
	distance:	400,
	minimum:	0,
	nodecenter:	{ x: 20, y: 5 },
	window:		{ width: 300, height: 400 }
};

// Funktion zum Sound abspielen
function playSound(url){
	$('soundbox').html('<embed src="'+url+'" hidden=true autostart=true loop=true>');
}

// Setzt und gibt das Elementattribut center zurück
jQuery.fn.setcenter = function(){
	var position = this.position();
	var center = {
			x: (position.left + (this.width()/2)+settings.nodecenter.x),
			y: (position.top + (this.height()/2)+settings.nodecenter.y)
		};
	this.data('center', center);
	return this;
};

jQuery.fn.getcenter = function(){
	return this.data('center');
};

// Kleiner Trick um das Markieren von Nodes beim Draggen zu verhindern
document.onselectstart = new Function ("return false")
if(window.sidebar) {
	document.onmousedown = disableselect;
	document.onclick = reEnable;
}

function disableselect(e) {
	return false;
}

function reEnable() {
	return true;
}



$(document).ready(function() {
	// HTML-Elemente
	var $chalkboard = $('#svg-chalkboard');
	var $allnodes = $('.node');
	var $node_start = $('.start');
	var $nodes_lvl1 = $('.waypoint-lvl1');
	var $nodes_lvl2 = $('.waypoint-lvl2');
	
	//$('body').draggable();
	
	function attachWindowsToNodes() {
		$('.ui-dialog').each(function(i, element) {
			if($(element).data('attachednode')) {
				$dialognode = $(element).data('attachednode');
				//console.log($(element).data('attachednode'));
				$(element).offset({
					//left:	$dialognode.offset().left + 50,
					left:	$dialognode.offset().left + 37,
					top:	$dialognode.offset().top + 38
				});
			}
		});
	}
	
	// leeren Raum bewegbar machen
	$chalkboard.draggable({
		drag: function(event, ui) {
			dialog = $('.ui-dialog');
			dialog.offset({ left: dialog_openingposition.left-Math.abs($chalkboard.offset().top)-500, top: dialog_openingposition.top-Math.abs($chalkboard.offset().top)-500 });
			//console.log(dialog);
			
			if($window) { 
				//console.log($window.dialog("position"));
				//console.log($('.ui-dialog').dialog('position', settings.nodecenter));
				
				//console.log($dialogdivs);
				
				attachWindowsToNodes();
				
				/*$dialognode = $dialogdiv.data('attachednode');
				$dialogdiv.offset({
					left:	$dialognode.offset().left + 50,
					top:	$dialognode.offset().top + 36
				});*/
			}
		},
		
		stop:	function(event, ui) {
					//console.log('chalkboard stop');
					attachWindowsToNodes();
				}
		//refreshPositions: true
	});
	
	// Startknoten bewegbar machen
	setDraggable($node_start);

	// Startknoten alle Kindknoten als Referenzattribute anhängen
	$node_start.data('subnodes', $nodes_lvl1);
	
	// Alle Kindknoten des Startknotens durchlaufen und jeweils deren Kindknoten zuweisen
	$node_start.data('subnodes').each(function(index, element){
		var $node = $(element);
		var $subnodes = $(element).parent('.branch').children('.waypoint-lvl2');
		$(element).data('subnodes', $subnodes);
		
		$node.droppable({
			drop: function(event, ui) {
				setDiscovered($node);
				$(event.target).droppable("destroy");
				//drawLinesBetween($(event.target), $(event.target).data('subnodes'));
			},
			accept:	'.start'
		});
		
		
		
		//$branch = $node.parent('.branch');
		
		//console.log($subnodes);
		
		//$acceptednode = $node.attr('id');

		$subnodes.droppable({
			// nur die jeweils vorhergehenden Nodes im Baum akzeptieren
			accept:	function(event, ui) {
						if(event.attr('id') == $node.attr('id')) {
							return true;
						} else {
							return false;	
						}						
					},
			drop:	function( event, ui ) {	setDiscovered($(event.target));	}
		});
	});
	
	// Nodetransparenzen je nach Entfernung zueinander setzen	
	function checkCollisions($dragged_node, $subnodes) {
		var startX = $dragged_node.getcenter().x;
		var startY = $dragged_node.getcenter().y;
			
		$subnodes.each(function(i, element) {
				
			$connected_node = $(element);
				
			var targetX = $connected_node.getcenter().x;
			var targetY = $connected_node.getcenter().y;
			
			var distance		= parseInt(Math.sqrt(Math.pow(startX - targetX, 2) + Math.pow(startY - targetY, 2)));
			var distanceRatio	= (settings.distance - distance) / settings.distance;
			
			if(distance <= settings.distance) {
				//if(i == 3) { console.log(percentage); }
				if(!$connected_node.hasClass('discovered') && !$connected_node.hasClass('discovered_txt')) {
					var percentage = distanceRatio + settings.minimum;
					
					if(!$connected_node.hasClass('inactive')) {
						$connected_node.css('opacity', percentage);
					} else {
						$connected_node.css('opacity', percentage/3);
					}
				} /*else {
					$connected_node.css('opacity', 1);
				}*/
			}
	
			//if(distance <= 100) {
				//setDiscovered($connected_node);		
				//if($connected_node.attr('ajax') && $connected_node.attr('ajax') != strLastVisitedPage) { openWindow($connected_node); }
			//}
		});
	}
	
	// discovered Highlight setzen bzw. Fenster öffnen, falls Endnode
	function setDiscovered($connected_node) {
		//console.log($connected_node);

		if($connected_node.hasClass('inactive')) {
			$connected_node.addClass('inactive-discovered');
			return;
		}
		
		if($connected_node.hasClass('textnode')) {
			$connected_node.addClass('discovered-txt');
		} else {
			$connected_node.addClass('discovered');
		}
		
		if($connected_node.attr('ajax') && $connected_node.attr('ajax') != strLastVisitedPage) { openWindow($connected_node); }
		else {
			setDraggable($connected_node);
		}
		
		/*$connected_node.draggable({
			drag:	function(event, ui) {
				console.log(event);
			}
		});*/
	}
			
	function drawDiscoveredBranches() {
		clear();
		
		drawLinesBetween($node_start, $node_start.data('subnodes'));
		
		$node_start.data('subnodes').each(function(i, element) {
			if($(element).hasClass('discovered')) {
				drawLinesBetween($(element), $(element).data('subnodes'));
			}
		});
		
	}
	
	// draggable einer Node initialisieren
	function setDraggable($node) {		
		$node.draggable({
			//iframeFix: true,
			zIndex:	2700,
			drag:	function(event, ui) {
						$dragged_node = $(event.target)
						//drawDiscoveredBranches();
						// Falls Pfadsichtbarkeit für alle erkundeten Pfade eingestellt, die Pfade des Startknotens mitrendern
						//if(settings.showpath) {
							//drawLinesBetween($node_start, $node_start.data('subnodes'));
							// und alle weiteren Pfade, die schon entdeckt wurden
							/*$node_start.data('subnodes').each(function(i, element) {				
								if($(element).hasClass('discovered')) {
									drawLinesBetween($(element), $(element).data('subnodes'));
								}
							});*/
							drawDiscoveredBranches();
						//} else {
						//	clear();
						//	drawLinesBetween($dragged_node, $dragged_node.data('subnodes'));
						//}
						checkCollisions($dragged_node, $dragged_node.data('subnodes'));
					},
			stop:	function(event, ui) {
						drawDiscoveredBranches();						
					}
			
			// ????
			/*dragStop:function(event, ui) {
						console.log('dragstop');
						$dragged_node = $(event.target)
						clear();
						drawLinesBetween($dragged_node, $dragged_node.data('subnodes'));
						checkCollisions($dragged_node, $dragged_node.data('subnodes'));
						
						// Falls Pfadsichtbarkeit für alle erkundeten Pfade eingestellt, die Pfade des Startknotens mitrendern
						if(settings.showpath) {
							drawLinesBetween($node_start, $node_start.data('subnodes'));
							// und alle weiteren Pfade, die schon entdeckt wurden
							$node_start.data('subnodes').each(function(i, element) {				
								if($(element).hasClass('discovered')) {
									drawLinesBetween($(element), $(element).data('subnodes'));
								}
							});
						}
					}*/
		});
	}



	// SVG RENDER SYSTEM (LINIEN)
	
	var svg = $('#svg-chalkboard').svg({onLoad:tutorial});
	var g = svg.svg('get');
	
	function tutorial(g) {
		$node_start.setcenter()
		g.text($node_start.getcenter().x + 90, $node_start.getcenter().y + 5, 'Drag me.', {fontFamily: 'Verdana', fontSize: 12, textAnchor: 'middle'});
	}

	// Linie zeichnen zwischen Element aus Parameter 1 un Elementen in Parameter 2 (Array)
	function drawLinesBetween($origin, $targets) {
		$origin.setcenter();
				
		$targets.each(function(i, element) {
			$(element).setcenter();
			var lineOpacity = ($(element).css('opacity') > 0.1) ? $(element).css('opacity') : 0.2;
			line = g.line($origin.getcenter().x, $origin.getcenter().y, $(element).getcenter().x, $(element).getcenter().y, {stroke: '#7DEEF7', 'stroke-width': 4, opacity: 50});
		});		
		
		/*var defs = g.defs();
		var path = g.createPath();
		g.path(defs, path.move(100, 200).curveC([[200, 100, 300, 0, 400, 100], [500, 200, 600, 300, 700, 200], [800, 100, 900, 100, 900, 100]]), {id: 'MyPath'}); 
		g.describe('Example toap02 - tspan within textPath');
		g.use('#MyPath', {fill: 'none', stroke: 'red'});
		
		var text = g.text('', {fontFamily: 'Verdana', fontSize: '42.5', fill: 'blue'});
		var texts = g.createText();
		g.text(text, texts.string('Drag ').span('me', {dy: -30, fill: 'red'}).span(',', {dy: 30}).string(' .'));*/
		
		
	}
	
	// Linien auf Chalkboard löschen
	function clear() {
		g.clear();
	}



	// DIALOGSYSTEM

	function handleSliderChange(event, ui)
	{
		$scrollWindow = $(event.target).next();
		$scrollContent = $(event.target).next().children('iframe');
		//console.log($scrollContent);
		
		var maxScroll = $scrollContent.attr("scrollHeight") - $scrollWindow.height();
		$scrollContent.animate({scrollTop: (100-ui.value) * (maxScroll / 100) }, 1000);
	}
	
	function handleSliderSlide(event, ui)
	{
		$scrollWindow = $(event.target).next();
		$scrollContent = $(event.target).next().children('iframe').contents().find('body');
		//console.log($scrollContent);
		
		var maxScroll = $scrollContent.attr("scrollHeight") - $scrollWindow.height();
		//console.log('ui.value: ' + ui.value);
		//console.log('maxScroll: ' + (maxScroll / 100));		
		//console.log('calc: ' + ui.value * (maxScroll / 100));
		
		$scrollContent.attr({scrollTop: /*ui.value*/ (100-ui.value) * (maxScroll / 100) });
	}
	
	$dialog = $('#dialog').dialog({ autoOpen: false });
	var dialog_openingposition = {};
	var $dialogdivs = [];
	var visible_dialogs = 0;
	var $window;
	var strLastVisitedPage = "";
	
	function openWindow($node) {

		//if($window) { $window.dialog('close'); }
		
		var temppos = $node.offset();
		//var posx = temppos.left + 100;
		var posx = temppos.left + 37; // 50 (o. slider)
		var posy = temppos.top + 38;
		var positionf = { left: posx, top: posy};
		
		strLastVisitedPage = $node.attr('ajax');

		content = $node.attr('ajax');
		
		$window = $.FrameDialog.create({
			url:		content,
			position:	positionf,
			draggable:	false,
			//resizable:	false,
			minWidth:	settings.window.width,
			width:		settings.window.width,
			maxWidth:	settings.window.width,
			height:		settings.window.height,
			modal:		false,
			buttons:	false,
			
			/*open:		function(event, ui) {
							$(event.target).find('iframe').css('width', 340);
							$(event.target).find('iframe').css('height', 500);
						},*/
			
			open:		function(event, ui) {
				
							//console.log(event.target);
							
							$(event.target).find('iframe').attr('scrolling', 'no');
							
							$(event.target).before('<div class="content-slider"></div>');
							
							//$slider = $('<div class="content-slider"></div>');
							
							//$slider.insertBefore($(event.target));
							
							//$slider.insertBefore($(event.target.parentNode));
							//console.log(event.target.parentNode);
							
							$(".content-slider").slider({
								animate: true,
								orientation: 'vertical',
								value: 100,
								change: handleSliderChange,
								slide: handleSliderSlide
							});
				
							var view_height = $(window).height();
							var node_y = $node.offset().top + 38;
							var dialog_bottom = node_y + settings.window.height;
							
							var bottom_space = view_height - dialog_bottom;
							
							//var bottom = dialog_bottom - view_height;
							
							//console.log(node_y);
							
							//console.log(view_height);
							//console.log(dialog_bottom);
							//console.log(bottom_space);
							
							var new_height = - bottom_space;
							
							//console.log($(event.target).parent('.ui-dialog'));
							//console.log(new_height);
							
							//console.log($(event.target).css('zIndex'));
							
						//	$(event.target).parent('.ui-dialog').css("height", new_height + "px !important");
							$(event.target).parent('.ui-dialog').css("top", posy);
						},
			close:		function(event, ui) {
							strLastVisitedPage = "";
							//console.log($node);
							if($node.hasClass('stub')) { $node.remove(); }
							//$chalkboard.draggable('enable');
					},
			// Verhindern dass node hinter dem Fenster verschwindet wenn man es fokussiert
			focus:		function(event, ui) {
							var $dialogdiv = $(event.target).parent('.ui-dialog');
							var dialogzindex = parseInt($dialogdiv.css('z-index'));
							$node.css('z-index', dialogzindex + 1);
						}
		});
		
		$node.css('opacity', '100 !important');
		
		visible_dialogs++;
		//$dialogdivs.push($window.parent('.ui-dialog'));
		
		//console.log($window.parent('.ui-dialog'));
		
		var $dialogdiv = $($window.parent('.ui-dialog'));
		
		$dialogdivs[visible_dialogs-1] = $($window.parent('.ui-dialog'));
		$dialogdivs[visible_dialogs-1].data('attachednode', $node)
		
		$node.css('z-index', parseInt($dialogdiv.css('z-index')) + 1);
		
		//console.log($node.css('z-index'));
		//console.log($dialogdiv.css('z-index'));
							
		$node.draggable({
			drag:		function(event, ui) {
							$dialogdiv.offset({
								left:	$(event.target).offset().left + 37, // 50 o. slider
								top:	$(event.target).offset().top + 38
							});
							
							drawDiscoveredBranches();
							
							/*$dragged_node = $(event.target)
							clear();
							drawLinesBetween($dragged_node, $dragged_node.data('subnodes'));
							checkCollisions($dragged_node, $dragged_node.data('subnodes'));
							
							// Falls Pfadsichtbarkeit für alle erkundeten Pfade eingestellt, die Pfade des Startknotens mitrendern
							if(settings.showpath) {
								drawLinesBetween($node_start, $node_start.data('subnodes'));
								// und alle weiteren Pfade, die schon entdeckt wurden
								$node_start.data('subnodes').each(function(i, element) {				
									if($(element).hasClass('discovered')) {
										drawLinesBetween($(element), $(element).data('subnodes'));
									}
								});
							}*/
						},
			// ????
			stop:		function(event, ui) {
							drawDiscoveredBranches();
							$dialogdiv.offset({
								left:	$(event.target).offset().left + 37,	// 50 o. slider
								top:	$(event.target).offset().top + 38
							});
						}
		});
		
		//$node.css('z-index', '20');
		//$window.css();
		
		return $dialog;
		
		//$chalkboard.draggable('disable');
	}

	
	
	// Für die Links im Menü (klickbare nodes ohne Baumbezug)
	$('.menu-node').click(function(event, ui) {
		$clicknode = $(event.target);
		if($clicknode.attr('ajax') != strLastVisitedPage) {
			$fakenode = $('<div class="stub node textnode" style="bottom:400px;right:300px;">Impressum</div>');
			$fakenode.attr('ajax', $clicknode.attr('ajax'));
			$fakenode.insertAfter($clicknode);
			openWindow($fakenode);
		}
	});
			
});
