/// <summary>
    /// Levels are defined by a JSON file, this method parses that file and loads the level information into memory
    /// </summary>
    private void LevelLoad()
    {
        BotController bController = actualBotGO.GetComponent <BotController> ();
        TextAsset     levelJson   = Resources.Load <TextAsset> (listManager.chosenLevelUrl);

        levelDefinition = new LevelDefinition();

        var levelD = JSON.Parse(levelJson.text);

        if (levelD != null)
        {
            levelDefinition.name       = levelD ["name"];
            levelDefinition.maxScore   = levelD ["maxScore"];
            levelDefinition.numRows    = levelD ["numRows"];
            levelDefinition.numColumns = levelD ["numColumns"];
            levelDefinition.botPos     = new Vector2(levelD ["botPos"] ["x"].AsInt, levelD ["botPos"] ["y"].AsInt);

            levelDefinition.board = new Tile[levelDefinition.numRows, levelDefinition.numColumns];

            for (int i = 0; i < levelDefinition.numRows; i++)
            {
                for (int j = 0; j < levelDefinition.numColumns; j++)
                {
                    Tile t = new Tile();

                    t.setInfo(levelD ["board"] [i] [j] ["height"].AsInt,
                              levelD ["board"] [i] [j] ["lightable"].AsBool,
                              new Vector2(levelD ["board"] [i] [j] ["position"] ["x"].AsInt, levelD ["board"] [i] [j] ["position"] ["y"].AsInt));

                    levelDefinition.board [i, j] = t;
                }
            }
        }

        int opAmount = levelD ["availableOps"].AsArray.Count;

        for (int i = 0; i < opAmount; i++)
        {
            var    op   = levelD ["availableOps"] [i];
            string name = op ["name"];

            switch (name)
            {
            case "FWD":
                bController.AddOperation(new ForwardOperation(), false, false, "FWD");
                uiManager.EnableOp(name);
                break;

            case "TL":
                bController.AddOperation(new TurnLeftOperation(), false, false, "TL");
                uiManager.EnableOp(name);
                break;

            case "TR":
                bController.AddOperation(new TurnRightOperation(), false, false, "TR");
                uiManager.EnableOp(name);
                break;

            case "JMP":
                bController.AddOperation(new JumpOperation(), false, false, "JMP");
                uiManager.EnableOp(name);
                break;

            case "LGHT":
                bController.AddOperation(new LightOperation(), false, false, "LGHT");
                uiManager.EnableOp(name);
                break;

            case "Main":
                CompositeOperation compOp = new CompositeOperation();
                compOp.limit = op ["limit"].AsInt;
                compOp.name  = "Main";
                bController.AddOperation(compOp, true, true, "Main");
                uiManager.EnableBlock(name, op["limit"].AsInt);
                break;

            default:
                //  If the operation is not one of the above it means that it's a function (or an unknown operation which isn't good)
                if (op ["type"].Value == "Composite")
                {
                    CompositeOperation comp = new CompositeOperation();
                    comp.limit = op ["limit"].AsInt;
                    comp.name  = op ["name"];
                    bController.AddOperation(comp, false, true, op ["name"]);
                    uiManager.EnableBlock(name, op["limit"].AsInt);
                    uiManager.EnableOp(name);
                }
                break;
            }
        }

        bController.LevelDef          = levelDefinition.Clone();
        bController.LevelDef.maxScore = levelDefinition.maxScore;

        Resources.UnloadAsset(levelJson);

        //Debug.Log (levelDefinition.ToString());
    }