// Fractal Clouds (c) CSE, 2006

			function dec2hex(n) {
				var i = 0;
				var hexstr = "0123456789ABCDEF";
				var str = "";
				while (n != 0) {
					i++;
					tmp = n % 16;
					n -= tmp;
					n /= 16;
					str = str+hexstr.charAt(tmp);						
				}
				if (i<2) str = "0"+str;
				return str;
			}

			function randomColor() {
				var rnd_r = Math.floor(256*Math.random());
				var rnd_g = Math.floor(256*Math.random());
				var rnd_b = Math.floor(256*Math.random());
				var str = "";
				str = "#" + dec2hex(rnd_r) + dec2hex(rnd_g) + dec2hex(rnd_b);
				return str;
			}

			function newMDA(iRows,iCols, format) 
			{ 
			// MDA = MultiDimentionalArray
			// format: 0: number; 1: string; 2: random nb
				var i; 
				var j; 
				var a = new Array(iRows); 
				for (i=0; i < iRows; i++) 
				{ 
					a[i] = new Array(iCols); 
					for (j=0; j < iCols; j++) { 
						if (format == 0) a[i][j] = 0;
						if (format == 1) a[i][j] = ""; 
						if (format == 2) a[i][j] = Math.random();
					} 
				} 
				return(a); 
			} 
			
			function multiMDA(mda, factor) {
				var lg = mda.length;
				for (i=0;i<lg;i++) {
					for (j=0;j<lg;j++) {
						mda[i][j] = mda[i][j]*factor;
					}
				}
				return mda;
			}
			
			function addMDA(mda, factor) {
				var lg = mda.length;
				for (i=0;i<lg;i++) {
					for (j=0;j<lg;j++) {
						mda[i][j] = mda[i][j]+factor;
					}
				}
				return mda;
			}
			
			function bipolarRnd(mu, sigma) {
				var nb;
				nb = (sigma*Math.pow(-2*Math.log(Math.random()), 0.3)*Math.cos(2*3.14159265*Math.random()))+mu;
				return nb;
			}
			
			function foldedPlan(iter, ini_ampl, pert, pert_dampen) {
                var surf=newMDA(2,2,2);
                var sz = 2;
                
                surf = multiMDA(surf,ini_ampl);
                //surf = addMDA(surf,-1*ini_ampl);
                
                var cnt = 1;
                
                for (i=0; i<iter; i++) {
                	sz = Math.pow(2,cnt)+1;
                	surf2 = newMDA(sz,sz,0);
                	//alert(surf);
                	
                	for (j=0;j<surf.length-1;j++) {
                		for (k=0;k<surf.length-1;k++) {
                			// corners copied
                			surf2[2*j][2*k] = surf[j][k];
                			surf2[2*j][2*(k+1)] = surf[j][k+1];
                			surf2[2*(j+1)][2*k] = surf[j+1][k];
                			surf2[2*(j+1)][2*(k+1)] = surf[j+1][k+1];
                			// center
                			surf2[2*j+1][2*k+1] = (surf[j][k]+surf[j+1][k]+surf[j][k+1]+surf[j+1][k+1])/4+bipolarRnd(0,1)*pert;
                			// edges mids
                			surf2[2*j+1][2*k] = (surf[j][k]+surf[j+1][k])/2+bipolarRnd(0,1)*pert;
                			surf2[2*j+1][2*(k+1)] = (surf[j][k+1]+surf[j+1][k+1])/2+bipolarRnd(0,1)*pert;
                			surf2[2*j][2*k+1] = (surf[j][k]+surf[j][k+1])/2+bipolarRnd(0,1)*pert;
                			surf2[2*(j+1)][2*k+1] = (surf[j+1][k]+surf[j+1][k+1])/2+bipolarRnd(0,1)*pert;
                		}
                	}
                	surf = surf2;
                	
                	pert /= pert_dampen;
                	cnt = cnt + 1;
                }
                
                var mx_vl = 0;
				for (j=0;j<surf.length-1;j++) {
					for (k=0;k<surf.length-1;k++) {
						if (surf[j][k]<0) surf[j][k] = 0;
						if (surf[j][k]>mx_vl) mx_vl=surf[j][k];
                	}
                }
                
                surf = multiMDA(surf, 1/mx_vl);
                
                return surf;
			
			}
			
			function getObj(name)
			{
				if (document.getElementById)
				{
					this.obj = document.getElementById(name);
				}
				else if (document.all)
				{
					this.obj = document.all[name];
				}
				else if (document.layers)
				{
					this.obj = document.layers[name];
				}
			}
			
			function hidediv() { 
				if (document.getElementById) 
				{ // DOM3 = IE5, NS6 
					document.getElementById('msg').style.visibility = 'hidden'; 
				} else { 
					if (document.layers)
					{ // Netscape 4 
						document.msg.visibility = 'hidden'; 
					} else { // IE 4 
						document.all.msg.style.visibility = 'hidden'; 
					} 
				}
			}
			
			function showdiv() { 
				if (document.getElementById) 
				{ // DOM3 = IE5, NS6 
					document.getElementById('msg').style.visibility = 'visible'; 
				} else { 
					if (document.layers)
					{ // Netscape 4 
						document.msg.visibility = 'visible'; 
					} else { // IE 4 
						document.all.msg.style.visibility = 'visible'; 
					} 
				}
			}
			
			function launchCalculation() {
				showdiv();
				timer = setTimeout("readDataCalculation()",100);
				return false;
			}
			
			function readDataCalculation() {
			
           	
           		var iter = document.clouds.iter.value*1;
           		
           		if (iter>8) alert('Calculations will be really long... Use around 7 iterations for reasonable computation times...');
           		
           		var ini_ampl = document.clouds.ini_ampl.value*1;
           		var perturbation = document.clouds.perturbation.value*1;
           		var pert_dampen = document.clouds.pert_dampen.value*1;
           		
           		drawClouds(iter, ini_ampl, perturbation, pert_dampen, "cv");
           		
           		hidediv();
				
			}

            function drawClouds(iter, ini_ampl, perturbation, pert_dampen, canv_name) {
           		var nb_el;
           		           		
                var surf=foldedPlan(iter, ini_ampl, perturbation, pert_dampen);
           		var str = "";
				
				
               canvas = document.getElementById(canv_name);
               ctx = canvas.getContext("2d");
 
               ctx.clearRect(0,0,canvas.width,canvas.height);
 
               ctx.lineWidth = 1;
               ctx.strokeStyle = "#FF00FF";
               ctx.moveTo(0,0);
               ctx.save();
               
               nb_el = surf.length;
               cur_width = canvas.width/nb_el;
               
               

                  grd = ctx.createLinearGradient(0, 0, 0, canvas.height);
                  grd.addColorStop(0,"#40A0E0");
                  grd.addColorStop(1,"#A0E0E0");
                  ctx.fillStyle = grd;
                  ctx.beginPath();
                  ctx.moveTo(0, 0);
                  ctx.lineTo(0, canvas.height);
                  ctx.lineTo(canvas.width, canvas.height);
                  ctx.lineTo(canvas.width, 0);
                  ctx.closePath();
                  ctx.fill();
						  
               for (i=0;i<nb_el;i++) {
               		for (j=0;j<nb_el;j++) {
               			  if (surf[i][j]<=0) {
               			  	// str = "#" + dec2hex(1) + dec2hex(200) + dec2hex(255);
               			  } else {
							  //str = "#" + dec2hex(20*surf[i][j]+1) + dec2hex(55*surf[i][j]+200) + dec2hex(255);
					      }
					      if (surf[i][j]<0.7) {
					      	str = 'rgba(255,255,255,' + surf[i][j] + ')';
					      } else {
					      	val = Math.floor(255-(surf[i][j]-0.7)*50);
					      	str = 'rgba(' + val + ',' + val + ',' + val + ',' + surf[i][j] + ')';
					      }
						  ctx.fillStyle = str;
						  ctx.beginPath();
						  ctx.moveTo(Math.floor(cur_width*i), Math.floor(cur_width*j));
						  ctx.lineTo(Math.floor(cur_width*i), Math.floor(cur_width*(j+1)));
						  ctx.lineTo(Math.floor(cur_width*(i+1)), Math.floor(cur_width*(j+1)));
						  ctx.lineTo(Math.floor(cur_width*(i+1)), Math.floor(cur_width*j));
						  ctx.closePath();
						  ctx.fill();
               		}
               }
           	   
               ctx.restore();
               
            }

            function testdraw() {
           	
           		var iter = 4;
           		var ini_ampl = 100;
           		var nb_el = 16;
           		           		
                var surf=foldedPlan(3, 20, 20);
           
               canvas = document.getElementById("cv");
               ctx = canvas.getContext("2d");
 
               ctx.clearRect(0,0,canvas.width,canvas.height);
 
               ctx.lineWidth = 1;
               ctx.strokeStyle = "#FF00FF";
               ctx.moveTo(0,0);
               ctx.save();
               cur_width = canvas.width/nb_el;
               
               
               for (i=0;i<nb_el;i++) {
               		for (j=0;j<nb_el;j++) {
						  grd = ctx.createLinearGradient(cur_width*i, cur_width*j, cur_width*(i+1), cur_width*(j+1));
						  grd.addColorStop(0,randomColor());
						  grd.addColorStop(1,randomColor());
						  ctx.fillStyle = grd;
						  ctx.beginPath();
						  ctx.moveTo(cur_width*i, cur_width*j);
						  ctx.lineTo(cur_width*i, cur_width*(j+1));
						  ctx.lineTo(cur_width*(i+1), cur_width*(j+1));
						  ctx.lineTo(cur_width*(i+1), cur_width*j);
						  ctx.closePath();
						  ctx.fill();
               		}
               }
           	   
               ctx.restore();
               
            }
