
var MotionGrid = new Class({
	
	BASE_TITLE : "VZDN",
	
	UNIT_SIZE  : 181,
	MARGIN     : 9,
	PADDING    : 0,
	MIN_WIDTH  : 980,
	MIN_HEIGHT : 600,
	
	SIDE_PADDING : 15,
	
	
	masterNode      : null,
	headerNode      : null,
	resizeTimer     : 0,
	scrollTimer     : 0,
	fontSizeTimer   : 0,
	masterWidth     : 0,
	masterHeight    : 0,
	isInited        : false,
	isRunnning      : false,
	fontSizeBuffer  : "",
	gridNodes       : new Array(),
	boxNode         : new Array(),
	props           : new Array(),
	slideBoxes      : new Array(),
	faceBoxes       : new Array(),
	motionBoxTimers : new Array(),
	motionBoxFxs    : new Array(),
	overlay         : null,
	detailView      : null,
	isMotionLocked  : false,
	
	
	
	//----------------------------------------------------------------------------------------------------
	//initialize
	
	initialize : function() {
		var i;
		var len;
		var nodes;
		var self = this;
		
		document.body.style.visibility = "hidden";
		document.body.style.overflow = "hidden";
		
		$(document.body).addClass("use-grid");
		if(!$vzdn.isPC) {
			$(document.body).removeClass("pc");
		}
		
		
		this.masterNode = document.getElementById("content");
		this.headerNode = document.getElementById("head");
		
		SWFAddress.addEventListener(SWFAddressEvent.CHANGE, function(evt){ self.onChangeAddress(evt.path) });
		
		
		
		nodes = this.masterNode.childNodes;
		len = nodes.length;
		
		for(i=0; i<len; i++) {
			var node = nodes[i];
			if(node.nodeType == 1 && node.className.match("box")) {
				this.boxNode.push(node);
				node.style.margin = "0";
				node.style.position = "absolute";
			}
		}
		
		this.boxNode = this.shuffleArray(this.boxNode);
		
		len = this.boxNode.length;
		for(i=0; i<len; i++) {
			var box = this.boxNode[i];
			this.gridNodes.push(box);
			
			var cname = this.boxNode[i].className;
			if(cname.match("works")) {
				this.slideBoxes.push(this.boxNode[i]);
				
				var a = box.getElementsByTagName("a")[0];
				a.href = "javascript:void(0);";
				a.onclick = function() {
					self.onclickBox(this);
				}
				//box.ontouchend = box.onclick;
			}
			else if(cname.match("staff")) {
				this.faceBoxes.push(this.boxNode[i]);
			}
			
			
				
			/*
			if($vzdn.isIOS) {
				box.ontouchstart = function(e) {
					window.isMoving = false;
					self.toggleOverlaySpec(this, true);
				}
				
				box.ontouchend = function(e) {
					self.toggleOverlaySpec(this, false);
					if(!window.isMoving) {
						self.onclickBox(this);
					}
				}
				
				window.ontouchmove = function() {
					window.isMoving = true;
				}
			}
			else {
				box.onmouseover = function() {
					self.toggleOverlaySpec(this, true);
				}
				box.onmouseout = function() {
					self.toggleOverlaySpec(this, false);
				}
				box.onclick = function() {
					self.onclickBox(this);
				}
			}
			*/
		}
		
		
		//this.setPosition();
		//this.fitToGrid();
		
		window.onresize = function() {
			self.resizeHandler();
		}
		
		window.onscroll = function() {
			self.scrollHandler();
		}
		
		this.setFontSizeListener();
		
		this.startBoxMotion();
	},
	
	
	
	//----------------------------------------------------------------------------------------------------

	startBoxMotion : function() {
		this.motionBoxTimers = new Array();
		this.motionBoxFxs = new Array();
		
		if(this.slideBoxes.length > 0) {
			this.startSlideBoxes();
		}
		
		if(this.faceBoxes.length > 0) {
			this.startFaceBoxes();
		}
	},
	
	
	replayBoxMotion : function() {
		this.motionBoxTimers = new Array();
		this.motionBoxFxs = new Array();
		
		if(this.slideBoxes.length > 0) {
			this.replaySlideBoxes();
		}
		
		if(this.faceBoxes.length > 0) {
			this.replayFaceBoxes();
		}
	},
	
	
	
	
	
	
	toggleOverlaySpec : function(elem, visibility) {
	},
	
	onclickBox : function(elem) {
		var rel = elem.rel;
		var length = Number( rel.replace(/^.*length:(.*?),.*$/, "$1") );
		var dir = rel.replace(/^.*dir:(.*?),.*$/, "$1");
		var site = rel.replace(/^.*site:(.*?),.*$/, "$1");
		
		this.showDetailOverlay(dir, length, site);
	},
	
	
	
	showDetailOverlay : function(dir, length, site) {
		var self = this;
		
		if(this.overlay && this.overlay.parentNode) {
			return;
		}
		
		this.stopAllMotionBoxes();
		this.isMotionLocked = true;
		
		this.overlay = document.createElement("div");
		this.overlay.id = "detail-overlay";
		
		var bg = document.createElement("div");
		bg.className = "bg";
		this.overlay.appendChild(bg);
		
		//$(this.overlay).set("opacity", 0);
		
		document.body.appendChild(this.overlay);
		
		
		var scrollHeight = $(document.body).getScrollSize().y;
		this.overlay.style.height = scrollHeight + "px";
		
		/*
		var fx = new Fx.Morph(this.overlay, {duration: 200, transition: Fx.Transitions.linear, onComplete: callback});
		fx.start({
			"opacity" : 1
		});
		*/
		callback();
		
		
		function callback() {
			self.createWorksDetailView(dir, length, site);
		}
	},
	
	
	
	createWorksDetailView : function(dir, length, site) {
		var self = this;
		
		this.detailView = document.createElement("div");
		this.detailView.id = "detail-view";
		this.overlay.appendChild(this.detailView);
		
		var worksWrap = document.createElement("div");
		worksWrap.id = "works-wrap";
		this.setAttributeVZDN(worksWrap, "total", length);
		this.setAttributeVZDN(worksWrap, "current", "1");
		this.setAttributeVZDN(worksWrap, "dir", dir);
		
		
		this.detailView.appendChild(worksWrap);
		
		var head = document.createElement("h2");
		this.detailView.appendChild(head);
		
		var btn = document.createElement("a");
		btn.className = "close";
		btn.href = "javascript:void(0);";
		this.detailView.appendChild(btn);
		
		var ttl = new Image();
		ttl.className = "works-title";
		ttl.src = "/asset/works/" + dir + "/title.png";
		this.detailView.appendChild(ttl);
		
		if(site) {
			var launch = document.createElement("a");
			launch.className = "launch";
			launch.href = site;
			launch.target = "_blank";
			this.detailView.appendChild(launch);
		}
		
		var inav = document.createElement("ul");
		for(var i=0; i<length; i++) {
			var li = document.createElement("li");
			var a = document.createElement("a");
			a.innerHTML = (i + 1);
			a.href = "javascript:void(0);";
			this.setAttributeVZDN(a, "key", (i + 1));
			
			a.onclick = function() {
				self.switchWorksImage(this);
			}
			//a.ontouchend = a.onclick;
			
			if(i === 0) {
				a.className = "active";
			}
			li.appendChild(a);
			inav.appendChild(li);
		}
		this.detailView.appendChild(inav);
		
		this.showDetailViewLoading();
		
		var img = new Image();
		img.src = "/asset/works/" + dir + "/1.jpg";
		img.onload = function() {
			if(this.className == "complete") { return; }
			this.className = "complete";
			
			this.style.top = "-480px";
			worksWrap.appendChild(this);
			
			var fx = new Fx.Morph(this, {duration: 500, transition: Fx.Transitions.Sine.easeOut, onComplete: callback});
			setTimeout(
				function(){
					fx.start({
						"top" : 0
					});
				},
				500
			);
				
		}
		
		
		var bodyHeight = $(document.body).getSize().y;
		var scrollTop = $(document.body).getScroll().y;
		var ot = Math.floor((bodyHeight - 680) / 2);
		var posY = ot + scrollTop;
		if(posY < 10) {
			posY = 10;
		}
		this.detailView.style.top = posY + "px";
		
		
		function callback() {
			self.isMotionLocked = false;
			self.hideDetailViewLoading();
			
			var bg = self.overlay.getElementsByTagName("div")[0]; 
			bg.onclick = function() {
				self.closeDetailOverlay();
			}
			
			btn.onclick = function() {
				self.closeDetailOverlay();
			}
			
			//bg.ontouchend = bg.onclick;
			//btn.ontouchend = btn.onclick;
		}
	},
	
	
	
	
	switchWorksImage : function(elem) {
		var self = this;
		
		if(this.isMotionLocked) {
			return;
		}
		
		this.isMotionLocked = true;
		
		var wrap = document.getElementById("works-wrap");
		var total =  Number( this.getAttributeVZDN(wrap, "total") );
		var dir =  this.getAttributeVZDN(wrap, "dir");
		
		var currentKey =  Number( this.getAttributeVZDN(wrap, "current") );
		var nextKey =  Number( this.getAttributeVZDN(elem, "key") );
		
		this.showDetailViewLoading();
		
		var currentImg = wrap.getElementsByTagName("img")[0];
		var nextImg = new Image();
		nextImg.src = "/asset/works/" + dir + "/" + nextKey + ".jpg";
		nextImg.onload = function() {
			if(this.className == "complete") { return; }
			this.className = "complete";
			
			this.style.top = "-480px";
			wrap.appendChild(this);
			
			var fx = new Fx.Morph(this, {duration: 500, transition: Fx.Transitions.Sine.easeOut, onComplete: callback});
			setTimeout(
				function(){
					fx.start({
						"top" : 0
					});
				},
				500
			);
		}
		
		
		var nodes = this.detailView.getElementsByTagName("li");
		var i;
		var len = nodes.length;
		for(i=0; i<len; i++) {
			var a = nodes[i].getElementsByTagName("a")[0];
			a.className = "";
		}
		
		elem.className = "active";
		
		
		
		function callback() {
			self.isMotionLocked = false;
			self.hideDetailViewLoading();
			if(currentImg && currentImg.parentNode) {
				currentImg.parentNode.removeChild(currentImg);
			}
		}
	},
	
	
	
	closeDetailOverlay : function() {
		var self = this;
		
		/*
		var fx = new Fx.Morph(this.overlay, {duration: 300, transition: Fx.Transitions.linear, onComplete: callback});
		fx.start({
			"opacity" : 0
		});
		*/
		callback();
		
		function callback() {
			var nodes = self.overlay.childNodes;
			var len = nodes.length;
			for(var i=len-1; i>=0; i--) {
				var node = nodes[i];
				if(node.tagName) {
					self.overlay.removeChild(node);
				}
			}
			self.overlay.parentNode.removeChild(self.overlay);
			self.overlay = null;
			self.replayBoxMotion();
		}
	},
	
	
	
	showDetailViewLoading : function() {
		var loading;
		
		if(document.getElementById("detail-loading")) {
			loading = document.getElementById("detail-loading");
		}
		else {
			loading = document.createElement("div");
			loading.id = "detail-loading";
		}
		
		if(!loading.parentNode) {
			this.detailView.appendChild(loading);
		}
	},
	
	
	hideDetailViewLoading : function() {
		var loading = document.getElementById("detail-loading");
		if(loading && loading.parentNode) {
			this.detailView.removeChild(loading);
		}
	},
	
	
	
	
	
	
	
	
	
	//----------------------------------------------------------------------------------------------------

	startSlideBoxes : function() {
		var self = this;
		
		var i;
		var len = this.slideBoxes.length;
		
		for(i=0; i<len; i++) {
			var rel = this.slideBoxes[i].getElementsByTagName("a")[0].rel;
			var loop = Number( rel.replace(/.*length:(.+?),.*/, "$1") );
			
			var box = this.slideBoxes[i];
			this.setAttributeVZDN(box, "currentMotion", "1");
			this.setAttributeVZDN(box, "loop", loop);
			
			
			var func = createfunc(box);
			var rnd = Math.floor( Math.random() * len );
			var motionTimer = setTimeout(func, 2000 + rnd * 100);
			this.motionBoxTimers.push({ timer:motionTimer, element:box });
		}
		
		function createfunc(b) {
			return function() { self.removeMotionBoxTimer(b); self.tweenSlideBox(b); }
		}
	},
	
	
	replaySlideBoxes : function() {
		var self = this;
		
		var i;
		var len = this.slideBoxes.length;
		
		for(i=0; i<len; i++) {
			var box = this.slideBoxes[i];
			var func = createfunc(box);
			var rnd = Math.floor( Math.random() * len );
			var motionTimer = setTimeout(func, 2000 + rnd * 100);
			this.motionBoxTimers.push({ timer:motionTimer, element:box });
		}
		
		function createfunc(b) {
			return function() { self.removeMotionBoxTimer(b); self.tweenSlideBox(b); }
		}
	},
	
	
	tweenSlideBox : function(node) {
		var self = this;
		
		var current = Number( this.getAttributeVZDN(node, "currentMotion") );
		var next;
		var loop = Number( this.getAttributeVZDN(node, "loop") );
		if(current + 1 <= loop) {
			next = current + 1;
		}
		else {
			next = 1;
		}
		
		var span = node.getElementsByTagName("span")[0];
		
		var fx = new Fx.Morph(span, {duration: 500, transition: Fx.Transitions.Sine.easeOut, onComplete: callback});
		fx.start({
			"top" : (next - 1) * -114
		});
		this.motionBoxFxs.push(fx);
		
		
		this.setAttributeVZDN(node, "currentMotion", next)
		
		function callback() {
			self.removeMotionBoxFx(fx);
			self.removeMotionBoxTimer(node);
			var motionTimer = setTimeout(function(){ self.tweenSlideBox(node); }, 4000);
			self.motionBoxTimers.push({ timer:motionTimer, element:node });
		}
	},
		
	
	//----------------------------------------------------------------------------------------------------

	startFaceBoxes : function() {
		var self = this;
		
		var i;
		var len = this.faceBoxes.length;
		
		for(i=0; i<len; i++) {
			var box = this.faceBoxes[i];
			this.setAttributeVZDN(box, "currentMotion", "1");
			this.setAttributeVZDN(box, "loop", 8);
			
			var func = createfunc(box);
			var rnd = Math.floor( Math.random() * len );
			var motionTimer = setTimeout(func, 1000 + rnd * 200);
			this.motionBoxTimers.push({ timer:motionTimer, element:box });
		}
		
		function createfunc(b) {
			return function() { self.removeMotionBoxTimer(b); self.swapFaceBox(b); }
		}
	},
	
	
	replayFaceBoxes : function() {
		var self = this;
		
		var i;
		var len = this.faceBoxes.length;
		
		for(i=0; i<len; i++) {
			var box = this.faceBoxes[i];
			var func = createfunc(box);
			var rnd = Math.floor( Math.random() * len );
			var motionTimer = setTimeout(func, 1000 + rnd * 200);
			this.motionBoxTimers.push({ timer:motionTimer, element:box });
		}
		
		function createfunc(b) {
			return function() { self.removeMotionBoxTimer(b); self.swapFaceBox(b); }
		}
	},
	
	
	swapFaceBox : function(node) {
		var self = this;
		
		var current = Number( this.getAttributeVZDN(node, "currentMotion") );
		var next;
		var loop = 8;
		if(current + 1 <= 8) {
			next = current + 1;
		}
		else {
			next = 1;
		}
		
		var span = node.getElementsByTagName("span")[0];
		span.style.top = ((next - 1) * -114) + "px";
		
		this.setAttributeVZDN(node, "currentMotion", next);
		callback();
		
		function callback() {
			self.removeMotionBoxTimer(node);
			var motionTimer = setTimeout(function(){ self.swapFaceBox(node); }, 500);
			self.motionBoxTimers.push({ timer:motionTimer, element:node });
		}
	},
	
	
	
	//----------------------------------------------------------------------------------------------------

	stopAllMotionBoxes : function() {
		var i;
		var len;
		
		len = this.motionBoxTimers.length;
		for(i=0; i<len; i++) {
			clearTimeout(this.motionBoxTimers[i]["timer"]);
		}
		
		len = this.motionBoxFxs.length;
		for(i=0; i<len; i++) {
			this.motionBoxFxs[i].cancel();
		}
		
		len = this.slideBoxes.length;
		for(i=0; i<len; i++) {
			var box = this.slideBoxes[i];
			var current = Number( this.getAttributeVZDN(box, "currentMotion") );
			var span = box.getElementsByTagName("span")[0];
			span.style.top = ((current - 1) * -114 ) + "px";
		}
	},
	
	
	removeMotionBoxFx : function(fx) {
		var i;
		var len = this.motionBoxFxs.length;
		for(i=0; i<len; i++) {
			var f = this.motionBoxFxs[i];
			if(f.element == fx.element) {
				var result = this.motionBoxFxs.splice(i, 1);
				//window.console.log(result);
				break;
			}
		}
	},
	
	
	removeMotionBoxTimer : function(elem) {
		var i;
		var len = this.motionBoxTimers.length;
		for(i=0; i<len; i++) {
			var t = this.motionBoxTimers[i];
			if(t.element === elem) {
				var result = this.motionBoxTimers.splice(i, 1);
				//window.console.log(result);
				break;
			}
		}
	},
	
	
	
	//----------------------------------------------------------------------------------------------------
	//Set Position
	
	setPosition : function() {
		var unitWidth = this.UNIT_SIZE + this.PADDING * 2 + this.MARGIN;
		var bodyWidth = Math.max(this.MIN_WIDTH, $(document.body).getSize().x - this.MARGIN * 2);
		bodyWidth = bodyWidth - (this.SIDE_PADDING * 2);
		
		var colMax = Math.floor(bodyWidth / unitWidth);
		
		this.masterWidth = colMax * unitWidth;
		this.masterNode.style.width  = this.masterWidth  + "px";

		var matrix = [ [0, this.masterWidth, 0] ];
		var maxHeight = 0;
		
		var i;
		var len = this.gridNodes.length;
		for(i=0; i<len; i++) {
			var node = this.gridNodes[i];
			var size;
			var point;
			
			if(node.style.display == "none") {
				size = [0, 0];
			}
			else {
				size = this.getSizeIncludeMargin(node);
			}
			
			
			if(node.style.display == "none") {
				point = [0,0];
			}
			else {
				point = this.getAttachPoint(matrix, size[0]);
				matrix = this.updateAttachArea(matrix, point, size);
				maxHeight = Math.max(maxHeight, point[1] + size[1]);
			}

			this.props[i] = {x:point[0], y:point[1]};
		}
		
		
		this.masterHeight = Math.max(this.MIN_HEIGHT, (maxHeight + 20));
		
		var bodyWidth  = $(document.body).getSize().x;
		var bodyHeight = $(document.body).getSize().y;
		
		if(this.masterHeight < bodyHeight) {
			this.masterHeight = bodyHeight - 10;
		}
		
		var masterLeft = Math.floor((bodyWidth - this.masterWidth) / 2);
		if(masterLeft < this.SIDE_PADDING) {
			masterLeft = this.SIDE_PADDING;
		}
		
		if(bodyWidth < this.MIN_WIDTH) {
			this.masterNode.style.paddingRight = this.SIDE_PADDING + "px";
		}
		else {
			this.masterNode.style.paddingRight = "";
		}
		this.masterNode.style.left = masterLeft + "px";
		
		
		this.headerNode.style.width = (this.masterWidth - 10) + "px";
	},
	
	
	
	
	resetPosition : function() {
		var len = this.gridNodes.length;
		for(var i=0; i<len; i++) {
			var node = this.gridNodes[i];
			node.style.left = "0";
			node.style.top  = "0";
		}
	},


	
	
	
	//----------------------------------------------------------------------------------------------------
	//Direct Fit
	
	fitToGrid : function() {
		var len = this.gridNodes.length;
		for(var i=0; i<len; i++) {
			var node = this.gridNodes[i];
			node.style.left = this.props[i].x + "px";
			node.style.top  = this.props[i].y + "px";
			node.style.visibility = "visible";
		}
		
		this.masterNode.style.height = this.masterHeight + "px";
	},
	
	
	
	
	
	//----------------------------------------------------------------------------------------------------
	//Tween And Fit

	tweenAndFit : function() {
		var isMove = false;
		var i;
		var len;
		var node;
		var self = this;
		
		
		len = this.gridNodes.length;
		for(i=0; i<len; i++) {
			node = this.gridNodes[i];
			var pos = this.getOffsetPosition(node);
			if(pos.x != this.props[i].x || pos.y != this.props[i].y) {
				isMove = true;
			}
		}
		
			
		if(isMove) {
			var masterFx = new Fx.Morph(this.masterNode, {duration: 400, transition: Fx.Transitions.Sine.easeOut});
			masterFx.start({
				"height" : this.masterHeight
			});
			
			
			var lastNode;
			len = this.gridNodes.length;
			for(i=0; i<len; i++) {
				node = this.gridNodes[i];
				if(node.style.display != "none") {
					lastNode = node;
				}
			}
			
			
			var count = 0;
			for(i=0; i<len; i++) {
				node = this.gridNodes[i];
				var isLastNode = Boolean(node === lastNode);
				
				if(node.style.display == "none") {
					continue;
				}
				else {
					var pos = this.getOffsetPosition(node);
					if(pos.x == this.props[i].x && pos.y == this.props[i].y) {
						node.style.visibility = "visible";
						continue;
					}
					
					else {
						count++;
					}
				}
				
				var delay = count * 10;
				if(delay > 2000) {
					delay = 2000;
				}
				
				/*
				if($vzdn.ua.match("MSIE")) {
					delay = 0;
				}
				*/
				
				var zindex = 0;
				
				var callback = isLastNode ? function(){ self.onTweened(); } : null;
				var onstart  = function(el) {
					el.style.visibility = "visible";
				}
				
				var fx = new Fx.Morph(node, {duration: 500, fps: 60, transition: Fx.Transitions.Sine.easeOut, onComplete: callback, onStart: onstart});
				fx.start.delay(delay, fx, {
					"left" : this.props[i].x,
					"top"  : this.props[i].y
				});
			}
		}
	},
	
	
	
	
	
	
	
	
	//----------------------------------------------------------------------------------------------------
	//OnTweeed
	
	onTweened : function() {
		this.isRunnning = false;
	},
	
	
	




	
	
	
	changeAddress : function(elem) {
		var key = elem.rel;
		var hash = "";
		location.hash = hash;
	},
	
	
	
	
	onChangeAddress : function(hash) {
		var key = hash.replace(/.*\/(.*)/, "$1");
		this.refineBlocks(key);
		
		if(key) {
			SWFAddress.setTitle(this.BASE_TITLE + " | " + key.toUpperCase());
		}
		else {
			SWFAddress.setTitle(this.BASE_TITLE);
		}
		
		if(!this.isInited) {
			//this.scrollToPrevPosition();
			this.isInited = true;
		}
	},
	
	
	
	scrollToPrevPosition : function() {
		var offset = $vzdn.readScrollOffset();
		if(offset) {
			window.scrollTo(0, offset);
		}
	},
	
	
	
	
	refineBlocks : function(key) {
		this.setPosition();
		this.fitToGrid();
		document.body.style.visibility = "visible";
		document.body.style.overflow = "";
		
		
		/*
		if(this.isInited) {
			clearTimeout(this.resizeTimer);
			this.isRunnning = true;
			this.resetPosition();
			this.tweenAndFit();
		}
		else {
			this.fitToGrid();
			document.body.style.visibility = "visible";
		}
		*/
	},
	
	
	
	
	
	














	//----------------------------------------------------------------------------------------------------
	//onResize
	
	resizeHandler : function() {
		clearTimeout(this.resizeTimer);
		
		this.isRunnning = true;
		this.setPosition();
		
		var self = this;
		
		this.resizeTimer = setTimeout(function(){
				self.tweenAndFit();
			},
		200);
	},
	
	

	//----------------------------------------------------------------------------------------------------
	//onScroll
	
	scrollHandler : function() {
		clearTimeout(this.scrollTimer);
		this.scrollTimer = setTimeout(function(){
				$vzdn.writeScrollOffset();
			},
		200);
	},
	
	
	
	
	//----------------------------------------------------------------------------------------------------
	//OnFontSizeChange
	
	setFontSizeListener : function() {
		var self = this;
		
		var style = document.body.currentStyle || document.defaultView.getComputedStyle(document.body, "");
		this.fontSizeBuffer = style.fontSize;
		
		
		this.fontSizeTimer = setInterval(function(){
				var s = document.body.currentStyle || document.defaultView.getComputedStyle(document.body, "");
				if(self.fontSizeBuffer == s.fontSize) {
					return;
				}
				
				if(self.isRunnning) {
					return;
				}
				
				self.fontSizeBuffer = s.fontSize;
				
				self.setPosition();
				self.tweenAndFit();
			},
		2000);
	},
	
	
	
	
	//----------------------------------------------------------------------------------------------------
	
	setAttributeVZDN : function(elem, prop, value) {
		if(elem.setAttributeNS) {
			elem.setAttributeNS("vzdn", prop, value);
		}
		else {
			elem["vzdn:" + prop] = value;
		}
	},
	
	getAttributeVZDN : function(elem, prop) {
		var value;
		
		if(elem.getAttributeNS) {
			value = elem.getAttributeNS("vzdn", prop);
		}
		else {
			value = elem["vzdn:" + prop];
		}
		
		return value;
	},
	
	
	
	
	
	
	//----------------------------------------------------------------------------------------------------
	
	shuffleArray : function(ary) {
		var i = ary.length;
		
		while(i){
			var j = Math.floor(Math.random() * i);
			var t = ary[--i];
			ary[i] = ary[j];
			ary[j] = t;
		}
		
		return ary;
	},
	
	
	
	//----------------------------------------------------------------------------------------------------
	//Math Funcs
	
	getSizeIncludeMargin : function(elem) {
		var prop = $(elem).getSize();
		var ary = [prop.x + this.MARGIN, prop.y + this.MARGIN];
		return ary;
	},
	
	
	
	getOffsetPosition : function(elem) {
		var pos = $(elem).getPosition();
		var obj = {x:pos.x, y:pos.y};
		return obj;
	},
	
	
	
	
	
	
	
	getAttachPoint : function(mtx, width) {
		var _mtx = mtx.concat().sort(this.matrixSortDepth);
		var _max = _mtx[_mtx.length-1][2];
	
		for(var i=0,imax=_mtx.length; i<imax; i++) {
			if(_mtx[i][2] >= _max)  {
				break;
			}
			
			if(_mtx[i][1] - _mtx[i][0] >= width) {
				return [_mtx[i][0], _mtx[i][2]];
			}
		}
		return [0, _max];
	},
	
	
	
	updateAttachArea : function(mtx, point, size) {
		var _mtx = mtx.concat().sort(this.matrixSortDepth);
		var _cell = [point[0], point[0] + size[0], point[1] + size[1]];
		for(var i=0,imax=_mtx.length; i<imax; i++) {
			if(_cell[0] <= _mtx[i][0] && _mtx[i][1] <= _cell[1]) {
				delete _mtx[i];
			}
			else {
				_mtx[i] = this.matrixTrimWidth(_mtx[i], _cell);
			}
		}
		return this.matrixJoin(_mtx, _cell);
	},
		
		
		
	matrixSortDepth : function(a, b) {
		if(!a || !b) return 0;
		return ((a[2] == b[2] && a[0] > b[0]) || a[2] > b[2]) ? 1 : -1;
	},
		
		
		
	matrixSortX : function(a, b) {
		if(!a || !b) return 0;
		return (a[0] > b[0]) ? 1 : -1;
	},
		
		
		
	matrixJoin : function(mtx, cell) {
		var _mtx = mtx.concat([cell]).sort(this.matrixSortX);
		var _mtx_join = [];
		for(var i=0,imax=_mtx.length; i<imax; i++) {
			if(!_mtx[i]) {
				continue;
			}
			
			if(_mtx_join.length > 0
				&& _mtx_join[_mtx_join.length-1][1] == _mtx[i][0]
				&& _mtx_join[_mtx_join.length-1][2] == _mtx[i][2]) {
				_mtx_join[_mtx_join.length-1][1] = _mtx[i][1];
			}
			else {
				_mtx_join.push(_mtx[i]);
			}
		}
		return _mtx_join;
	},
		
		
		
	matrixTrimWidth : function(a, b) {
		if(a[0] >= b[0] && a[0] < b[1] || a[1] >= b[0] && a[1] < b[1]) {
			if(a[0] >= b[0] && a[0] < b[1]) {
				a[0] = b[1];
			}
			else {
				a[1] = b[0];
			}
		}
		return a;
	}




});





