/*
-------------------------------------------------------------------------------------
\\\\\\\\_____________________1D Cellular Automaton v1.0______________________////////
////////                                                                     \\\\\\\\
-------------------------------------------------------------------------------------
> Written by dimitris gourdoukis.
> object-e architecture 2009.
-------------------------------------------------------------------------------------
> http://object-e.blogspot.com/
> object.e.architecture@gmail.com
-------------------------------------------------------------------------------------
> released under the creative commons license 
  "Attribution-Noncommercial-Share Alike 3.0 Unported"
> http://creativecommons.org/licenses/by-nc-sa/3.0/
-------------------------------------------------------------------------------------
> v1.0 Last Modified 05/05/09. Tested on Maya 2008.
> Use and modify at your own risk.
-------------------------------------------------------------------------------------
> Description:
	This script is a one-dimensional cellular automaton algorithm. It contains two  
	procedures. The first (cellAuto) generates a random initial state of a user defi-
	ned	number of cells and calculates the solution for a user defined number of gene-
	rations. The second (animateCA) offers the option to animate the growth of the ca.
	The duration parameter specifies the number of frames between each generation.
	Note: the non active cells are also created, only with their scale set to 1.
-------------------------------------------------------------------------------------
*/
proc cellAuto (){

	int $xmax = `intSliderGrp -q -v numofCells`;
	int $generations = `intSliderGrp -q -v numofGenerations`;
	
	//create the first line of cells
	for($x=0; $x<$xmax; $x++){ 
		
		polyPlane -ax 0 0 1 -w 1 -h 1 -sx 1 -sy 1 -name ("MyPlane0x" + $x);
		move $x $generations 0;
	}
	
	//create a random initial state
	for($x=0; $x<$xmax; $x++){
		
		$name = ("MyPlane0x" + $x);
		select -cl  ;
		select -r $name ;
		if(rand(2) >1){ 
			scale 0 0 0;
		}
	}
	
	int $cell_state[];
	//loop for each generation
	for ($i=1; $i<$generations; $i++){
		
		//create an array that will contain the state of each cell
		for($x=0; $x<$xmax; $x++){
					
			$name = ("MyPlane" + ($i-1) +"x" + $x);
			string $attribholder = "getAttr \"" + $name + ".scaleX\"";
			$cell_state [$x] = `eval ($attribholder)`; 		
		}
	
		//create the planes for each generation and scale them according to the state of the neighbor cells
		for($x=0; $x<$xmax; $x++){
			
			polyPlane -ax 0 0 1 -w 1 -h 1 -sx 1 -sy 1 -name ("MyPlane" + $i + "x" + $x);
			move $x ($generations-$i) 0;
			scale 0 0 0;
	
			int $neigh_state;
			//take care of the border cells
			if ($x==0){
				$neigh_state = $cell_state[$x+1];
			}else if ($x==$xmax){
				$neigh_state = $cell_state[$x-1];
			}else{
				$neigh_state = $cell_state[$x-1] + $cell_state[$x+1];
			}
			
			$name = ("MyPlane" + $i + "x" + $x);
			select -cl  ;
			select -r $name ;
			//here are the ca rules
			if ($neigh_state==0){
				scale 0 0 0;
			}else if ($neigh_state==1){
				scale 1 1 1;}
			else{
				scale 0 0 0;
			}
		}
	}
}

proc animateCA (){
	int $ymax = `intSliderGrp -q -v numofCells`;
	int $generation = `intSliderGrp -q -v numofGenerations`;
	int $duration = `intSliderGrp -q -v duration`;
	int $cell_scale[];
	string $nome;
	for ($i=1; $i<$generation; $i++){
		for($x=0; $x<$ymax; $x++){
			$nome = ("MyPlane" + $i +"x" + $x);
			string $attribholder = "getAttr \"" + $nome + ".scaleX\"";
			$cell_scale [$x] = `eval ($attribholder)`; 		
		}
		
		for($x=0; $x<$ymax; $x++){
			if($cell_scale[$x] == 1){
				$nome = ("MyPlane" + $i + "x" + $x);
				select -cl  ;
				select -r $nome ;
				currentTime (($i-1)*$duration);
				scale 0 0 0;
				eval ("setKeyframe \"" + $nome + ".sx\"");
				eval ("setKeyframe \"" + $nome + ".sy\"");
				eval ("setKeyframe \"" + $nome + ".sz\"");
				currentTime ($i*$duration);
				scale 1 1 1;
				eval ("setKeyframe \"" + $nome + ".sx\"");
				eval ("setKeyframe \"" + $nome + ".sy\"");
				eval ("setKeyframe \"" + $nome + ".sz\"");
			}
		}
	}
}

//UI
global proc constructCaWin ()
{
	if (`window -exists CaWindow`) { 
		deleteUI CaWindow; 
	}
	 
	window
	-width 400
	-height 200
	-title "1D Cellular Automaton v1.0"
	-sizeable true
	CaWindow;
	
	columnLayout;
		
	text -l "";
	
	intSliderGrp -label "number of cells"
	-field true
	-fieldStep 1
	-sliderStep 1
	-value 5
	-fieldMinValue 0 -fieldMaxValue 100
	numofCells;
	
	intSliderGrp -label "number of gens"
	-field true
	-fieldStep 1
	-sliderStep 1
	-value 5
	-fieldMinValue 0 -fieldMaxValue 100
	numofGenerations;
	
	//create button
	button -label "Generate"
	-command "cellAuto" buildIt;
	
	intSliderGrp -label "duration"
	-field true
	-fieldStep 1
	-sliderStep 1
	-value 5
	-fieldMinValue 0 -fieldMaxValue 100
	duration;
	
	//create button
	button -label "Animate"
	-command "animateCA" buildUs;
	
	setParent ..;
	
	//break
	columnLayout;
	text -l "";
	separator -w 800 -h 4 -backgroundColor 1 0.663 1;
	text -l "object-e / dimitris gourdoukis. 2009.";
	text -l "http://object-e.blogspot.com/";
		 	
	showWindow;
}

constructCaWin;