/** Modified from original Node-Red source, for audio system visualization
 * vim: set ts=4:
 * Copyright 2014 IBM Corp.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 **/

RED.touch = RED.touch||{};
RED.touch.radialMenu = (function() {
	
	
	var touchMenu = null;
	var isActive = false;
	var isOutside = false;
	var activeOption = null;

	
	function createRadial(obj,pos,options) {
		isActive = true;
		try {
			var w = $("body").width();
			var h = $("body").height();
			
			touchMenu = d3.select("body").append("div")
				.style({
						position:"absolute",
						top: 0,
						left:0,
						bottom:0,
						right:0,
						"z-index": 1000
				})
				.on('touchstart',function() {
					hide();
					d3.event.preventDefault();
				});
					
			

	
			var menu = touchMenu.append("div")
				.style({
						position: "absolute",
						top: (pos[1]-80)+"px",
						left:(pos[0]-80)+"px",
						"border-radius": "80px",
						width: "160px",
						height: "160px",
						background: "rgba(255,255,255,0.6)",
						border: "1px solid #666"
				});
				
			var menuOpts = [];
			var createMenuOpt = function(x,y,opt) {
				opt.el = menu.append("div")
					.style({
						position: "absolute",
						top: (y+80-25)+"px",
						left:(x+80-25)+"px",
						"border-radius": "20px",
						width: "50px",
						height: "50px",
						background: "#fff",
						border: "2px solid #666",
						"text-align": "center",
						"line-height":"50px"
					});
				if (opt.icon) {
					opt.el.append("i").attr("class","icon "+opt.icon)
				} else {
					opt.el.html(opt.name);
				}
				if (opt.disabled) {
					opt.el.style({"border-color":"#ccc",color:"#ccc"});
				}
				opt.x = x;
				opt.y = y;
				menuOpts.push(opt);
				
				opt.el.on('touchstart',function() {
					opt.el.style("background","#999");
					d3.event.preventDefault();
					d3.event.stopPropagation();
				});
				opt.el.on('touchend',function() {
					hide();
					opt.onselect();
					d3.event.preventDefault();
					d3.event.stopPropagation();
				});
			}
			
			var n = options.length;
			var dang = Math.max(Math.PI/(n-1),Math.PI/4);
			var ang = Math.PI;
			for (var i=0;i<n;i++) {
				var x = Math.floor(Math.cos(ang)*80);
				var y = Math.floor(Math.sin(ang)*80);
				if (options[i].name) {
					createMenuOpt(x,y,options[i]);
				}
				ang += dang;
			}
			

			var hide = function() {
				isActive = false;
				activeOption = null;
				touchMenu.remove();
				touchMenu = null;
			}
					
			obj.on('touchend.radial',function() {
					obj.on('touchend.radial',null);
					obj.on('touchmenu.radial',null);
					
					if (activeOption) {
						try {
							activeOption.onselect();
						} catch(err) {
							RED._debug(err);
						}
						hide();
					} else if (isOutside) {
						hide();
					}
			});


			
			obj.on('touchmove.radial',function() {
			try {
				var touch0 = d3.event.touches.item(0);
				var p = [touch0.pageX - pos[0],touch0.pageY-pos[1]];
				for (var i=0;i<menuOpts.length;i++) {
					var opt = menuOpts[i];
					if (!opt.disabled) {
						if (p[0]>opt.x-30 && p[0]<opt.x+30 && p[1]>opt.y-30 && p[1]<opt.y+30) {
							if (opt !== activeOption) {
								opt.el.style("background","#999");
								activeOption = opt;
							}
						} else if (opt === activeOption) {
							opt.el.style("background","#fff");
							activeOption = null;
						} else {
							opt.el.style("background","#fff");
						}
					}
				}
				if (!activeOption) {
					var d = Math.abs((p[0]*p[0])+(p[1]*p[1]));
					isOutside = (d > 80*80);
				}
				
			} catch(err) {
				RED._debug(err);
			}

				
			});
			
		} catch(err) {
			RED._debug(err);
		}
	}    

	
	return {
		show: createRadial,
		active: function() {
			return isActive;
		}
	}

})();

