var Cloud = jsFW.Class({
	tags:[],
	vx:0.0,
	vy:0.0,
	ax:-0.01,
	ay:-0.01,
	parentCoords:null,
	interval: 100,
	
	__constructor:function(o)
	{
		jsFW.hash.extend(this,o);
		this.init();
	},
		
	init:function()
	{
		this.parent = jsFW.element(this.parent);
			var tmpParent = jsFW.element('cloudtop');
			//alert(tmpParent);
		this.parentCoords = getOffsetRect(this.parent);
		this.initMatrix();
		this.currint = this.interval;
		//tmpParent.onmousemove = jsFW.delegate(this,this.mousemove);
		this.parent.onmousemove = jsFW.delegate(this,this.mousemove);
		//this.parent.onclick = jsFW.delegate(this,this.onclick);
		jsFW.event.hover(this.parent,jsFW.delegate(this,this.hover));
	},
	mousemove:function(s,e)
	{
		if (navigator.appName.substring(0,3) == "Net") {
			e.preventDefault();
			var x = e.pageX - this.parentCoords.left;
			if (x < 0) x = 0;
			var y = e.pageY - this.parentCoords.top;
			if (y < 0) y = 0;
		} else {
			var x = event.x + document.documentElement.scrollLeft;
			var y = event.y + document.documentElement.scrollTop;
		}
		
		this.vx = -(x/s.clientWidth-0.5)/3;
		this.vy = (y/s.clientHeight-0.5)/3;
		this.initMatrix();
	},
	
	// onmouseout:function(s,e) {
		// alert('sadasd');
		// this.currint = Math.round(this.interval*2);
	// },
	
	hover:function(s,e)
	{
		if(e.hover)
		{
			this.currint = this.interval;
			this.timeout = this.play();
		}
		else if(this.timeout)
		{
			this.stop();
			// this.currint = Math.round(this.interval*2);
			// this.timeout = this.play();
			// window.setTimeout(this.stop, 1000);
			// window.setTimeout(this.clear, 1000);
			
		}
	},
	
	play: function() {
		return setInterval(jsFW.delegate(this,this.process),this.currint);
	},
	
	stop: function() {
		clearInterval(this.timeout);
	},
	
	clear: function() {
		this.vx = 0;
		this.vy = 0;
		this.initMatrix;
	},
	
	initMatrix:function()
	{
		var cosX =Math.cos(this.vx);
		var sinX =Math.sin(this.vx);
		var cosY =Math.cos(this.vy);
		var sinY =Math.sin(this.vy); 
		this.mx = [
			[1,0,0],
			[0,cosY,-sinY],
			[0,sinY,cosY]
		];
		this.my = [
			[cosX,0,sinX],
			[0,1,0],
			[-sinX,0,cosX]
		];
	},
	umn:function(m,v)
	{
		return [
			m[0][0]*v[0]+m[0][1]*v[1]+m[0][2]*v[2],
			m[1][0]*v[0]+m[1][1]*v[1]+m[1][2]*v[2],
			m[2][0]*v[0]+m[2][1]*v[1]+m[2][2]*v[2]
		]
	},
	initTag:function(jtag)
	{
		var tag = new Tag(jtag,this)
		var html = tag.getHtml();
		if(html)
		{
			this.parent.appendChild(html);
			var x = Math.rand(-this.radius,this.radius);
			var my = Math.sqrt(this.radius*this.radius - x*x);
			var y = Math.rand(-my,my);
			var mz = Math.sqrt(this.radius*this.radius - x*x - y*y);
			var z = Math.rand(-mz,mz);
			tag.setPosition({x:x+this.radius+this.x,y:y+this.radius+this.y,z:z+this.radius});
			return tag;
		}
	},
	process:function()
	{
		var dx = this.radius+this.x;
		var dy = this.radius+this.y;
		this.tags.map(function(tag)
		{
			var p = [tag.x-dx,tag.y-dy,tag.z-this.radius];
			var r = this.umn(this.my,p);
			var r = this.umn(this.mx,r);
			tag.setPosition({x:r[0]+dx,y:r[1]+dy,z:r[2]+this.radius});
		},this);
		this.vx += this.ax;
		this.vy += this.ay;
	},
	
	addTag:function(tag)
	{
		this.tags=this.tags.concat(tag.map(function(e){return this.initTag(e)},this));
	}
});
var Tag = jsFW.Class({
	x:0,
	y:0,
	z:0,
	width:0,
	height:0,
	k: 0,
	
	__constructor:function(o,cloud)
	{
		jsFW.hash.extend(this,o);
		this.cloud = cloud;
		this.init();
	},
	setPosition:function(p)
	{
		this.x = p.x;
		this.y = p.y;
		this.z = p.z;
	
		this.html.style.left = this.x+'px';
		this.html.style.top = this.y+'px';
		this.html.style.zIndex = this.z;
		var z = 0.2+this.z/this.cloud.radius/2;
		if (z > 1) z = 1;
		if (z <= 0) z = 0.01;

		jsFW.element.opacity(this.html,z);
		
		z = z*2;
		
		this.img.style.width = Math.round(this.width*z) +'px';
		this.img.style.height = Math.round(this.height*z) +'px';
		this.html.style.width = Math.round(this.width*z) +'px';
		this.html.style.height = Math.round(this.height*z) +'px';
	},
	getHtml:function() {
		if(!this.html){
			this.html = document.createElement('a');
		
			this.html.className = this.cloud.tagname;
			this.html.href = this.src;//this.href;
			this.img = document.createElement('img');
			
			this.img.style.border = 'none';
			this.img.src = this.src;
			this.img.title = this.text;
			this.img.alt = this.text;
			this.k = 1;
			
			if (this.img.width <= this.cloud.radius*0.5) {
				this.width = this.img.width;
			} else {
				this.k = this.cloud.radius*0.5/this.img.width;
				this.width = Math.round(this.img.width*this.k);
			}
				//if (this.w > 0) this.width = this.img.width*(this.w/4);
			if (this.k == 1) {
				this.height = this.img.height;
			} else {
				this.height = Math.round(this.img.height*this.k);
			}
				//if (this.w > 0) this.height = this.img.height*(this.w/4);
			this.html.appendChild(this.img);
		}
		return this.html;
	},
	init:function()
	{
		
	}
});

function getOffsetRect(elem) {
    // (1)
    var box = elem.getBoundingClientRect();
 
    // (2)
    var body = document.body;
    var docElem = document.documentElement;
 
    // (3)
    var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
    var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
 
    // (4)
    var clientTop = docElem.clientTop || body.clientTop || 0;
    var clientLeft = docElem.clientLeft || body.clientLeft || 0;
 
    // (5)
    var top  = box.top +  scrollTop - clientTop;
    var left = box.left + scrollLeft - clientLeft;
 
    return { top: Math.round(top), left: Math.round(left) };
}