

enum StepDirection {
  NONE;
  UP;
  LEFT;
  DOWN;
  RIGHT;
}

class Design_11_11_MazeGenerator extends SceneScript
{
	public var _C:Float;

	
	private static var Pos=-1;
	prviate static var oldPos=0;
	
	private static var nextStep=0; // Maybe return from findDir
	//private static var array=new Array<Array<Int>>();	
	private static var array:Array<Dynamic>=new Array<Dynamic>();	
	
	private static var X:Int=1;
	private static var Y:Int=1;
	
	/* ========================= Custom Event ========================= */
	public function _customEvent_ArrayToPath():Void
	{
		/* "Marching Square Algorithm" */
		/* http://devblog.phillipspiess.com/better%20know%20an%20algorithm/2010/02/23/better-know-marching-squares.html
		*/
		
		trace("Before    ArrayToPath");
		var array:Array<Dynamic>=new Array<Dynamic>();
		var dirCounter=1;
		var oldNextStep=-20;
		
		var posCounter=0;
		
		var Size=12; // ?? What is Size ?? 
		
		setGameAttribute("StepWorker", 0);
		
		

		// testdata
		if(true){
			array.push([1,1]);
			array.push([0,1]);
			array.push([0,15]);
			array.push([15,15]);
			array.push([15,0]);
			array.push([0,0]);
			array.push([0,1]);
			array.push([1,1]);
		}
		setGameAttribute("posCounter", 0);
		posCounter=0;
		var Pos=0;
		while(Pos != 16)){
		
			if(Pos == -1)
			{
				Pos=16;
			}
			//_customEvent_FindDir();
			findDir(); // changes nextStep
			Pos += nextStep;
			if(oldNextStep == nextStep){
				dirCounter ++;
				
			}			else			{
				if(oldNextStep == 1){
					X+=dirCounter;
				}
				if(oldNextStep == -1){
					X-=dirCounter;
				}
				if(oldNextStep == Size){
					Y+=dirCounter;
				}
				if(oldNextStep == -Size){
					Y-=dirCounter;
					
				}
				var pos:Array<Dynamic>=new Array<Dynamic>();
				pos.push(X);pos.push(Y);
				array.push(pos);
				setGameAttribute("oldNextStep", ((getGameAttribute("nextStep")) : Dynamic));
				oldNextStep=nextStep;
				dirCounter=1;
				
			} // iff oldNexStep = nextStep?
			
			posCounter++;
			// Limit the number of steps it takes to do the marching (endless marching check!?)
			if(posCounter > 3000) ||  X > Size + 1 || Y > Size +1 ){
			
				trace("Stopping since posCounter  > ...");
				
				Pos = 16;
			}
trace("X,Y:  " + X + " , "+Y);
			
			
			if(posCounter > 2 && dirCounter < 1){
				if(X == 1 && Y == 1){
					trace("Stopping since X == 1 && Y == 1");
					Pos = 16;
					
				}
			}
		} // while pos != 16
trace((("ArrayToPath: ") + ("" + array)));
		
	} // arrayToPath
	
	
	private static function isPixelSolid(X:Int, Y:Int):Bool{
		var retval:Bool = false;
			for(pos in array){
				if(pos[0] == X && pos[1] == Y){
					retval=true;
				}
			}
		return retval;
	}
	
	private static function findDir(){
			var x=X;
			var y=Y;
			
			var upLeft:Bool = IsPixelSolid(x-1, y-1);
			var upRight:Bool = IsPixelSolid(x, y-1);
			var downLeft:Bool = IsPixelSolid(x-1, y);
			var downRight:Bool = IsPixelSolid(x, y);
 
			// Store our previous step
			var previousStep = nextStep;
 
			// Determine which state we are in
			var state:Int = 0;
 
 
			if (upLeft)
				state |= 1;
			if (upRight)
				state |= 2;
			if (downLeft)
				state |= 4;
			if (downRight)
				state |= 8;
 var prevStep=nextStep;
   switch (state)
    {
      case 1, 5, 13: 
        nextStep = StepDirection.UP;
      case 2, 3, 7: 
        nextStep = StepDirection.RIGHT;
      case 4, 12, 14: 
        nextStep = StepDirection.LEFT;
      case 6:
        nextStep = (prevStep == StepDirection.UP ? StepDirection.LEFT : StepDirection.RIGHT);
      case 8, 10, 11: 
        nextStep = StepDirection.DOWN;
      case 9:
        nextStep = (prevStep == StepDirection.RIGHT ? StepDirection.UP : StepDirection.DOWN);
      default: 
		nextStep = StepDirection.None;
    }
  }
  
			/*
			// State now contains a number between 0 and 15
			// representing our state.
			// In binary, it looks like 0000-1111 (in binary)
 
			// An example. Let's say the top two pixels are filled,
			// and the bottom two are empty.
			// Stepping through the if statements above with a state
			// of 0b0000 initially produces:
			// Upper Left == true ==>  0b0001
			// Upper Right == true ==> 0b0011
			// The others are false, so 0b0011 is our state
			// (That's 3 in decimal.)
 
			// Looking at the chart above, we see that state
			// corresponds to a move right, so in our switch statement
			// below, we add a case for 3, and assign Right as the
			// direction of the next step. We repeat this process
			// for all 16 states.
 
			// So we can use a switch statement to determine our
			// next direction based on
			switch (state )
			{
				case 1: nextStep = StepDirection.Up;
				case 2: nextStep = StepDirection.Right; 
				case 3: nextStep = StepDirection.Right;
				case 4: nextStep = StepDirection.Left; 
				case 5: nextStep = StepDirection.Up; 
				case 6:
					if (previousStep== StepDirection.Up)
					{
						nextStep = StepDirection.Left;
					}
					else
					{
						nextStep = StepDirection.Right;
					}
					
				case 7: nextStep = StepDirection.Right; 
				case 8: nextStep = StepDirection.Down; 
				case 9:
					if (previousStep== StepDirection.Right)
					{
						nextStep = StepDirection.Up;
					}
					else
					{
					nextStep = StepDirection.Down;
					}
					
				case 10: nextStep = StepDirection.Down; 
				case 11: nextStep = StepDirection.Down; 
				case 12: nextStep = StepDirection.Left; 
				case 13: nextStep = StepDirection.Up; 
				case 14: nextStep = StepDirection.Left; 
				default:
					nextStep = StepDirection.None;
					
			}
			*/
		}
		
	}
	
	/* ========================= Custom Event ========================= */
	
	private static function findDir2(){
		var previousStep = nextStep;
		
		var findUpLeft = 1;
		var findUpRight = 1;
		var findDownLeft = 1;
		var findDownRight = 1;
		
		//if((asNumber((getGameAttribute("Pos"))) > (asNumber((getGameAttribute("Size"))) * 2)))
		
		if(Pos > Size *2){
			var pos:Array<Dynamic>=new Array<Dynamic>();
			pos = array[Pos-(Size+1)];
			findUpLeft=pos;
			setGameAttribute("FindUpLeft", ((getGameAttribute("Array")) : Array<Dynamic>)[Std.int((asNumber((getGameAttribute("Pos"))) - Math.round((asNumber((getGameAttribute("Size"))) + 1))))]);
		}
		setGameAttribute("FindUpRight", 1);
		if((asNumber((getGameAttribute("Pos"))) > (asNumber((getGameAttribute("Size"))) * 2)))
		{
			setGameAttribute("FindUpRight", ((getGameAttribute("Array")) : Array<Dynamic>)[Std.int((asNumber((getGameAttribute("Pos"))) - asNumber((getGameAttribute("Size")))))]);
		}
		setGameAttribute("FindDownLeft", 1);
		if((asNumber((getGameAttribute("Pos"))) < (asNumber((getGameAttribute("Size"))) * (asNumber((getGameAttribute("Size"))) - 1))))
		{
			setGameAttribute("FindDownLeft", ((getGameAttribute("Array")) : Array<Dynamic>)[Std.int((asNumber((getGameAttribute("Pos"))) - 1))]);
		}
		setGameAttribute("FindDownRight", 1);
		if((asNumber((getGameAttribute("Pos"))) < (asNumber((getGameAttribute("Size"))) * (asNumber((getGameAttribute("Size"))) - 1))))
		{
			setGameAttribute("FindDownRight", ((getGameAttribute("Array")) : Array<Dynamic>)[Std.int(asNumber((getGameAttribute("Pos"))))]);
		}
		setGameAttribute("nextStep", 1);
		trace((("Investigating Pos: ") + ("" + (getGameAttribute("Pos")))));
		trace((("UpLeft ") + ("" + (getGameAttribute("FindUpLeft")))));
		trace((("UpRight ") + ("" + (getGameAttribute("FindUpRight")))));
		trace((("DownLeft ") + ("" + (getGameAttribute("FindDownLeft")))));
		trace((("DownRight ") + ("" + (getGameAttribute("FindDownRight")))));
		var state=0;
		if((((getGameAttribute("FindUpLeft")) : Dynamic) == 0))
		{
			state |= 1;
		}
		if((((getGameAttribute("FindUpRight")) : Dynamic) == 0))
		{
			state |= 2;
		}
		if((((getGameAttribute("FindDownLeft")) : Dynamic) == 0))
		{
			state |= 4;
		}
		if((((getGameAttribute("FindDownRight")) : Dynamic) == 0))
		{
			state |= 8;
		}
		trace((("State: ") + ("" + state)));
		if((state == 1))
		{
			setGameAttribute("nextStep", -(asNumber((getGameAttribute("Size")))));
		}
		if((state == 2))
		{
			setGameAttribute("nextStep", 1);
		}
		if((state == 3))
		{
			setGameAttribute("nextStep", 1);
		}
		if((state == 4))
		{
			setGameAttribute("nextStep", -1);
		}
		if((state == 5))
		{
			setGameAttribute("nextStep", -(asNumber((getGameAttribute("Size")))));
		}
		if((state == 6))
		{
			if((((getGameAttribute("previousStep")) : Dynamic) == -(asNumber((getGameAttribute("Size"))))))
			{
				setGameAttribute("nextStep", -1);
			}
			else
			{
				setGameAttribute("nextStep", 1);
			}
		}
		if((state == 7))
		{
			setGameAttribute("nextStep", 1);
		}
		if((state == 8))
		{
			setGameAttribute("nextStep", ((getGameAttribute("Size")) : Dynamic));
		}
		if((state == 9))
		{
			if((((getGameAttribute("previousStep")) : Dynamic) == 1))
			{
				setGameAttribute("nextStep", -(asNumber((getGameAttribute("Size")))));
			}
			else
			{
				setGameAttribute("nextStep", ((getGameAttribute("Size")) : Dynamic));
			}
		}
		if((state == 10))
		{
			setGameAttribute("nextStep", ((getGameAttribute("Size")) : Dynamic));
		}
		if((state == 11))
		{
			setGameAttribute("nextStep", ((getGameAttribute("Size")) : Dynamic));
		}
		if((state == 12))
		{
			setGameAttribute("nextStep", -1);
		}
		if((state == 13))
		{
			setGameAttribute("nextStep", -(asNumber((getGameAttribute("Size")))));
		}
		if((state == 14))
		{
			setGameAttribute("nextStep", -1);
		}
	}
	
	/* ========================= Custom Event ========================= */
	public function _customEvent_getDir():Void
	{
		setGameAttribute("isDirOK", false);
		setGameAttribute("Dir", -1000);
		while(((((getGameAttribute("DirArray")) : Array<Dynamic>).length < 3) && !(((getGameAttribute("isDirOK")) : Bool))))
		{
			shoutToScene("_customEvent_" + "getNumber");
			setGameAttribute("dirRandom", (asNumber((getGameAttribute("getNumberRetval"))) % 3));
			trace((("dirRandom:  (getNumberRetval)") + ((("") + ((("" + (getGameAttribute("dirRandom"))) + ("")))))));
			if(!(Utils.contains(((getGameAttribute("DirArray")) : Array<Dynamic>), ((getGameAttribute("dirRandom")) : Dynamic))))
			{
				((getGameAttribute("DirArray")) : Array<Dynamic>).push(((getGameAttribute("dirRandom")) : Dynamic));
				setGameAttribute("isDirOK", true);
				setGameAttribute("Dir", ((getGameAttribute("dirRandom")) : Dynamic));
			}
		}
		if(!(((getGameAttribute("Dir")) : Dynamic) == -1000))
		{
			if((((getGameAttribute("Dir")) : Dynamic) == 0))
			{
				setGameAttribute("Dir", -1);
			}
			else if((((getGameAttribute("Dir")) : Dynamic) == 1))
			{
				setGameAttribute("Dir", 1);
			}
			else if((((getGameAttribute("Dir")) : Dynamic) == 2))
			{
				setGameAttribute("Dir", ((getGameAttribute("Size")) : Dynamic));
			}
			else if((((getGameAttribute("Dir")) : Dynamic) == 3))
			{
				setGameAttribute("Dir", -(asNumber((getGameAttribute("Size")))));
			}
		}
	}
	
	
	public function new(dummy:Int, dummy2:Engine)
	{
		super();
		nameMap.set("C", "_C");
		_C = 0.0;
		
	}
	
	override public function init()
	{
		
	}
	
	override public function forwardMessage(msg:String)
	{
		
	}
}