/*************************************************************************************************************
 * Gestion du menu contextuel
 ************************************************************************************************************/
var ContextMenu = {
	imgPath : '',
	radius : 35,
	circleRadiusRate : 1.5,
	sepHeight : [3, 0],
	margin : [0, 20],
	marginAtEnd : true,
	height : [22, 20],
	iconMargin : [1, 0],
	iconWidth : [16, 0],
	iconHeight : [16, 0],
	textMargin : [2, 5],
	boxAttr : [{
				off : {
					'fill' : "#462b09",
					// 'stroke-linejoin' : 'join',
					"fill-opacity" : .85,
					'stroke-width' : 0
				},
				on : {
					'fill-opacity' : .97,
					'stroke' : "#ff9900",
					'stroke-opacity' : .6,
					'stroke-width' : 1
				}
			}, {
				off : {
					'fill' : "#7b5422",
					// 'stroke-linejoin' : 'join',
					"fill-opacity" : .90,
					'stroke-width' : 0
				},
				on : {
					'fill-opacity' : .98,
					'stroke' : "#ff9900",
					'stroke-opacity' : .6,
					'stroke-width' : 1
				}
			}],
	textAttr : [{
				'font-family' : 'Tahoma,Helvetica,sans,Arial,sans-serif',
				'font-size' : '12px',
				'fill' : '#ff9900'
			}, {
				'font-family' : 'Tahoma,Helvetica,sans,Arial,sans-serif',
				'font-size' : '12px',
				'fill' : '#ffd98c'
			}],

	opened : false,
	fOldDocumentOnclick : null,
	fOldDocumentOncontextmenu : null,
	closeIt : null,

	sideLeft : false,
	width : null,
	paperCtn : null,
	paper : null,
	rs : null,
	textSandbox : null,

	open : function(centerX, centerY, items, sideLeft) {
		this.closeEnd();

		if (!this.paperCtn) {
			this.paperCtn = $(document.createElement("div"));
			this.paperCtn.style.position = "absolute";
			this.paperCtn.style.top = "0px";
			this.paperCtn.style.left = "0px";
			this.paperCtn.style.width = "200px";
			this.paperCtn.style.height = "200px";
			document.body.appendChild(this.paperCtn);
		}
		if (!this.paper) {
			this.paper = Raphael(this.paperCtn, 200, 200);
		}

		this.paperCtn.style.left = "0px";
		this.paperCtn.style.zIndex = -1;

		this.opened = true;

		if (null == this.closeIt) {
			this.closeIt = this.close.bindAsEventListener(this);
		}
		$(document).observe('mousedown', this.closeIt);

		var totalHeight = this.computeHeight(items, 0);
		if (totalHeight % 2 > 0) {
			totalHeight++;
		}
		// this.paper.setSize(this.paper.width, totalHeight);

		var noItems = this.countItems(items);

		var maxItemWidth = this.computeMaxWidth(items, 0);
		this.width = this.margin.collect(function(margin) {
					return maxItemWidth - margin;
				});
		var totalWidth = this.radius + maxItemWidth;

		this.sideLeft = (sideLeft && (totalWidth < centerX))
				|| ((totalWidth + centerX) > document.viewport.getDimensions().width);

		this.paper.setSize(totalWidth, totalHeight);
		this.paperCtn.setStyle({
					left : (this.sideLeft ? (centerX - totalWidth) : centerX) + "px",
					top : (centerY - (totalHeight / 2)) + "px",
					width : totalWidth + "px",
					height : totalHeight + "px"
				});

		this.circleRadius = totalHeight * this.circleRadiusRate;
		this.circleCenterX = (this.sideLeft
				? (maxItemWidth + this.circleRadius)
				: (this.radius - this.circleRadius));
		this.circleCenterY = totalHeight / 2;

		this.y = 0;
		this.rs = this.paper.set();
		items.each(function(item, index) {
					this.displayItem(item, 0, index);
				}, this);

		this.paperCtn.style.zIndex = 100000;
	},

	clickItem : function(e, link) {
		Event.stop(e);
		if (link) {
			window.setTimeout(link, 1);
		}
		this.close();
	},

	close : function(e) {
		if (!this.opened) {
			return;
		}
		if (e) {
			Event.stop(e);
		}

		$(document).stopObserving('mousedown', this.closeIt);

		this.rs.animate({
					"opacity" : "0"
				}, 300, this.closeEnd.bind(this));
	},

	closeEnd : function() {
		if (!this.opened) {
			return;
		}
		this.paperCtn.style.zIndex = -1;
		this.rs.remove();
		this.rs = null;
		this.opened = false;
	},

	countItems : function(items) {
		if (!items) {
			return 0;
		}
		var sum = 0;
		$A(items).each(function(item) {
					sum += 1 + this.countItems(item.items);
				}, this);
		return sum;
	},

	computeHeight : function(items, depth) {
		if (!items) {
			return 0;
		}
		var sum = 0;
		$A(items).each(function(item, i) {
			sum += (i > 0 ? this.sepHeight[depth] : 0) + this.height[depth]
					+ this.computeHeight(item.items, depth + 1);
		}, this);
		return sum;
	},

	computeMaxWidth : function(items, depth) {
		if (!this.textSandbox) {
			this.textSandbox = this.paper.text(-100, -100);
		}
		if (!items) {
			return 0;
		}
		var max = 0;
		$A(items).each(function(item, i) {
			this.textSandbox.attr(Object.extend({
						'text-anchor' : 'start',
						'text' : item.text
					}, this.textAttr[depth]));
			var textWidth = this.textSandbox.getBBox().width + 8;
			max = Math.max(max, this.margin[depth] + this.iconMargin[depth] + this.iconWidth[depth]
							+ this.textMargin[depth] + textWidth);
			max = Math.max(max, this.computeMaxWidth(item.items, depth + 1));
		}, this);
		return max;
	},

	displayItem : function(item, depth, index) {
		if (index > 0) {
			this.y += this.sepHeight[depth];
		}
		var y1 = this.y;
		var y2 = y1 + this.height[depth];
		var yMid = (y1 + y2) / 2;

		var radius = this.circleRadius + (this.marginAtEnd ? 0 : this.margin[depth]);
		var radiusb = radius + this.width[depth];
		var x1 = this.computeX(radius, y1);
		var x2 = this.computeX(radius, y2);
		var x1b = this.computeX(radiusb, y1);
		var x2b = this.computeX(radiusb, y2);

		var st = this.paper.set();

		var box = this.paper.path([("M " + x1 + " " + y1), ("H " + x1b),
				("A " + radiusb + " " + radiusb + " 0 0 0 " + x2b + " " + y2), ("H " + x2),
				("A " + radius + " " + radius + " 0 0 0 " + x1 + " " + y1)].join(" "));
		st.push(box);

		box.attrDef = this.boxAttr[depth];
		box.attr(box.attrDef.off);

		box.highliteTimeout = null;
		box.highliteOn = function() {
			window.clearTimeout(this.highliteTimeout);
			this.highliteTimeout = window.setTimeout(function() {
						if (box.attrDef) {
							this.attr(box.attrDef.on);
							// this.animate(box.attrDef.on, 150);
						}
					}.bind(this), 50);
		};
		box.highliteOff = function() {
			window.clearTimeout(this.highliteTimeout);
			this.highliteTimeout = window.setTimeout(function() {
						if (box.attrDef) {
							this.attr(box.attrDef.off);
							// this.animate(box.attrDef.off, 150);
						}
					}.bind(this), 50);
		};

		if (item.icon) {
			var icon = this.paper.image(this.imgPath + item.icon + '.png',
					(this.sideLeft ? (Math.min(x1, x2) - this.iconMargin[depth] - this.iconWidth[depth]) : (Math.max(
							x1, x2) + this.iconMargin[depth])), (yMid - this.iconHeight[depth] / 2), this.iconWidth[depth],
					this.iconHeight[depth]);
			st.push(icon);
		}

		var textMargin = this.iconMargin[depth] + this.iconWidth[depth] + this.textMargin[depth];
		var text = this.paper.text((this.sideLeft
						? (Math.min(x1, x2) - textMargin)
						: (Math.max(x1, x2) + textMargin)), yMid, item.text);
		st.push(text);
		text.attr(Object.extend({
					'text-anchor' : this.sideLeft ? 'end' : 'start'
				}, this.textAttr[depth]));

		if (item.link) {
			st.hover(box.highliteOn.bind(box), box.highliteOff.bind(box));
			st.click(this.clickItem.bindAsEventListener(this, item.link));
		}

		this.rs.push(st);

		st.depth = depth;

		this.y += this.height[depth];

		if (item.items) {
			item.items.each(function(subitem, index) {
						this.displayItem(subitem, depth + 1, index);
					}, this);
		}
	},

	computeX : function(radius, y) {
		var delta = -4 * (Math.pow((y - this.circleCenterY), 2) - Math.pow(radius, 2));
		if (delta <= 0) {
			throw "delta must be > 0";
		}
		var x = (2 * this.circleCenterX + (this.sideLeft ? -1 : 1) * Math.sqrt(delta)) / (2);
		return x;
	}

}
/** ************************************************************************** */
