private void HandleTreasureMode()
        {
            if (treasurePathQueue.Count == 0) {
                // switch mode
                mode = ModeEnum.EXPLORING;
                npAgentGameMode = Stage.GameMode.NP_AGENT_EXPLORING;

                // resume to previous exploring path if any
                if (previousPath != null && !previousPath.Done) {
                    currentPath = previousPath;
                    // nextGoal = currentPath.NextNode;
                    // agentObject.TurnToFace(nextGoal.Translation);
                }
                else {
                    HandleExploringMode();
                }
            }
            else {
                // get another path from treasure path queue
                currentPath = treasurePathQueue.Dequeue();
                // add path to stage two show trace
                stage.Components.Add(currentPath);
                // get first path goal
                nextGoal = currentPath.NextNode;
                // orient towards the first path goal
                agentObject.TurnToFace(nextGoal.Translation);
            }
        }
 private void HandleExploringMode()
 {
     if (explorePathQueue.Count == 0) {
         done = true;
         npAgentGameMode = Stage.GameMode.NP_AGENT_TREASURE_STOP;
     }
     else {
         // get another path from explore path queue
         currentPath = explorePathQueue.Dequeue();
         // get first path goal
         nextGoal = currentPath.NextNode;
         // orient towards the first path goal
         agentObject.TurnToFace(nextGoal.Translation);
     }
 }
        /// <summary>
        /// Here we allow switching from regular path to treasure path if only if 
        /// the treasure path is not done, otherwise it will do nothing (disable)
        /// </summary>
        private void ChangeToTreasurePath(int idx)
        {
            AddNewTreasurePath(idx);

            // save the previous path if any
            if (mode == ModeEnum.EXPLORING) {
                if (!currentPath.Done) {
                    previousPath = currentPath;
                }
            }

            // update the mode
            mode = ModeEnum.TREASURE_HUNTING;
            // set new path
            currentPath = treasurePathQueue.Dequeue();
            // add path to stage
            stage.Components.Add(currentPath);
            // get the first target
            nextGoal = currentPath.NextNode;
            // orient towards the first path goal
            agentObject.TurnToFace(nextGoal.Translation);
        }
        /// <summary>
        /// Create exploring path using A* algorithm
        /// to avoid collision
        /// </summary>
        private void AddPathToExploreQueue()
        {
            /**
            *      We move as follows
            *           + path:
            *                   s -> x1 -> x2 -> x3 -> x4 -> ...
            *
            *           + direction:
            *                   right -> down -> right -> up -> right -> down ....
            *
            *           + cover an rectangle area of 52 * spacing since the distance
            *             of seeing is 4000 pixles = 26 * 150
            *
            *        =================
            *        = Map 512 x 512 =
            *        =================
            *
            *                  100          200          300          400          500
            *      ------------|------------|------------|------------|------------|
            *      |                                                               |
            *      | s ------> x1          x4 ----------->                         |
            *      |           |            ^            .                         |
            *      |           |            |            .                         |
            *  100 -           |            |            .                         |
            *      |           |            |            .                         |
            *      |           |            |                                      |
            *      |           |            |                                      |
            *      |           |            |                                      |
            *  200 -           |            |                                      |
            *      |           |            |                                      |
            *      |           |            |                                      |
            *      |           |            |                                      |
            *      |           |            |                                      |
            *  300 -           |            |                                      |
            *      |           |            |                                      |
            *      |           |            |                                      |
            *      |           |            |                                      |
            *      |           |            |                                      |
            *  400 -           |            |                                      |
            *      |           |            |                                      |
            *      |           V            |                                      |
            *      |           x2 ----------> x3                                   |
            *      |                                                               |
            *  500 -----------------------------------------------------------------
            *
            */
            Vector3 start = new Vector3(0, 0, 0);
            Vector3 goal = new Vector3(0, 0, 0);

            Vector3 x0  = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 78),   78  * stage.Spacing);
            Vector3 x1  = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 130),  130 * stage.Spacing);
            Vector3 x2  = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 182),  182 * stage.Spacing);
            Vector3 x3  = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 234),  234 * stage.Spacing);
            Vector3 x4  = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 286),  286 * stage.Spacing);
            Vector3 x5  = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 338),  338 * stage.Spacing);
            Vector3 x6  = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 390),  390 * stage.Spacing);
            Vector3 x7  = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 442),  442 * stage.Spacing);
            Vector3 x8  = new Vector3(26 * stage.Spacing, stage.SurfaceHeight(26, 494),  494 * stage.Spacing);

            Vector3 z0  = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 26),   26  * stage.Spacing);
            Vector3 z1  = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 78),   78  * stage.Spacing);
            Vector3 z2  = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 130),  130 * stage.Spacing);
            Vector3 z3  = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 182),  182 * stage.Spacing);
            Vector3 z4  = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 234),  234 * stage.Spacing);
            Vector3 z5  = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 286),  286 * stage.Spacing);
            Vector3 z6  = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 338),  338 * stage.Spacing);
            Vector3 z7  = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 390),  390 * stage.Spacing);
            Vector3 z8  = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 442),  442 * stage.Spacing);
            Vector3 z9  = new Vector3(486 * stage.Spacing, stage.SurfaceHeight(486, 494),  494 * stage.Spacing);

            /*
             * Debugging only to show path pattern
             */
            bool ifDebug = false;
            bool displayPath = ifDebug;

            // right
            start = z0; goal = z1;
            Path p1 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug) {
                stage.Components.Add(p1);
            }
            explorePathQueue.Enqueue(p1);

            // down
            start = z1; goal = x0;
            Path p2 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug) {
                stage.Components.Add(p2);
            }
            explorePathQueue.Enqueue(p2);

            // right
            start = x0; goal = x1;
            Path p3 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug) {
                stage.Components.Add(p3);
            }
            explorePathQueue.Enqueue(p3);

            // up
            start = x1; goal = z2;
            Path p4 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug) {
                stage.Components.Add(p4);
            }
            explorePathQueue.Enqueue(p4);

            // right
            start = z2; goal = z3;
            Path p5 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug) {
                stage.Components.Add(p5);
            }
            explorePathQueue.Enqueue(p5);

            // down
            start = z3; goal = x2;
            Path p6 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug) {
                stage.Components.Add(p6);
            }
            explorePathQueue.Enqueue(p6);

            // right
            start = x2; goal = x3;
            Path p7 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug) {
                stage.Components.Add(p7);
            }
            explorePathQueue.Enqueue(p7);

            // up
            start = x3; goal = z4;
            Path p8 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug) {
                stage.Components.Add(p8);
            }
            explorePathQueue.Enqueue(p8);

            // right
            start = z4; goal = z5;
            Path p9 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug) {
                stage.Components.Add(p9);
            }
            explorePathQueue.Enqueue(p9);

            // down
            start = z5; goal = x4;
            Path p10 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug) {
                stage.Components.Add(p10);
            }
            explorePathQueue.Enqueue(p10);

            // right
            start = x4; goal = x5;
            Path p11 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug)
                stage.Components.Add(p11);
            explorePathQueue.Enqueue(p11);

            // up
            start = x5; goal = z6;
            Path p12 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug)
                stage.Components.Add(p12);
            explorePathQueue.Enqueue(p12);

            // right
            start = z6; goal = z7;
            Path p13 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug)
                stage.Components.Add(p13);
            explorePathQueue.Enqueue(p13);

            // down
            start = z7; goal = x6;
            Path p14 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug)
                stage.Components.Add(p14);
            explorePathQueue.Enqueue(p14);

            // right
            start = x6; goal = x7;
            Path p15 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug)
                stage.Components.Add(p15);
            explorePathQueue.Enqueue(p15);

            // up
            start = x7; goal = z8;
            Path p16 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug)
                stage.Components.Add(p16);
            explorePathQueue.Enqueue(p16);

            // right
            start = z8; goal = z9;
            Path p17 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug)
                stage.Components.Add(p17);
            explorePathQueue.Enqueue(p17);

            // down
            start = z9; goal = x8;
            Path p18 = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.WAYPOINT), Path.PathType.SINGLE, displayPath);
            if (ifDebug)
                stage.Components.Add(p18);
            explorePathQueue.Enqueue(p18);
        }
        /// <summary>
        /// Build an A* path to treasure
        /// and add it to the treasure path queue
        /// </summary>
        /// <param name="idx">index of treasure</param>
        private void AddNewTreasurePath(int idx)
        {
            // build A* path to goal
            int startX = (int)(agentObject.Translation.X / 150);
            int startZ = (int)(agentObject.Translation.Z / 150);
            int goalX = (int)(stage.Treasures[idx].Translation.X / 150);
            int goalZ = (int)(stage.Treasures[idx].Translation.Z / 150);

            Vector3 start =
                new Vector3(startX * stage.Terrain.Spacing, stage.Terrain.SurfaceHeight(startX, startZ), startZ * stage.Terrain.Spacing);
            Vector3 goal =
                new Vector3(goalX * stage.Terrain.Spacing, stage.Terrain.SurfaceHeight(goalX, goalZ), goalZ * stage.Terrain.Spacing);

            // create A* path forward to treasure
            Path forwardPath = new Path(stage, MakeAStarPath(start, goal, NavNode.NavNodeEnum.A_STAR), Path.PathType.SINGLE, true);
            // add this path to queue
            treasurePathQueue.Enqueue(forwardPath);

            // create A* path backward to previous position
            if (goalX == LocationConstant.TREASURE_1_X && goalZ == LocationConstant.TREASURE_1_Z) {
                Path backwardPath = new Path(stage, MakeAStarPath(goal, start, NavNode.NavNodeEnum.PATH), Path.PathType.SINGLE, true);
                // add this path to queue
                treasurePathQueue.Enqueue(backwardPath);
            }
        }
        /// <summary>
        /// Create a NPC. 
        /// AGXNASK distribution has npAgent move following a Path.
        /// </summary>
        /// <param name="theStage"> the world</param>
        /// <param name="label"> name of </param>
        /// <param name="pos"> initial position </param>
        /// <param name="orientAxis"> initial rotation axis</param>
        /// <param name="radians"> initial rotation</param>
        /// <param name="meshFile"> Direct X *.x Model in Contents directory </param>
        public NPAgent(Stage theStage, string label, Vector3 pos, Vector3 orientAxis, float radians, string meshFile)
            : base(theStage, label, pos, orientAxis, radians, meshFile)
        {
            IsCollidable = true;

            first.Name = "npFirst";
            follow.Name = "npFollow";
            above.Name = "npAbove";

            // initialize all treasures
            InitializeMarkTreasures();

            // initialize treasure path queue
            treasurePathQueue = new Queue<Path>();
            // initialize exploring path queue
            explorePathQueue = new Queue<Path>();

            // add all predefined path to explore path queue
            // AddPathToExploreQueue();

            Path initialPath = new Path(stage, MakeExploringPaths(), Path.PathType.SINGLE, true);

             // set it to current path
            currentPath = initialPath;

            // set the mode
            mode = ModeEnum.EXPLORING;
            npAgentGameMode = Stage.GameMode.NP_AGENT_EXPLORING;

            stage.Components.Add(currentPath);
            nextGoal = currentPath.NextNode;
            agentObject.TurnToFace(nextGoal.Translation);
        }