//*** CLASS MenuLevel **************************************************
function MenuLevel(id, groundLevel, menuAvatar) {
	this._id = id;
	this._items = new Array(); //container for objects that apply to interface MenuItem.
	this._isLoaded = 0;
	this._groundLevel = groundLevel;
	this._menuAvatar = menuAvatar;	//related front end object
	
	//new stuff
	this._animationMode = "wheel";
	if(menuAvatar != "") { this._animationMode = menuAvatar._defaultMenuMode; }
	this._animIterator = 0;
	this._wheelRadius = 0;
	this._clockwise = 1; // set to -1 or 1
	this._isHorizontal = 1;
	this._wheelCenterX = parseInt(VIRTUAL_SPACE_WIDTH / 2); //init center for wheel animation
	this._wheelCenterY = groundLevel; //parseInt(VIRTUAL_SPACE_HEIGHT / 2);
	this._wheelCenterZ = parseInt(VIRTUAL_SPACE_DEPTH / 2);
}

MenuLevel.prototype._id;
MenuLevel.prototype._items;
MenuLevel.prototype._isLoaded;
MenuLevel.prototype._groundLevel;
MenuLevel.prototype._menuAvatar;
MenuLevel.prototype._animationMode;
MenuLevel.prototype._animIterator;
MenuLevel.prototype._wheelRadius;
MenuLevel.prototype._clockwise;
MenuLevel.prototype._isHorizontal;
MenuLevel.prototype._wheelCenterX;
MenuLevel.prototype._wheelCenterY;
MenuLevel.prototype._wheelCenterZ;

MenuLevel.prototype.populateXML = function(menuXML) {
	//parse XML SOAP response
	var NewMenuData = new Array();
	$("menu/*", menuXML).each( function() {
		//access to selected xml-element via $(this)
		var label = "";
		var contentUrl ="";
		var imageUrl = "";
		var imageWidth = "";
		var imageHeight = "";
		if( $(this).children("title") ) { label= $(this).children("title").text(); }
		if( $(this).children("url") ) { contentUrl = $(this).children("url").text(); }
		if( $(this).children("image").length > 0 ) {
			label="";
			imageUrl = $(this).children("image").text();
			imageWidth = 95; //$(this).children("image").children("width").text();
			imageHeight = 90; //$(this).children().filter("image").eq(0).attr("height");
			//alert($(this).children("image").eq(0).attr("width"));
			
		}
		if( $(this).is("submenu") ) {
			if( $(this).attr("mode") == "wheel") {
				var MenuEntry = new Array(MENU_ITEM_TYPE_WHEELMENU, label, contentUrl, imageUrl, imageWidth, imageHeight);
				NewMenuData.push(MenuEntry);
			}
			if( $(this).attr("mode") == "shuffle") {
				var MenuEntry = new Array(MENU_ITEM_TYPE_SHUFFLEMENU, label, contentUrl, imageUrl, imageWidth, imageHeight);
				NewMenuData.push(MenuEntry);
			}
		}//if
		if( $(this).is("page") ) {
			var MenuEntry = new Array(MENU_ITEM_TYPE_PAGE, label, contentUrl, imageUrl, imageWidth, imageHeight  );
			NewMenuData.push(MenuEntry);
		}//if
		if( $(this).is("link") ) {
			var MenuEntry = new Array(MENU_ITEM_TYPE_LINK, label, contentUrl, imageUrl, imageWidth, imageHeight  );
			NewMenuData.push(MenuEntry);
		}//if
	});//each
	this.populate(NewMenuData);
}//populateXML

MenuLevel.prototype.populate = function(MenuDataAry) {
	for (var i=0; i < MenuDataAry.length; i++) {
		//generate new avatar for the item
		var NewAvatar = "";
		
		//calculate initial avatar sizes
		//TODO: substitute with browser auto-sizing of boxes
		var defaultWidth = 12 * MenuDataAry[i][1].length;
		var defaultHeight = 20;
		if(MenuDataAry[i][1].length > 9) {
			defaultWidth = 6 * MenuDataAry[i][1].length;
			defaultHeight = 40;
		}
		if(MenuDataAry[i][1].length > 30) {
			defaultWidth = 6 * MenuDataAry[i][1].length;
			defaultHeight = 60;
		}
		
		if(MenuDataAry[i][0] == MENU_ITEM_TYPE_PAGE) {
			var defaultBgColor = "#DDDDDD";
			if(MenuDataAry[i][3] != "") {
				//has image url
				defaultBgColor = "transparent";
				defaultWidth = MenuDataAry[i][4];
				defaultHeight = MenuDataAry[i][5];
			}
			NewAvatar = new PageAvatar(i, 0, MenuDataAry[i][1], MenuDataAry[i][2], this, defaultWidth, defaultHeight, defaultBgColor, "#222222", "#777777", MenuDataAry[i][3]);
		}
		
		if(MenuDataAry[i][0] == MENU_ITEM_TYPE_LINK) {
			if(MenuDataAry[i][3] != "") {
				//has image url
				defaultWidth = MenuDataAry[i][4];
				defaultHeight = MenuDataAry[i][5];
			}
			NewAvatar = new PageAvatar(i, 1, MenuDataAry[i][1], MenuDataAry[i][2], this, defaultWidth, defaultHeight, "transparent", "#EEEEFF", "#66DD77", MenuDataAry[i][3]);
		}
		if(MenuDataAry[i][0] == MENU_ITEM_TYPE_SHUFFLEMENU) {
			NewAvatar = new MenuAvatar(i, MenuDataAry[i][1], MenuDataAry[i][2], this, defaultWidth, defaultHeight, "#80A1C0", "#DDDDDD", "#888888", MenuDataAry[i][3], "shuffle");
		}
		if(MenuDataAry[i][0] == MENU_ITEM_TYPE_WHEELMENU) {
			NewAvatar = new MenuAvatar(i, MenuDataAry[i][1], MenuDataAry[i][2], this, defaultWidth, defaultHeight, "#80A1C0", "#DDDDDD", "#888888", MenuDataAry[i][3], "wheel");
		}
		
		//lift vanishing point to menu ground level
		NewAvatar._projection._vanishY = this._groundLevel - LEVEL_HEIGHT;
		
		var randX = 50;
		var randY = this._groundLevel;
		var randZ = Math.random() * VIRTUAL_SPACE_DEPTH;
		
		NewAvatar._projection.set3DPosition(randX, randY, randZ);
		this._items.push(NewAvatar);
		
	}//for
	
	//init radius for wheel animation
	this._wheelRadius = 25 * this._items.length;
	if(this._wheelRadius < 100) { this._wheelRadius = 100; }
	if(this._wheelRadius > 250) { this._wheelRadius = 250; }
	
	this._isLoaded = 1;
}

MenuLevel.prototype.finishedLoading = function() {
	//menu data may not be available until asynchron SOAP request finishes
	var success = 0;
	if(this._isLoaded == 1) {
		if(OPEN_MENU_INTERVAL) {
			window.clearInterval(OPEN_MENU_INTERVAL); //also cleared in SOAP timeout and error handlers for save fallback.
		}
		for(var i=0; i < this._items.length; i++) {
			this._items[i].showDOM();
		};
		success = 1;
	} else {
		success = 0;
	}
	return success;
}

MenuLevel.prototype.formWheel = function(centerX, centerY, centerZ, radius) {
	this._wheelCenterX = centerX;
	this._wheelCenterY = centerY;
	this._wheelCenterZ = centerZ;
	this._wheelRadius = radius;
	
	var divisor = 1;
	if(this._items.length != 0) { divisor = this._items.length };
			
	var initCirclePhi = 0;
	for(var i=0; i < this._items.length; i++) {
		if(this._items[i]._isOpened == 0 && this._items[i]._isParked == 0) {
			this._items[i]._projection.set3DPosition(centerX + (this._wheelRadius * Math.sin(initCirclePhi)), centerY, centerZ + (radius * Math.cos(initCirclePhi)) );
			
			//increase initCirclePhi iterator, full circle is 2 * PI
			initCirclePhi = initCirclePhi + (2 * Math.PI) / divisor;
			if(initCirclePhi > 2 * Math.PI) { initCirclePhi = 0; }
		}//if
	}//for
}//formWheel

MenuLevel.prototype.animate = function() {
	//PERFORMANCE CRITICAL FROM HERE ON: avaid any cpu-step possible!
	
	//animate temporary movements
	for(var i=0; i < TEMP_ANIMATION_STACK.length; i++) {
		if(TEMP_ANIMATION_STACK[i]._isSelfTargeting == 1) {
			this.animateLinear(TEMP_ANIMATION_STACK);
		}
	}
	
	//animate menu items depending on current mode
	if(this._animationMode == "linear") {
		//this.animateLinear();
		return; // !
	}
	if(this._animationMode == "wheel") {
		this.animateWheel();
		return; // !
	}
	if(this._animationMode == "shuffle") {
		this.animateShuffle();
		return; // !
	}
}//animate

//LINEAR animation for menu items
MenuLevel.prototype.animateLinear = function(AnimationStack) {
	for(var i=0; i < AnimationStack.length; i++) {
		if(AnimationStack[i]._isSelfTargeting == 1) {
			AnimationStack[i]._projection.stepToTarget();
		}
	}//for
}//animateLinear

//SHUFFLE animation for menu items
MenuLevel.prototype.animateShuffle = function() {
	for(var i=0; i < this._items.length; i++) {
		//identify idle avatars and start them moving again
		if(this._items[i]._isSelfTargeting == 0 && this._items[i]._isOpened == 0 && this._items[i]._isParked == 0 && this._items[i]._isMouseOver == 0) {
		
			//choose random target and start moving again
			this._items[i]._isSelfTargeting = 1; //flag instantly as being busy with moving
			//set a random target in virtual space within Y-ground layer
			var targetX = Math.random() * VIRTUAL_SPACE_WIDTH;
			var targetY = this._groundLevel;
			var targetZ = Math.random() * VIRTUAL_SPACE_DEPTH;
			this._items[i]._projection.setTargetPosition(targetX, targetY, targetZ);
			
			this._items[i]._projection.moveToTarget();
			
		} else {
			if(this._items[i]._isSelfTargeting == 1 && this._items[i]._isMouseOver == 0) {
				this._items[i]._projection.moveToTarget();
			}
		}//if
	}//for
}//animateShuffle


MenuLevel.prototype.reshuffle = function() {
	for(var m=0; m < this._items.length; m++) {
		if(this._items[m]._isOpened == 0 && this._items[m]._isParked == 0) {
			this._items[m]._isSelfTargeting = 0;
		}
	}//for
}//reshuffle


//WHEEL animation for menuItems
MenuLevel.prototype.animateWheel = function() {
					//Remembering some maths on circles
					//Umfang, Flaeche: u=2*PI*radius, A=PI*r^2  =u^2/(4*PI)
					//Linear translation: pos = pos + 1
					//Wave translation: pos = pos + sin(iterator) with iterator staying between 0 <= i <= 2*PI
					//		y = sin(x): A full wave-period is 360 degree = 2*PI, Amplitude=1
					//			Nullpunkte:			sin(x) = 0 AT x=0 AND x=PI    //sind auch Wendepunkte
					//			Hochpunkt:	max sin(x)=1 AT x=PI/2
					//			Tiefpunkt:			min sin(x)=-1 AT x=(3*PI)/2
					//		y = a * sin(b*x): Full wave period is 360 degree = (2*PI)/b, Amplitude=a
					//			Nullpunkte:			=0 AT x=0 AND x=(PI/b)
					//			Hochpunkt:			max=a AT x=PI/(2*b)
					//			Tiefpunkt:				min=-a AT x=(3*PI)/(2*b)
					//			Parallel translation:	?
					//			Symetrie examples: sin(-x)= -sin(x); cos(-x)=cos(x);
					//			Cosinus: sin(x + PI/2)= cos(x), so the cosinus curve is the sinus curve shifted by PI/2 to the right.
					//				cos(x + PI/2)= -sin(x); sin(x+PI)= -sin(x); cos(x+PI)= -cos
					
	var initCirclePhi = 0;
	for(var i=0; i < this._items.length; i++) {
		if(this._items[i]._isOpened == 0 && this._items[i]._isParked == 0) {			
			var translationPhi = initCirclePhi + this._animIterator;
			//var tmpCenterY = this._wheelCenterY;
			//if(this._items[i]._isMouseOver == 1) {
			//	 tmpCenterY = tmpCenterY - 30;
			//}
			if(this._isHorizontal == 1) {
				this._items[i]._projection.setTargetPosition(this._wheelCenterX + (this._wheelRadius * Math.sin(translationPhi)), this._wheelCenterY, this._wheelCenterZ + (this._wheelRadius * Math.cos(translationPhi)) );
			} else {
				this._items[i]._projection.setTargetPosition(this._wheelCenterX, this._wheelCenterY  + (this._wheelRadius * Math.sin(translationPhi)), this._wheelCenterZ + (this._wheelRadius * Math.cos(translationPhi)) );
			}
			this._items[i]._isSelfTargeting = 1;
			this._items[i]._projection.moveToTarget();
			
			//increase initCirclePhi iterator, full circle is 2 * PI
			var divisor = 1;
			if(this._items.length != 0) { divisor = this._items.length };
			initCirclePhi = initCirclePhi + (2 * Math.PI) / divisor;
			if(initCirclePhi > 2 * Math.PI) { initCirclePhi = 0; }
		
		} else {
			if(this._items[i]._isSelfTargeting == 1) {
				this._items[i]._projection.moveToTarget();
			}
		}
	}//for
	
	//increase animating iterator
	this._animIterator = this._animIterator + (0.05 * this._clockwise);
	if(this._animIterator > 2 * Math.PI) { this._animIterator = 0; }
}//animateWheel

//TODO: BALL animation for menuItems
//TODO: CRYSTAL animation for menuItems

//*** END CLASS MenuLevel ************************************************
