package {
    import away3d.cameras.*;
    import away3d.containers.*;
    import away3d.core.base.*;
    import away3d.core.math.*;
    import away3d.core.render.*;
    import away3d.core.utils.*;
    import away3d.materials.*;
    import away3d.primitives.*;
    
    import com.tiles.*;
    import com.utils.ai.Path;
    
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.text.TextField;
    
    public class Detour extends Sprite
    {
        
        
        [Embed(source="assets/dirtysand.jpg")]
        public var FloorImg:Class;
        
        [Embed(source="assets/stonetile10.jpg")]
        public var WallImg:Class;
        
        /*
            Matrix Key:
            1 = floor
            2 = wall
        //*/
        
        private var _boardMatrix:Array = [[{t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}],
                                            [{t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}],
                                              [{t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}],
                                             [{t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}],
                                              [{t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}],
                                             [{t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}],
                                              [{t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}],
                                             [{t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}],
                                              [{t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}],
                                             [{t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}],
                                              [{t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}],
                                             [{t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}, {t:1}],
                                              [{t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}, {t:1}, {t:2}]];
        
        private var _pathFinder:Path = new Path(_boardMatrix);
        
        
        private var view:View3D;
        private var sphereA:Sphere;
        private var _floorDipObj:ObjectContainer3D;
        private var _wallsDipObj:ObjectContainer3D;
        private var _playersDipObj:ObjectContainer3D;
        private var _obstructDipObj:ObjectContainer3D;
        
        private var _p1_AvatarSphere:Sphere;
        private var _p2_AvatarSphere:Sphere;
        
        private var _outputTxt:TextField;
        
        //TileType Contrainers
        private var _floorSprite:Sprite;
        private var _playersSprite:Sprite;
        private var _wallsSprite:Sprite;
        private var _basesSprite:Sprite;
        private var _obstructionSprite:Sprite;
        
        
        private var _p1_Avatar:Sprite;
        private var _p2_Avatar:Sprite;
        
        private var _clearSpaces:Array = new Array();
    
        private var p2_CurrentCell:Object     = _boardMatrix[1][1];
        private var p2_EndCell:Object         = _boardMatrix[11][11];
        private var p1_CurrentCell:Object     = _boardMatrix[11][11];
        private var p1_EndCell:Object         = _boardMatrix[1][1];  
                
        private var _cubeSize = 90;
        
        public function Detour()
        {
            this.addEventListener("boardComplete", addPlayers);
            this.addEventListener(Event.ENTER_FRAME,away3dloop);
            
            this.stage.addEventListener(KeyboardEvent.KEY_DOWN,checkKeysDown);
            this.stage.scaleMode = "noScale";
            this.stage.align = "left";
            this.stage.frameRate=60;
            
            this.addChild(view=new View3D({x:stage.stageWidth/2, y:stage.stageHeight/2}));
            view.x=400;
            view.y=300;
            view.camera.rotationY= 45;
            view.camera.rotationX=140;
            
            createChildren();
            
            
        }
    
        private function away3dloop(event:Event):void {
            _p1_AvatarSphere.rotationY += 3;
            _p2_AvatarSphere.rotationY -= 3;
            view.camera.moveTo(new Number3D(650, 0, 650));
            
            view.camera.moveBackward(2500);
            view.render();
        }
        
        private function checkKeysDown(event:KeyboardEvent):void{
            trace(_boardMatrix.length + " " + _boardMatrix[0].length + " " + (p1_CurrentCell.r) + " " + p1_CurrentCell.c)
            switch(event.keyCode){
                case 40:
                    //down
                    //check to see if you could advance
                    if((p1_CurrentCell.r) <=  _boardMatrix.length-2 && _boardMatrix[(p1_CurrentCell.r)+1][p1_CurrentCell.c].t == 1){
                        p1_CurrentCell = _boardMatrix[(p1_CurrentCell.r)+1][p1_CurrentCell.c];
                        _p1_AvatarSphere.z = _cubeSize * p1_CurrentCell.r;
                        _p1_AvatarSphere.x = _cubeSize * p1_CurrentCell.c;
                        handleObstruction();
                        handleComputerPos();
                    }else{
                        trace("Blocked")
                    }
                break;
                case 39:
                //right
                    if(p1_CurrentCell.c <=  _boardMatrix[0].length-2 && _boardMatrix[(p1_CurrentCell.r)][(p1_CurrentCell.c)+1].t == 1){
                        p1_CurrentCell = _boardMatrix[(p1_CurrentCell.r)][(p1_CurrentCell.c)+1];
                        _p1_AvatarSphere.z = _cubeSize * p1_CurrentCell.r;
                        _p1_AvatarSphere.x = _cubeSize * p1_CurrentCell.c;
                        handleObstruction();
                        handleComputerPos();
                    }else{
                            trace("Blocked")
                    }
                break;
                case 38:
                    //up
                    //check to see if you could advance
                    if((p1_CurrentCell.r) >  0 && _boardMatrix[(p1_CurrentCell.r)-1][(p1_CurrentCell.c)].t == 1){
                        p1_CurrentCell = _boardMatrix[(p1_CurrentCell.r)-1][(p1_CurrentCell.c)];
                        _p1_AvatarSphere.z = _cubeSize * p1_CurrentCell.r;
                        _p1_AvatarSphere.x = _cubeSize * p1_CurrentCell.c;
                        handleObstruction();
                        handleComputerPos();
                    }else{
                        trace("Blocked")
                    }
                break;
                case 37:
                //left
                    if(p1_CurrentCell.c > 0 && _boardMatrix[(p1_CurrentCell.r)][(p1_CurrentCell.c)-1].t == 1){
                        p1_CurrentCell = _boardMatrix[(p1_CurrentCell.r)][(p1_CurrentCell.c)-1];
                        _p1_AvatarSphere.z = _cubeSize * p1_CurrentCell.r;
                        _p1_AvatarSphere.x = _cubeSize * p1_CurrentCell.c;
                        handleObstruction();
                        handleComputerPos();
                    }else{
                        trace("Blocked")
                    }
                break;
            }
            
            //TEMP
            
        }
        
        
        
    
        
        
        private function createChildren():void{
            _floorDipObj = new ObjectContainer3D();
            view.scene.addChild(_floorDipObj);
            
            _wallsDipObj = new ObjectContainer3D();
            view.scene.addChild(_wallsDipObj);
            
            _playersDipObj = new ObjectContainer3D();
            view.scene.addChild(_playersDipObj);
            
            _obstructDipObj = new ObjectContainer3D();
            view.scene.addChild(_obstructDipObj);
            
            _outputTxt = new TextField();
            _outputTxt.width = 500;
            _outputTxt.height = 200;
            _outputTxt.x = 100;
            this.addChild(_outputTxt)
            buildBoard();
        }
        
        
        //layout entire floor grid based on tile matrix
        private function buildBoard():void{
            //figure out x & y tile counts
            var xBlockCount:Number = _boardMatrix[0].length;
            var yBlockCount:Number = _boardMatrix.length;
            
            //loop through matrix and place tiles
            for(var x:String in _boardMatrix){
                var internalTiles:Array = _boardMatrix[x];
                
                for(var y:String in internalTiles){
                    
                    //decide what type of tile needs to be placed
                    switch(internalTiles[y].t){
                        case 1:
                            
                            var floormat:BitmapMaterial=new BitmapMaterial(Cast.bitmap(FloorImg));
                            var floorCube:Plane = new Plane({material:floormat, width:_cubeSize, height:_cubeSize});
                            floorCube.pushback = true;
                            floorCube.z = _cubeSize * Number(x);
                            floorCube.rotationX = 180;
                            floorCube.x = _cubeSize * Number(y);
                            _floorDipObj.addChild(floorCube)
                
                            var clearSpace:Object = new Object();
                            clearSpace.x = x;
                            clearSpace.y = y;
                            _clearSpaces.push(clearSpace)
                        break;
                        case 2:
                        
                            var wallmat:BitmapMaterial=new BitmapMaterial(Cast.bitmap(WallImg));
                            var wallCube:Cube = new Cube({material:wallmat});
                            wallCube.pushfront = true;
                            wallCube.z = _cubeSize * Number(x);
                            wallCube.x = _cubeSize * Number(y);
                            wallCube.y = (_cubeSize/2)*-1;
                            wallCube.width = _cubeSize;
                            wallCube.height = _cubeSize;
                            wallCube.depth = _cubeSize;
                            _wallsDipObj.addChild(wallCube)
                        break;
                    }
                    
                }
            }
            var evt:Event = new Event("boardComplete")
            this.dispatchEvent(evt);
        }
        
        private function addPlayers(evt:Event):void{
            
            _p1_AvatarSphere = new Sphere();
            _p1_AvatarSphere.pushfront = true;
            _p1_AvatarSphere.z = _cubeSize * p1_CurrentCell.r;
            _p1_AvatarSphere.x = _cubeSize * p1_CurrentCell.c;
            _p1_AvatarSphere.y = ((_cubeSize/2)*-1)-10;
            _p1_AvatarSphere.radius = (_cubeSize/2);
            _playersDipObj.addChild(_p1_AvatarSphere)
            
            _p2_AvatarSphere = new Sphere();
            _p2_AvatarSphere.pushfront = true;
            _p2_AvatarSphere.z = _cubeSize * p2_CurrentCell.r;
            _p2_AvatarSphere.x = _cubeSize * p2_CurrentCell.c;
            _p2_AvatarSphere.y = ((_cubeSize/2)*-1)-10;
            _p2_AvatarSphere.radius = (_cubeSize/2);;
            _playersDipObj.addChild(_p2_AvatarSphere)
        }
        
        
        private function handleObstruction(evtObj:MouseEvent = null):void{
            //GET RANDOM VALUE
            var randomBlockIndex:Number = Math.floor(Math.random() * _clearSpaces.length);
            var wallmat=new BitmapMaterial(Cast.bitmap(WallImg));
            var obstructionBlock:Cube = new Cube({material:wallmat});
            obstructionBlock.z = _cubeSize * Number(_clearSpaces[randomBlockIndex].y);
            obstructionBlock.x = _cubeSize * Number(_clearSpaces[randomBlockIndex].x);
            obstructionBlock.y = ((_cubeSize/2)*-1);
            obstructionBlock.width = _cubeSize;
            obstructionBlock.height = _cubeSize;
            obstructionBlock.depth = _cubeSize;
            obstructionBlock.pushfront = true;
            _obstructDipObj.addChild(obstructionBlock);
            
            var newBlock = _boardMatrix[Number(_clearSpaces[randomBlockIndex].y)][Number(_clearSpaces[randomBlockIndex].x)];
            newBlock.t = 2;
            
            
            if(newBlock == p1_CurrentCell){
                _outputTxt.text = "You Got Killed";
            }
            
            if(newBlock == p2_CurrentCell){
                _outputTxt.text = "Computer got killed";
            }
            
            
            
            //check to see if all your paths are blocked off
            var nearestPath = getPath(p1_CurrentCell,p1_EndCell);
            
            if(nearestPath.length == 1){
                if(p1_CurrentCell == p1_EndCell){
                    _outputTxt.text = "You Win!";
                }else{
                    _outputTxt.text = "GAME OVER, YOUR PATH HAS BEEN BLOCKED";
                }
            }
            
        }
        
        private function moveComputer(newPath:Array):void{
            p2_CurrentCell = _boardMatrix[newPath[1].r][newPath[1].c];
            _p2_AvatarSphere.z = _cubeSize * newPath[1].r;
            _p2_AvatarSphere.x = _cubeSize * newPath[1].c;
        }
        
        
        private function getPath(currentCell, endCell):Array{
            _pathFinder = new Path(_boardMatrix);
            return _pathFinder.findPath(currentCell,endCell);
        }
        
        
        private function handleComputerPos(evt:MouseEvent = null):void{
            try{
                moveComputer(getPath(p2_CurrentCell,p2_EndCell));
            }catch(err:Error){
                if(p2_CurrentCell == p2_EndCell){
                    _outputTxt.text = "You Lose!";
                }else{
                    _outputTxt.text = "COMPUTER IS BLOCKED, YOU WIN";
                }
            }
            
        }
        
        
    }
}