magic.update =
	[{
		$BIRD: "Ruler",
		rulez: {
			tbl: {
				dir: {
					ttb: true,
					ltr: true
				},
				rows: null,
				cols: null,
				x: {},
				y: {}
			},
			spiral: {
				dir: true,
				rows: null,
				cols: null,
				x: {},
				y: {}
			}
		},
		rule: function (r) {
			var obj = {};
			if (isArray(r)) {
				for (var i = 0; i < r.length; i++)
					obj = Love(obj, this.rule(r[i]));
				return obj;
			}
			if (isString(r))
				r = this.rulez[r];

			//-----------------------------------

			return obj;
		},
		init: function () {
			var thisBox = this;
			var ani = this.ani;
			var set = this.set;

			this.ani = function (r) {
				ani(thisBox.rule(r));
				return thisBox;
			};
			this.set = function (r) {
				set(thisBox.rule(r));
				return thisBox;
			};
		}
	}, {
		$BIRD: "CSS3"
	}, {
		$BIRD: "Canvas",
		init: function () {
			this.cnv = this.gr.tag.getContext("2d");
			this.resized();
		},
		resized: function () {
			this.gr.set({
				width: this.width,
				height: this.height
			});
		},
		nodes: [{
				$PLUME: 'gr',
				$TAG: "canvas"
			}
		]
	}, {
		$BIRD: "Rune",
		$rune: [{
				$TEXT: 'hallo',
				def: 'Hallo <b>W</b>orlds!'
			}, {
				$COUNTER: 'counter',
				def: 0,
				min: 0,
				max: 10
			}, {
				$COUNTERANGE: 'counter',
				def: 0,
				min: 0,
				max: 10
			}, {
				$NUMBER: 'val',
				def: 1.0,
				min: 0,
				max: 10.234
			}, {
				$NUMBERANGE: 'val',
				def: 1.0,
				min: 0,
				max: 10.234
			}, {
				$COLOR: 'val',
				def: 0x202020,
				min: 0,
				max: 0xFFFFFF
			}, {
				$COLORANGE: 'val',
				def: 1.0,
				min: 0,
				max: 10.234
			}, {
				$ROLL: 'R1',
				stone: [],
				rune: []
			}, {
				$STONE: 'S1',
				stone: [],
				rune: []
			}, // if switch fork
			{
				$DELTA: 'D1',
				body: []
			}, // multiprocessing
			{
				$CALL: 'Math.abs',
				body: 'counter'
			}, // multiprocessing
			{}
		],
		pack: function () {
			return magic.runePack(this.$rune);
		},
		unpack: function (src) {
			this.$rune = magic.runeUnPack(src);
		},
		load: function (url) {
			magic.load(url, function (d) {
				if (isString(d.$RUNEPACK))
					this.$rune = this.unpack(d.$RUNEPACK);
				else
					this.$rune = d;
			});
		},
		save: function (url) {
			magic.save(url, this.pack(this.$rune));
		},
		$compile: function () {
			// return magic.runeCompile(this, this.$rune);
			var aliases = {};

			function $bjsonCompileRune(obj) {}
			function $bjsonCompileBox(obj) {}
			function $bjsonCompileData(obj) {}

			var src = this.$bjsonSrc;
			for (var i in src) {
				var v = src[i];
				if (isObject(v)) {
					if (isObject(v.$RUNE))
						$bjsonCompileRune(v.$RUNE);
					else if (isObject(v.$RVR))
						$bjsonCompileData(v.$RVR);
				}
			}
			return this;
		},
		init: function () {
			this.$compile();
		}
	}, {
		$BIRD: "SVG"
	}, {
		$BIRD: "PNGDraw"
	}, {
		$BIRD: "Flash"
	}, {
		$BIRD: "SilverLights"
	}, {
		$BIRD: "ACE"
	}, {
		$BIRD: "NicEdit"
	}, {
		$BIRD: "Fx",
		init: function () {
			var thisBox = this;
			thisBox.fx = {};
			thisBox.fx.fade = function (v, d) {
				if (!isNumber(d))
					d = 200;
				if (!isNumber(v))
					v = 1;
				thisBox.ani({
					alpha: v,
					delay: d
				});
				return thisBox;
			};

			thisBox.fx.fly = function (xs, ys, d) {
				if (!isNumber(d))
					d = 200;

				if (!isNumber(xs))
					xs = 0;
				if (!isNumber(ys))
					ys = 0;

				thisBox.ani({
					x: thisBox.x + xs,
					y: thisBox.y + ys,
					delay: d
				});
			};

			thisBox.fx.scale = function (v) {
				if (!isNumber(d))
					d = 200;

				if (!isNumber(v))
					v = 1;
				thisBox.ani({
					scale: v,
					delay: d
				});
				return thisBox;
			};

			thisBox.fx.scroll = function (xv, yv, d) {
				if (!isNumber(d))
					d = 200;

				if ((isNumber(xv)) && (isNumber(yv)))
					thisBox.ani({
						clip: {
							y: yv,
							x: xv
						},
						delay: d
					});
				else
					if ((isNumber(xv)) && (!isNumber(yv)))
						thisBox.ani({
							clip: {
								x: xv
							},
							delay: d
						});
					else
						if ((!isNumber(xv)) && (isNumber(yv)))
							thisBox.ani({
								clip: {
									y: yv
								},
								delay: d
							});

				return thisBox;
			};

			thisBox.fx.slide = function (wv, hv, d) {
				if (!isNumber(d))
					d = 200;

				var w = thisBox.clip.width;
				var h = thisBox.clip.height;

				if (isNumber(wv))
					w = wv;
				if (isNumber(hv))
					w = hv;

				if (typeof(wv) == "undefined")
					thisBox.$.collapseH = !thisBox.$.collapseH;
				else if (wv == null)
					thisBox.$.collapseH = !thisBox.$.collapseH;

				if (typeof(hv) == "undefined")
					thisBox.$.collapseV = !thisBox.$.collapseV;
				else if (hv == null)
					thisBox.$.collapseV = !thisBox.$.collapseV;

				if (!isNumber(wv))
					if (thisBox.$.collapseH)
						w = 0;

				if (!isNumber(hv))
					if (thisBox.$.collapseV)
						h = 0;

				thisBox.ani({
					clip: {
						height: h,
						width: w
					},
					delay: d
				});
				return thisBox;
			};

		}
	},

	// **********************************************
	// NAVIGATION
	// **********************************************
	// ~defaultContent
	{
		$BIRD: "DefaultContent",
		bg: null,
		width: 1000,
		height: 'auto',
		selectionColor: 0xDFB0F0,
		action: null,
		itemSchema: "Text",
		designSchema: "Default",
		nodes:
		[{
				$PLUME: "marker1",
				bg: {
					color: 0xF0F0F0
				},
				alpha: 0.5
			}, {
				$PLUME: "marker2",
				bg: {
					color: 0xF0F0F0
				},
				alpha: 0.5,
				height: 1
			}, {
				$PLUME: "subst",
				bg: {
					color: 0xF0F0F0
				}
			}, {
				$PLUME: "item",
				text: {
					data: "hallo!",
					size: 14,
					font: "Verdana",
					align: "left",
					color: 0x404040,
					weight: 'normal'
				},
				bg: null
			}
		],
		mouseOver: function () {
			this.item.ani({
				text: {
					color: 0xFFFFFF
				}
			});
			this.subst.set({
				bg: {
					color: this.selectionColor
				}
			});
			this.subst.ani({
				width: this.width
			});
		},
		mouseOut: function () {
			this.item.ani({
				text: {
					color: 0x404040
				}
			});
			this.subst.ani({
				width: 0
			});
		},
		mouseDown: function () {
			this.subst.set({
				bg: {
					color: this.selectionColor
				},
				width: this.width
			});
			if (isFunction(this.action))
				this.action();
			this.subst.set({
				bg: {
					color: this.selectionColor
				},
				width: this.width
			});
		},
		reDraw: function () {
			this.setRect();
		},
		updateDesign: function () {
			if (isFunction(this.selectionColor))
				this.selectionColor = this.selectionColor();
			this.marker1.ani({
				bg: {
					color: this.selectionColor
				}
			});
			this.marker2.ani({
				bg: {
					color: this.selectionColor
				}
			});
		},
		setRect: function (mw, mh) {
			if (!isNumber(mw))
				mw = this.item.width;
			if (!isNumber(mh))
				mh = this.item.height;

			var cp = this;
			while (cp != this.topParent) {
				mw -= cp.x;
				cp = cp.parent;
			}
			if (mw > 0) {
				if (isFunction(this.selectionColor))
					this.selectionColor = this.selectionColor();
				this.item.set({
					x: 8,
					width: mw - 8,
					height: mh,
					text: this.item.text,
					bg: null
				});
				this.marker1.set({
					width: 1,
					x: 0,
					height: mh,
					bg: {
						color: this.selectionColor
					}
				});
				this.marker2.set({
					x: 0,
					width: mw,
					height: 1,
					bg: {
						color: this.selectionColor
					}
				});
				this.subst.set({
					x: 0,
					width: mw,
					height: mh,
					bg: null
				});
				this.set({
					width: mw,
					height: mh
				});
			}
		}
	},

	// ~navigatorList
	{
		$BIRD: "NavigatorList",
		bg: null,
		widthLimit: 200,
		dataList: [],
		design: {
			color: function () {
				return magic.tools.randomColor(0x909090, 0xD0D0D0);
			}
		},
		setRect: function (mw) {
			for (var i = 0; i < this.nodes.length; i++)
				this.nodes[i].setRect(mw);
			var cp = this;
			while (cp != this.topParent) {
				mw -= cp.x;
				cp = cp.parent;
			}
			this.set({
				width: mw
			});
		},
		reDrawUpdate: function () {
			var me = this;
			var globalH = me.nodes[0].height;
			for (var i = 1; i < me.nodes.length; i++) {
				me.nodes[i].set({
					y: globalH
				});
				globalH += me.nodes[i].height;
			}
			me.set({
				height: globalH,
				clip: {
					width: me.width,
					height: globalH
				}
			});

			if (isBox(me.parent))
				if (isFunction(me.parent.reDrawUpdate))
					me.parent.reDrawUpdate();
		},
		reDraw: function () {
			var me = this;
			var maxWidth = 100;
			for (var i = 0; i < me.dataList.length; i++) {
				var prevY = 0;
				if (me.nodes.length > 0)
					prevY = me.nodes[me.nodes.length - 1].y + me.nodes[me.nodes.length - 1].height;

				var dataItem = me.dataList[i];
				if (!isObject(dataItem))
					break;
				if ((dataItem.nodes == null) || (dataItem.nodes.length == 0)) {
					var nn = null;
					if (typeof(dataItem.contentClass) == "string")
						nn = me.baby(dataItem.contentClass);
					else
						nn = me.baby("DefaultContent");
					nn.action = dataItem.action;
					nn.item.set({
						text: dataItem.text,
						width: 'auto',
						height: 'auto'
					});
					nn.reDraw();
					nn.set({
						x: 2,
						y: prevY + 1
					});
					if (nn.width > maxWidth)
						maxWidth = nn.width;
					me.set({
						height: prevY + 2 + nn.height,
						width: maxWidth
					});
				} else {
					var nn = me.baby("NavigatorTree");
					nn.dataTree = dataItem;
					nn.set({
						x: 1,
						y: prevY + 1
					});
					nn.reDraw();
					if (nn.width > maxWidth)
						maxWidth = nn.width;
					me.set({
						height: prevY + 2 + nn.height,
						width: maxWidth
					});
				}
			};
			this.setRect(maxWidth);
		},
		nodes: []
	},
	// tree
	{
		$BIRD: "NavigatorTree",
		bg: null,
		prevHeight: 0,
		listPrevHeight: 0,
		canCollapse: true,
		dataTree: {},
		collapsed: false,
		setRect: function (mw) {
			this.treeItem.setRect(mw, null, this.height);
			this.treeList.setRect(mw);
			var cp = this;
			while (cp != this.topParent) {
				mw -= cp.x;
				cp = cp.parent;
			}
			this.set({
				width: mw
			});
		},
		reDrawUpdate: function () {
			var me = this;
			//me.treeItem.setRect(me.width,me.treeList.y);
			me.treeList.set({
				clip: {
					width: me.treeList.width,
					height: me.treeList.height
				}
			});
			me.set({
				height: me.treeItem.height + me.treeList.height
			});
			me.marker.set({
				height: me.height,
				bg: {
					color: me.treeItem.selectionColor
				}
			});

			if (isBox(me.parent))
				if (isFunction(me.parent.reDrawUpdate))
					me.parent.reDrawUpdate();
		},
		collapse: function () {
			var me = this;
			this.treeList.ani({
				height: 0,
				clip: {
					width: this.treeList.width,
					height: 0
				},
				progress: function (b, p) {
					me.set({
						height: me.treeItem.height + me.treeList.clip.height
					});
					me.reDrawUpdate();
				}
			});
			me.collapsed = true;
		},
		uncollapse: function () {
			var me = this;
			me.treeList.ani({
				height: me.globalHeight - me.treeItem.height,
				clip: {
					width: me.treeList.width,
					height: me.globalHeight - me.treeItem.height
				},
				progress: function (b, p) {
					me.set({
						height: me.treeItem.height + me.treeList.clip.height
					});
					me.reDrawUpdate();
				}
			});
			me.collapsed = false;
		},
		toggle: function () {
			if (this.canCollapse)
				if (this.collapsed)
					this.uncollapse();
				else
					this.collapse();
		},
		reDraw: function () {
			var me = this;
			me.treeItem.action = me.dataTree.action;
			me.treeItem.item.set({
				text: me.dataTree.text,
				width: 'auto',
				height: 'auto'
			});
			me.treeItem.reDraw();
			if (typeof(me.dataTree.canCollapse) == "boolean")
				if (me.dataTree.canCollapse != null)
					me.canCollapse = me.dataTree.canCollapse;

			me.collapsed = me.dataTree.collapsed;
			if (me.dataTree.nodes != null)
				if (me.dataTree.nodes.length > 0) {
					me.treeList.dataList = me.dataTree.nodes;
					me.treeList.set({
						y: me.treeItem.height + 2
					});
					me.treeList.reDraw();
					if ((isNaN(me.height)) || (me.height == null) || (me.height == 'auto') || (me.height != me.height) || (me.height == 0))
						me.set({
							height: me.treeList.height + me.treeItem.height + 2,
							width: me.treeList.width + 40
						});
					else
						me.set({
							width: me.treeList.width + 40
						});
				}
			me.prevHeight = me.height;
			me.listPrevHeight = me.treeList.height;
			this.setRect(Math.max(me.treeList.width, me.treeItem.width) + 40);
			me.marker.set({
				height: me.height,
				bg: {
					color: me.treeItem.selectionColor
				}
			});
			me.globalHeight = me.height;
			me.treeItem.action = function () {
				me.toggle();
				if (isFunction(me.dataTree.action))
					me.dataTree.action();
			};
		},
		nodes: [{
				$INVITE: "treeItem",
				bind: "DefaultContent",
				x: 0,
				y: 0,
				bg: null
			}, {
				$INVITE: "treeList",
				bind: "NavigatorList",
				x: 6,
				y: 18,
				bg: null
			}, {
				$PLUME: "marker",
				x: 0,
				y: 0,
				width: 1
			}
		],
		init: function () {
			this.reDraw();
		}
	},
	// navigator
	{
		$BIRD: "Navigator",
		$LOVE: "Fx",
		contentData: {},
		designPalette: {},
		dataTree: {},
		autoCloseDelay: 200,
		reDraw: function () {
			this.treeN.dataTree = this.dataTree;
			this.treeN.set({
				bg: this.bg,
				x: 0,
				y: 0,
				width: this.width,
				height: this.height
			});
			this.treeN.reDraw();
		},
		close: function () {
			this.ani({
				x: 30 - this.width,
				postal: function (me) {
					me.parent.windows.arrange();
				}
			});
		},
		init: function () {
			this.reDraw();
		},
		mouseOut: function () {
			var me = this;
			this.fx.fade(0.9);
			me.autoClose = magic.wait(this.autoCloseDelay, function () {
					me.close();
				});
		},
		mouseOver: function () {
			if (isNumber(this.autoClose))
				clearInterval(this.autoClose);

			this.ani({
				x: 0,
				alpha: 1,
				postal: function (me) {
					me.parent.windows.arrange();
				}
			});
		},
		nodes:
		[{
				$INVITE: "treeN",
				bind: "NavigatorTree"
			}
		]
	},
	// ***********************************************************************
	// ICON
	// ***********************************************************************
	{
		$BIRD: "Icon",
		$LOVE: "Fx",
		x: 0,
		y: 0,
		width: 100,
		height: 100,
		bg: null,
		col: 0,
		row: 0,
		iconData: {
			text: "Hallo!",
			image: "star"
		},
		reDraw: function () {
			//CONTENTUPLOAD
			//this.layerImage.set({width:'auto', height:'auto', bg:{image:"img/icons/"+this.iconData.image+".png", repeat:"no-repeat"}});
			this.layerImage.set({
				width: 32,
				height: 32,
				bg: {
					image: "img/icons/" + this.iconData.image + ".png",
					repeat: "no-repeat"
				}
			});
			this.layerImage.set({
				x: (this.width - this.layerImage.width) / 2,
				y: (this.layerText.y - this.layerImage.height) / 2
			});

			this.layerText.set({
				text: {
					data: this.iconData.text
				}
			});
		},
		mouseDown: function () {
			this.dragStart();
		},
		doubleClick: function () {
			if (isFunction(this.action))
				this.action();
		},
		drag: function (e) {
			var xx = e.targetX;
			var yy = e.targetY;
			this.set({
				x: xx,
				y: yy
			});
			this.layerCover.fx.fade(0.6);
		},
		drop: function (e) {
			var xx = e.targetX;
			var yy = e.targetY;
			var gg = this.parent.gridSize;
			this.col = Math.round(xx / gg);
			this.row = Math.round(yy / gg);
			var gfe = {};

			if (!this.parent.gridIsEmptyCR(this.col, this.row)) {
				gfe = this.parent.gridFindNearestEmptyCR(this.col, this.row);
				this.col = gfe.col;
				this.row = gfe.row;
			}

			xx = this.col * gg;
			yy = this.row * gg;
			this.ani({
				x: xx,
				y: yy
			});
			this.layerCover.fx.fade(0.1);
		},
		nodes:
		[
			//{id:'layerSubstrate', schema:'plume', x:10, y:0, width:80, height:80, alpha:0.01, bg:{color:0x202020}},

			{
				$PLUME: 'layerImage',
				x: 10,
				y: 0,
				width: 80,
				height: 80,
				alpha: 0.8,
				contentUpload: function () {
					this.parent.reDraw();
				}
			}, {
				$PLUME: 'layerText',
				x: 0,
				y: 82,
				width: 100,
				height: 'auto',
				text: {
					data: 'hallo',
					align: 'center',
					color: 0x202020,
					font: "Verdana",
					size: 12
				}
			}, {
				$PLUME: 'layerCover',
				x: 0,
				y: 0,
				width: 98,
				height: 98,
				bg: null,
				border: {
					color: 0x202020,
					size: 1
				},
				alpha: 0,
				mouseOver: function () {
					this.fx.fade(0.6);
				},
				mouseOut: function () {
					this.fx.fade(0);
				}
			}
		]
	},
	// ***********************************************************************
	// ICONSET
	// ***********************************************************************
	{
		$BIRD: "Iconset",
		x: 0,
		y: 0,
		width: '100%',
		height: '100%',
		bg: null,
		gridSize: 100,
		iconData: [{
				text: 'Demo',
				image: "star",
				col: 2,
				row: 2,
				action: function () {
					var win = desktop.windows.newWindow({
							x: 450,
							y: 450,
							width: 550,
							height: 250
						});
					win.winarea.content.set({
						text: {
							data: "GOODAY (-:<br><ul><li>hallo<li>worlds!<li>how are You?</ul>",
							color: 0x203028,
							size: 12,
							font: "Verdana"
						}
					});
				}
			}, {
				text: 'Warning!',
				image: "thumbs-down",
				col: 3,
				row: 3,
				action: function () {
					var win = desktop.windows.newWindow({
							x: 250,
							y: 250,
							width: 350,
							height: 550
						});
					win.winarea.content.load("data/warning.json", "doc.warning");
				}
			}
		],
		gridIsEmptyCR: function (col, row) {
			for (var i = 0; i < this.nodes.length; i++)
				if ((this.nodes.col == col) && (this.nodes.row == row))
					return false;
			return true;
		},
		gridFindNearestEmptyCR: function (col, row) {
			var empty = false;
			while (!empty) {
				row++;
				empty = gridIsEmptyCR(col, row);
			}
			return {
				col: col,
				row: row
			};
		},
		settings: {
			icon: {
				height: 100,
				width: 100
			},
			style: 'Jump'
		},
		animate: function (ico) {
			this['ani' + this.settings.style](ico);
		},
		aniNone: function (ico) {},
		aniJump: function (ico) {
			ico.ani([{
						y: ico.y - 30,
						delay: 50
					}, {
						y: ico.y + 20,
						delay: 200
					}, {
						y: ico.y - 10,
						delay: 50
					}, {
						y: ico.y + 20,
						delay: 100
					}
				]);
		},
		newIcon: function (idata) {
			var icon = this.baby("Icon", this.settings.icon);
			icon.iconData = idata;
			if (isFunction(idata.action))
				icon.action = idata.action;
			icon.reDraw();
			icon.set({
				x: idata.col * 110,
				y: idata.row * 110
			});
		},
		nodes:
		[
		],
		init: function () {
			for (var i = 0; i < this.iconData.length; i++)
				this.newIcon(this.iconData[i]);
		}
	},
	// **********************************************
	// HTMLViewer
	// **********************************************
	{
		$BIRD: "Content",
		loadContent: function (url) {
			magic.load(url, function (d) {
				this.tag.innerHTML = src;
			});
		},
		setContent: function (src) {
			this.tag.innerHTML = src;
		}
	}, {
		$BIRD: "HTMLViewer",
		$LOVE: "Content"
	}, {
		$BIRD: "ScrollContent",
		contentClass: "HTMLViewer",
		scroller: {
			weight: 20,
			border: {
				size: 1,
				color: 0x40B0FF
			},
			bg: {
				color: 0x3090F0
			},
			up: {},
			carret: {
				width: 16,
				height: 16,
				x: 2,
				y: 2,
				bg: {
					color: 0x50BBFF
				},
				shadow: {
					size: 1
				}
			}
		},
		reDraw: function () {
			var hScroller = false,
			vScroller = false;
			this.content.set({
				width: this.width,
				height: 'auto'
			});
			if (this.content.width != this.width)
				hScroller = true;

			this.content.set({
				clip: {
					x: 0,
					y: 0,
					width: this.width,
					height: this.height
				}
			});
			if (this.content.height != this.height)
				vScroller = true;

			if (hScroller) // draw HScroll
			{
				var tail1 = 0;
				if (vScroller)
					tail1 = this.scrollerWeight;

				this.hScroller.set(this.scroller);
				this.hScroller.set({
					visible: true,
					x: 0,
					y: this.height - this.scroller.weight,
					height: this.scroller.weight,
					width: this.width - tail1
				});
				this.hScroller.reDraw();
			} else
				this.hScroller.set({
					visible: false
				});

			if (vScroller) // draw VScroll
			{
				var tail2 = 0;
				if (hScroller)
					tail2 = this.scrollerWeight;

				this.vScroller.set(this.scroller);
				this.vScroller.set({
					visible: true,
					x: this.width - this.scroller.weight,
					y: this.caption.height,
					height: this.height - this.caption.height - tail2,
					width: this.scroller.weight
				});
				this.vScroller.reDraw();
			} else
				this.vScroller.set({
					visible: false
				});
		},
		init: function () {
			this.content.Love(this.contentClass);
			this.reDraw();
		},
		nodes: [{
				$PLUME: "content"
			}, {
				$PLUME: "vScroller",
				nodes: [{
						$PLUME: "up"
					}, {
						$PLUME: "down"
					}, {
						$PLUME: "carret"
					}
				]
			}, {
				$PLUME: "hScroller",
				nodes: [{
						$PLUME: "left"
					}, {
						$PLUME: "right"
					}, {
						$PLUME: "carret"
					}
				]
			}
		]
	},
	// **********************************************
	// WINDOW
	// **********************************************
	{
		$BIRD: "Window",
		dataTree: {},
		alpha: 0,
		status: "normal",
		bg: null,
		activate: function () {
			with (this) {

				var currentID = -1;
				parent.activeWindow = this;

				for (var i = 0; i < parent.nodes.length; i++) {
					if (parent.nodes[i] == this) {
						currentID = i;
						ani({
							alpha: 1,
							delay: 50
						});
					} else
						parent.nodes[i].ani({
							alpha: 0.5
						});
				}

				if ((parent.nodes.length > 1) && (currentID != -1)) {
					parent.tag.removeChild(tag);
					parent.tag.appendChild(tag);
				}

			}
		},
		close: function () {
			this.status = ">>void";
			this.parent.closeWindow(this);
		},
		maximize: function () {
			var nrect = {
				x: desktop.navigator.width,
				y: 0,
				width: desktop.width - desktop.navigator.width,
				height: desktop.height,
				alpha: 1,
				progress: function (b, p) {
					b.reDraw();
				},
				postal: function (b) {
					b.status = "max";
				}
			};
			if (this.status == "normal") {
				this.status = "normal>>max";
				this.normalRect = {
					x: this.x,
					y: this.y,
					width: this.width,
					height: this.height
				};
				this.ani(nrect);
			} else if (this.status == "min") {
				this.status = "min>>max";
				this.ani(nrect);
			}
		},
		normalize: function () {
			var thisBox = this;
			this.status = ">>normal";
			this.normalRect.alpha = 0.5;
			this.normalRect.progress = function (b, p) {
				if (p >= 1)
					b.status = "normal";
				b.reDraw();
			};
			this.normalRect.postal = function (b) {
				b.status = "normal";
			};
			this.ani(this.normalRect);
			wait(200, function () {
				thisBox.status = "normal";
			});
		},
		minimize: function () {
			if (this.status == "normal") {
				this.status = "normal>>min";
				this.normalRect = {
					x: this.x,
					y: this.y,
					width: this.width,
					height: this.height
				};
				this.ani({
					x: desktop.width,
					y: 0,
					width: 50,
					height: 50,
					alpha: 0,
					progress: function (b, p) {
						b.reDraw();
					},
					postal: function (b) {
						b.status = "min";
						b.set({
							x: desktop.width,
							alpha: 0
						});
					}
				});
			} else if (this.status == "max") {
				this.status = "max>>min";
				this.ani({
					x: desktop.width,
					y: 0,
					width: 50,
					height: 50,
					alpha: 0,
					progress: function (b, p) {
						b.reDraw();
					},
					postal: function (b) {
						b.status = "min";
						b.set({
							x: desktop.width,
							alpha: 0
						});
					}
				});
			}
			if (isBox(desktop))
				if (isBox(desktop.trayNavigator))
					if (isBox(desktop.trayNavigator.tray))
						desktop.trayNavigator.tray.push(this);
		},
		deactivate: function () {
			this.ani({
				alpha: 0.5
			});
		},
		reDraw: function () {
			this.tag.style.overflow = "";
			this.tag.style.border = "";
			this.tag.style.zoom = null;

			var rect = {
				width: this.width,
				height: this.height
			};
			this.winarea.set({
				width: rect.width,
				height: rect.height
			});
			//this.winarea.set({clip:{x:0, y:0, width:this.width, height:this.height}});
			this.winarea.caption.set({
				text: this.text,
				width: rect.width,
				shadow: {
					size: 2
				}
			});
			this.winarea.scrollContent.set({
				x: 0,
				y: this.winarea.caption.height,
				width: rect.width,
				height: rect.height - this.winarea.caption.height
			});
			this.winarea.btnClose.set({
				x: rect.width - 20,
				width: 18,
				height: 18
			});
			this.winarea.btnMax.set({
				x: rect.width - 40,
				width: 18,
				height: 18
			});
			this.winarea.btnMin.set({
				x: rect.width - 60,
				width: 18,
				height: 18
			});

			this.resizerL.set({
				x: -4,
				y: 0,
				width: 8,
				height: rect.height
			});
			this.resizerR.set({
				x: rect.width - 4,
				y: 0,
				width: 8,
				height: rect.height
			});
			this.resizerT.set({
				y: -4,
				x: 0,
				height: 8,
				width: rect.width
			});
			this.resizerB.set({
				y: rect.height - 4,
				x: 0,
				height: 8,
				width: rect.width
			});

		},
		reSize: function (rect) {
			this.set(rect);
			this.reDraw();
		},
		move: function (nx, ny) {
			this.set({
				x: nx,
				y: ny
			});
		},
		setContent: function(ctx)
		{
			this.winarea.scrollContent.content.setContent(ctx);
		},
		drag: function (e) {
			this.set({
				x: e.targetX,
				y: e.targetY
			});
		},
		init: function () {
			this.tag.style.overflow = "";
			this.tag.style.width = null;
			this.tag.style.height = null;
			this.tag.style.border = "";
			this.tag.style.zoom = null;

			var randomColor = magic.tools.randomColor(0x0070E0, 0x20A0F0);
			this.ani({
				alpha: 1,
				delay: 50
			});
			this.winarea.set({
				bg: {
					color: randomColor
				}
			});
			this.reDraw();
		},
		mouseOver: function () {
			if (this.status.indexOf(">>") == -1)
				this.activate();
		},
		nodes:
		[{
				$PLUME: "winarea",
				bg: {
					color: 0x20B0FF
				},
				width: 300,
				height: 300,
				shadow: {
					size: 1
				},
				border: {
					size: 1,
					color: 0x20B0FF
				},
				normalRect: {
					x: 0,
					y: 0,
					width: 20,
					heigth: 20
				},
				nodes: [{
						$PLUME: "caption",
						x: 2,
						y: 2,
						width: 'auto',
						height: 20,
						bg: null,
						text: {
							color: 0xF0F0F0,
							data: "Window",
							font: "Verdana",
							size: 12
						},
						mouseOver: function () {
							document.body.style.cursor = "move";
						},
						mouseOut: function () {
							document.body.style.cursor = "auto";
						},
						mouseDown: function () {
							this.parent.parent.dragStart();
						},
						doubleClick: function () {
							if (this.parent.parent.status == "max")
								this.parent.parent.normalize();
							else
								this.parent.parent.maximize();
						}
					}, {
						$PLUME: "btnMin",
						y: 2,
						width: 18,
						height: 18,
						bg: {
							image: "img/buttons/minimize_unfocused.png"
						},
						mouseOver: function () {
							this.set({
								bg: {
									image: "img/buttons/minimize.png"
								}
							});
						},
						mouseOut: function () {
							this.set({
								bg: {
									image: "img/buttons/minimize_unfocused.png"
								}
							});
						},
						mouseDown: function () {
							if (this.parent.parent.status == "min")
								this.parent.parent.normalize();
							else
								this.parent.parent.minimize();
						}
					}, {
						$PLUME: "btnMax",
						y: 2,
						width: 18,
						height: 18,
						bg: {
							image: "img/buttons/maximize_unfocused.png"
						},
						mouseOver: function () {
							this.set({
								bg: {
									image: "img/buttons/maximize.png"
								}
							});
						},
						mouseOut: function () {
							this.set({
								bg: {
									image: "img/buttons/maximize_unfocused.png"
								}
							});
						},
						mouseDown: function () {
							if (this.parent.parent.status == "max")
								this.parent.parent.normalize();
							else
								this.parent.parent.maximize();
						}
					}, {
						$PLUME: "btnClose",
						y: 2,
						width: 18,
						height: 18,
						bg: {
							image: "img/buttons/close_unfocused.png"
						},
						mouseOver: function () {
							this.set({
								bg: {
									image: "img/buttons/close.png"
								}
							});
						},
						mouseOut: function () {
							this.set({
								bg: {
									image: "img/buttons/close_unfocused.png"
								}
							});
						},
						mouseDown: function () {
							this.parent.parent.close();
						}
					}, {
						$PLUME: "scrollContent",
						x: 1,
						y: 14,
						width: 300,
						height: 300,
						bg: {
							color: 0xF0F0F0
						},
						$LOVE: "ScrollContent",
						text: {
							color: 0x606060,
							data: "hallo worlds! \n hallo! \n hallo...",
							font: "Verdana",
							size: 12
						},
						changing: function () {
							return true;
						},
						mouseDown: function () {
							this.tag.focus();
						},
						mouseOver: function () {
							this.tag.focus();
						}
					}

				]
			}, // PLUME:window

			{
				$PLUME: "resizerL",
				alpha: 0,
				bg: {
					color: 0x902020
				},
				mouseOver: function () {
					document.body.style.cursor = "ew-resize";
				},
				mouseOut: function () {
					document.body.style.cursor = "auto";
				},
				mouseDown: function () {
					this.parent.prevSize = {
						x: this.parent.x,
						y: this.parent.y,
						width: this.parent.winarea.width,
						height: this.parent.winarea.height
					};
					this.dragStart();
				},
				drag: function (e) {
					var nr = copy(this.parent.prevSize);
					nr.x += e.shiftX;
					nr.width -= e.shiftX;
					this.parent.reSize(nr);
				}
			}, {
				$PLUME: "resizerR",
				alpha: 0,
				bg: {
					color: 0x902020
				},
				mouseOver: function () {
					document.body.style.cursor = "ew-resize";
				},
				mouseOut: function () {
					document.body.style.cursor = "auto";
				},
				mouseDown: function () {
					this.parent.prevSize = {
						x: this.parent.x,
						y: this.parent.y,
						width: this.parent.winarea.width,
						height: this.parent.winarea.height
					};
					this.dragStart();
				},
				drag: function (e) {
					var nr = copy(this.parent.prevSize);
					nr.width += e.shiftX;
					this.parent.reSize(nr);
				}
			}, {
				$PLUME: "resizerT",
				alpha: 0,
				bg: {
					color: 0x902020
				},
				mouseOver: function () {
					document.body.style.cursor = "ns-resize";
				},
				mouseOut: function () {
					document.body.style.cursor = "auto";
				},
				mouseDown: function () {
					this.parent.prevSize = {
						x: this.parent.x,
						y: this.parent.y,
						width: this.parent.winarea.width,
						height: this.parent.winarea.height
					};
					this.dragStart();
				},
				drag: function (e) {
					var nr = copy(this.parent.prevSize);
					nr.y += e.shiftY;
					nr.height -= e.shiftY;
					this.parent.reSize(nr);
				}
			}, {
				$PLUME: "resizerB",
				alpha: 0,
				bg: {
					color: 0x902020
				},
				mouseOver: function () {
					document.body.style.cursor = "ns-resize";
				},
				mouseOut: function () {
					document.body.style.cursor = "auto";
				},
				mouseDown: function () {
					this.parent.prevSize = {
						x: this.parent.x,
						y: this.parent.y,
						width: this.parent.winarea.width,
						height: this.parent.winarea.height
					};
					this.dragStart();
				},
				drag: function (e) {
					var nr = copy(this.parent.prevSize);
					nr.height += e.shiftY;
					this.parent.reSize(nr);
				}
			}
		]

	},
	// ***********************************************************************
	// WINDOWS TRAY
	// ***********************************************************************
	{
		$BIRD: "TrayItem",
		bg: {
			color: 0x60D0FF
		},
		text: {
			data: "",
			color: 0x909090,
			font: "Verdana",
			size: 12
		},
		alpha: 0.8,
		x: 0,
		y: 0,
		height: 20,
		width: 100,
		window: null,
		tray: null,
		mouseOver: function () {
			this.ani({
				alpha: 1
			});
		},
		mouseOut: function () {
			this.ani({
				alpha: 0.5
			});
		},
		mouseDown: function () {
			this.tray.remove(this);
		}
	}, {
		$BIRD: "Tray",
		width: 300,
		height: '100%',
		bg: null,
		itemMargin: 2,
		push: function (win) {
			var node = this.baby("TrayItem");
			node.window = win;
			node.tray = this;
			node.set({
				text: win.winarea.caption.text,
				bg: win.winarea.bg
			});
			node.set({
				x: 1,
				width: this.width,
				height: 20
			});
			this.arrange();
		},
		remove: function (node) {
			node.window.normalize();
			this.free(node);
			this.arrange();
		},
		arrange: function () {
			if (this.nodes.length > 0)
				this.nodes[0].set({
					y: 0
				});
			// >(8:((
			for (var i = 1; i < this.nodes.length; i++)
				this.nodes[i].set({
					y: this.nodes[i - 1].y + this.nodes[i - 1].height + this.itemMargin
				});
		}
	},

	// ***********************************************************************
	// WINDOWS
	// ***********************************************************************
	{
		$BIRD: "Windows",
		activeWindow: null, // active context
		animations: {
			winAppear: {
				dropDown: function (win) {
					var targetHeight = win.winarea.height;
					var targetY = win.y;

					win.set({
						y: targetY + targetHeight / 2,
						height: 0,
						alpha: 1
					});
					win.ani({
						y: targetY,
						height: targetHeight
					});

					// TODO: new animodel, add sub nodes!
					// win.set({y:targetY+targetHeight/2, height:0, alpha:1, content:{height:0}});
					// win.ani({y:targetY, height:targetHeight, content:{height:targetHeight-win.caption.height}});

					//win.reDraw();
					//win.ani({y:targetY,height:targetHeight,progress:function(){win.reDraw();}});
				},
				dropRight: function (win) {
					var targetWidth = win.width;
					win.winarea.set({
						width: 0,
						alpha: 1
					});
					win.winarea.ani({
						width: targetWidth
					});
				},
				fly: function (win) {
					var targetY = win.y;
					win.set({
						y: targetY - 300,
						alpha: 0
					});
					win.ani({
						y: targetY,
						alpha: 1
					});
				}
			}
		},
		refit: function () {
			if (this.nodes == null)
				return;
			if (this.nodes.length == 0)
				return;
			var dwidth = this.parent.width;
			var dheight = this.parent.height;
			var margin = dwidth / 40;
			var bigRectLeft = this.parent.navigator.width + this.parent.navigator.x;
			var bigRectRight = this.parent.trayNavigator.x;
			var bigRectW = bigRectRight - bigRectLeft - (margin * 2);
			var bigRectH = dheight - margin * 2;
		},
		behaviour: "intuition",
		behaviourInterval: null,
		behaviourUpdate: function (obj) {
			var thisObj = this;
			this.behavourInterval = wait(obj.delay, function () {
					thisObj.behaviour = obj.target;
					thisObj[obj.func]();
					thisObj.arrange();
				});
		},
		context: [],
		updateContext: function () {
			if (this.context.length > 0) {
				if (this.context[this.context.length - 1] != this.activeWindow)
					this.context.push(this.activeWindow);
			} else
				this.context.push(this.activeWindow);
			while (this.context.length > 10)
				this.context.shift();
		},
		arrange: function () {
			with (this) {
				updateContext();
				switch (behaviour) {
				case "demo":
					break;
				case "intuition":
					behaviourUpdate({
						target: "intuition:cascade",
						func: "cascade",
						delay: 4000
					});
					behaviourUpdate({
						target: "demo",
						func: "demo",
						delay: 60000
					});
					break;
				case "intuition:cascade":
					break;
				case "cascade":
					this.cascade();
					break;
				case "intuition:tile":
					break;
				case "tile":
					break;
				case "intuition:highlight":
					break;
				case "highlight":
					break;
				case "intuition:ravens":
					break;
				case "ravens":
					break;
				case "intuition:flock":
					break;
				case "flock":
					break;
				case "intuition:rockStar":
					break;
				case "rockStar":
					break;
				}
			}
		},
		demo: function () {},
		cascade: function () {
			if (this.nodes == null)
				return;
			if (this.nodes.length == 0)
				return;
			var dwidth = this.parent.width;
			var dheight = this.parent.height;
			var margin = dwidth / 40;
			var bigRectLeft = this.parent.navigator.width + this.parent.navigator.x;
			var bigRectRight = this.parent.trayNavigator.x;
			var bigRectW = bigRectRight - bigRectLeft - (margin * 2);
			var bigRectH = dheight - margin * 2;
			var shiftX = bigRectW;
			if (this.nodes.length > 1)
				shiftX = (bigRectW - bigRectW / Math.pow(this.nodes.length, 0.5)) / (this.nodes.length - 1);
			var shiftY = bigRectH;
			if (this.nodes.length > 1)
				shiftY = (bigRectH - bigRectH / Math.pow(this.nodes.length, 0.5)) / (this.nodes.length - 1);

			for (var i = 0; i < this.nodes.length; i++)
				if (this.nodes[i].status.indexOf("min") == -1) {
					//var randomColor = magic.tools.randomColor(0x909090, 0xF0F0F0);
					var randomColor = this.nodes[i].bg.color;
					this.nodes[i].ani({
						x: bigRectLeft + margin + i * shiftX,
						y: margin + i * shiftY,
						width: bigRectW / Math.pow(this.nodes.length, 0.5),
						height: bigRectH / Math.pow(this.nodes.length, 0.5),
						bg: {
							color: randomColor
						},
						progress: function (b, p) {
							b.reDraw();
							b.status = "normal";
						}
					});
				}
		},
		newWindow: function (rect, aniModel) {
			var win = desktop.windows.baby("Window");
			win.activate();
			win.reSize(rect);
			if (isString(aniModel))
				this.animations.winAppear[aniModel](win);
			else
				this.animations.winAppear.dropDown(win);
			return win;
		},
		closeWindow: function (win) {
			if (win.status.indexOf("min") != -1)
				return;

			var desk = this;
			win.status = ">>void";
			win.ani({
				x: win.x + 400,
				alpha: 0,
				postal: function (w) {
					desk.free(w);
					if (desk.nodes.length > 0)
						desk.nodes[0].activate();
				}
			})
		},
		closeAllWindows: function () {
			for (var i = this.nodes.length - 1; i >= 0; i--) {
				var win = this.nodes[i];
				if (win.status.indexOf("min") == -1)
					win.ani({
						x: win.x + 400,
						alpha: 0,
						postal: function (w) {
							w.parent.free(w);
						}
					})
			}
		},
		intuitionCascade: function () {
			this.behaviour = "intuition:cascade";
		},
		init: function () {
			for (var i = 0; i < this.nodes.length; i++)
				this.nodes[i].activate();
			this.tag.style.overflow = "";
			this.tag.style.width = null;
			this.tag.style.height = null;
			this.tag.style.border = "";
			this.tag.style.zoom = null;
			//this.arrange();
		},
		nodes: [{
				$INVITE: "win1",
				bind: "Window",
				x: 30,
				y: 30,
				width: 200,
				height: 300,
				text: {
					data: "HALLO!",
					color: 0xFFFFFF,
					size: 12,
					font: "Verdana"
				}
			}, {
				$INVITE: "win2",
				bind: "Window",
				x: 30,
				y: 30,
				width: 200,
				height: 300,
				text: {
					data: "HI!",
					color: 0xFFFFFF,
					size: 12,
					font: "Verdana"
				}
			}, {
				$INVITE: "win3",
				bind: "Window",
				x: 30,
				y: 30,
				width: 200,
				height: 300,
				text: {
					data: "ÏÐÈÂÅÒÈÊÈ!",
					color: 0xFFFFFF,
					size: 12,
					font: "Verdana"
				}
			}, {
				$INVITE: "win4",
				bind: "Window",
				x: 30,
				y: 30,
				width: 200,
				height: 300,
				text: {
					data: "ÏÐÛÂßÒÀÍÍÅ!",
					color: 0xFFFFFF,
					size: 12,
					font: "Verdana"
				}
			}
		]
	},
	// **********************************************
	// BIRDESK
	// **********************************************
	{
		$BIRD: "Desktop",
		width: '100%',
		height: '100%',
		mouseMove: function () {
			this.mouse = this.event.mouse;
		},
		browserResize: function () {
			this.set({
				width: '100%',
				height: '100%'
			});
			this.trayNavigator.reDraw();
			this.windows.arrange();
		},
		debugWindow: null,
		init: function () {
			mg.debug.trap = function () {
				var txt = "";
				for (var i = 0; i < mg.debug.errors.length; i++) {
					var e = mg.debug.errors[i];
					txt = txt + "<br>" +
						"<span style='color:#202020'>" + e.obj +
						"</span><span style='color:#FF9090'>" + e.msg +
						"</span><span style='color:#9050FF'>" + e.path + "</span>";
				};
				if (!isBox(desktop.debugWindow))
					desktop.debugWindow = desktop.windows.newWindow({
							x: 300,
							y: 200,
							width: 300,
							height: 500
						});

				desktop.debugWindow.setContent(txt);
			}
		},
		nodes:
		[{
				$INVITE: "icons",
				bind: "Iconset",
				x: 0,
				y: 0,
				bg: null,
				iconsList: []
			}, {
				$INVITE: "windows",
				bind: "Windows",
				x: 0,
				y: 0,
				bg: null,
				dataList: []
			}, {
				$PLUME: "trayNavigator",
				x: 0,
				y: 0,
				width: 300,
				height: '100%',
				bg: {
					color: 0xFFFFFF
				},
				alpha: 0.9,
				shadow: {
					size: 1
				},
				border: {
					size: 1,
					color: 0x606060
				},
				mouseOver: function () {
					this.ani({
						x: this.parent.width - 300,
						postal: function (b) {
							b.parent.windows.arrange();
						}
					});
				},
				mouseOut: function () {
					this.ani({
						x: this.parent.width - 30,
						postal: function (b) {
							b.parent.windows.arrange();
						}
					});
				},
				reDraw: function () {
					this.set({
						x: this.parent.width - 30
					})
				},
				init: function () {
					this.reDraw();
				},
				nodes: [{
						$INVITE: "tray",
						bind: "Tray",
						x: 2,
						y: 20,
						width: 300
					}
				]
			}, {
				$INVITE: "navigator",
				bind: "Navigator",
				x: 0,
				y: 0,
				width: 200,
				height: '100%',
				shadow: {
					size: 1
				},
				style: "autocollapse accordion",
				alpha: 0.9,
				dataTree: {},
				bg: {
					color: 0xE3F2F4
				},
				border: {
					size: 1,
					color: 0xFFFFFF
				}
			}

		]
	}
];
