public bool PuzzleInit()
        {
            dispatcher.DispatchEvent(new UIDisablerEvents.DisableUIElement("Joystick"));
            rectTransform = GetComponent <RectTransform>();
            rectTransform.localPosition = new Vector3(0f, 0f, -100f);
            swipeThreshold = Screen.dpi * 0.4f;
            if (swipeThreshold <= 0f)
            {
                swipeThreshold = 50f;
            }
            focusObj            = null;
            oldFocus            = null;
            hasInitalizedPuzzle = false;
            isSolved            = false;
            pieceCount          = 0;
            solveCount          = 0;
            hasMadeMove         = false;
            isTap = false;
            solveObjects.Clear();
            moveableObjects.Clear();
            settings = base.gameObject.GetComponentInParent <BlockAndLockSettings>();
            if (settings == null)
            {
                throw new MissingComponentException("Could not find BlockAndLockSettings component");
            }
            UnityEngine.Object.Instantiate(settings.AudioPrefab, base.transform);
            settings.MarkerTopLeft.SetActive(value: false);
            settings.MarkerBottomRight.SetActive(value: false);
            gameBoard = new BlockAndLockBoardData[settings.GridWidth, settings.GridHeight];
            for (int i = 0; i < settings.GridHeight; i++)
            {
                for (int j = 0; j < settings.GridWidth; j++)
                {
                    gameBoard[j, i] = new BlockAndLockBoardData(PieceCategory.Empty, 0);
                }
            }
            for (int k = 0; k < maxPieces; k++)
            {
                prevBoardData[k] = new BlockAndLockBoardData(PieceCategory.Empty, 0);
            }
            bkgArtworkObj = base.gameObject.transform.Find("Common/Bkg common").gameObject;
            if (checkWasFound(bkgArtworkObj, "common background artwork"))
            {
                bkgArtworkColl = bkgArtworkObj.GetComponent <Collider>();
                if (bkgArtworkColl == null)
                {
                    Log.LogError(this, $"BlockAndLock -  could not find collider on background artwork");
                    return(false);
                }
                bkgArtworkObj.layer = LayerMask.NameToLayer("UI");
            }
            beginArtworkObj = base.gameObject.transform.Find("Begin/Begin artwork").gameObject;
            if (checkWasFound(beginArtworkObj, "beginning artwork"))
            {
                beginArtworkObj.layer = LayerMask.NameToLayer("UI");
            }
            completedArtworkObj = base.gameObject.transform.Find("Completed/Completed Artwork").gameObject;
            if (checkWasFound(completedArtworkObj, "completed artwork"))
            {
                completedArtworkObj.layer = LayerMask.NameToLayer("UI");
                completedArtworkObj.SetActive(value: false);
            }
            completedAnchorObj = base.gameObject.transform.Find("Completed/Completed particles anchor").gameObject;
            if (checkWasFound(completedAnchorObj, "Completed particles anchor"))
            {
                completedAnchorObj.layer = LayerMask.NameToLayer("UI");
            }
            restartButton = base.gameObject.transform.Find("RestartBtn").gameObject;
            if (checkWasFound(restartButton, "restart button"))
            {
                restartButton.layer = LayerMask.NameToLayer("UI");
                restartButton.SetActive(value: false);
                fieldRestart = restartButton.GetComponentInChildren <Text>();
                if (checkWasFound(fieldRestart, "text field on the restart button"))
                {
                    if (string.IsNullOrEmpty(settings.RestartToken))
                    {
                        throw new Exception("BlockAndLock - token for Restart text must be set");
                    }
                    fieldRestart.text = Service.Get <Localizer>().GetTokenTranslation(settings.RestartToken).ToUpper();
                }
            }
            arrowContainer = base.gameObject.transform.Find("Arrows");
            if (checkWasFound(arrowContainer, "arrow container"))
            {
                foreach (Transform item in arrowContainer)
                {
                    GameObject gameObject = item.transform.gameObject;
                    if (uniqueNames.Contains(gameObject.name))
                    {
                        Log.LogError(this, $"Found duplicate arrow piece '{gameObject.name}'. Please make them unique");
                        return(false);
                    }
                    if (gameObject.name == "ArrowLeft")
                    {
                        arrowLeft = gameObject;
                    }
                    else if (gameObject.name == "ArrowRight")
                    {
                        arrowRight = gameObject;
                    }
                    else if (gameObject.name == "ArrowUp")
                    {
                        arrowUp = gameObject;
                    }
                    else
                    {
                        if (!(gameObject.name == "ArrowDown"))
                        {
                            Log.LogError(this, $"Piece '{gameObject.name}' is not an expected name. Please rename or delete it");
                            return(false);
                        }
                        arrowDown = gameObject;
                    }
                    uniqueNames.Add(gameObject.name);
                    if (gameObject.GetComponent <Collider>() == null)
                    {
                        gameObject.AddComponent <BoxCollider>();
                    }
                    BlockAndLockPiece blockAndLockPiece = gameObject.GetComponent <BlockAndLockPiece>();
                    gameObject.layer = LayerMask.NameToLayer("UI");
                    if (blockAndLockPiece == null)
                    {
                        blockAndLockPiece = gameObject.AddComponent <BlockAndLockPiece>();
                    }
                    blockAndLockPiece.Init(PieceCategory.Arrow);
                }
            }
            solveContainer = base.gameObject.transform.Find("Solve Positions");
            int result;

            if (checkWasFound(solveContainer, "solve container"))
            {
                foreach (Transform item2 in solveContainer)
                {
                    GameObject gameObject = item2.transform.gameObject;
                    if (uniqueNames.Contains(gameObject.name))
                    {
                        Log.LogError(this, $"'{gameObject.name}'. Please make them unique");
                        return(false);
                    }
                    Grid2 grid = PositionToGrid(gameObject.transform.localPosition.x, gameObject.transform.localPosition.y);
                    if (gameBoard[grid.x, grid.y].Category != 0)
                    {
                        Log.LogError(this, $"'{gameObject.name}' can't go into grid position ({grid.x}, {grid.y}), it's not empty.");
                        return(false);
                    }
                    uniqueNames.Add(gameObject.name);
                    Match match = Regex.Match(gameObject.name, "\\(([0-9]+)\\)", RegexOptions.None);
                    if (match.Success)
                    {
                        if (!int.TryParse(match.Groups[1].Value, out result))
                        {
                            Log.LogError(this, string.Format("'{0}' cannot parse matched value of (1)'.", gameObject.name, match.Groups[1].Value));
                            return(false);
                        }
                        gameBoard[grid.x, grid.y] = new BlockAndLockBoardData(PieceCategory.SolvePosition, result);
                        if (gameObject.GetComponent <Collider>() == null)
                        {
                            gameObject.AddComponent <BoxCollider>();
                        }
                        gameObject.layer = LayerMask.NameToLayer("UI");
                        solveObjects.Add(result, gameObject);
                        BlockAndLockPiece blockAndLockPiece = gameObject.GetComponent <BlockAndLockPiece>();
                        if (blockAndLockPiece == null)
                        {
                            blockAndLockPiece = gameObject.AddComponent <BlockAndLockPiece>();
                        }
                        blockAndLockPiece.Init(PieceCategory.SolvePosition);
                        continue;
                    }
                    Log.LogError(this, string.Format("'{0}' doesn't have an id, should be named like 'SolvedPostion (1)'.", gameObject.name, grid.x, grid.y));
                    return(false);
                }
            }
            moveableContainer = base.gameObject.transform.Find("Moveable Positions");
            if (moveableContainer == null)
            {
                Log.LogError(this, $"could not find moveable container object");
                return(false);
            }
            foreach (Transform item3 in moveableContainer)
            {
                GameObject gameObject = item3.transform.gameObject;
                if (uniqueNames.Contains(gameObject.name))
                {
                    Log.LogError(this, $"Found duplicate start piece '{gameObject.name}'. Please make them unique");
                    return(false);
                }
                Grid2 grid = PositionToGrid(gameObject.transform.localPosition.x, gameObject.transform.localPosition.y);
                if (gameBoard[grid.x, grid.y].Category != 0)
                {
                    Log.LogError(this, $"'{gameObject.name}' can't go into grid position ({grid.x}, {grid.y}), it's not empty.");
                    return(false);
                }
                uniqueNames.Add(gameObject.name);
                Match match = Regex.Match(gameObject.name, "\\(([0-9]+)\\)", RegexOptions.None);
                if (match.Success)
                {
                    if (!int.TryParse(match.Groups[1].Value, out result))
                    {
                        Log.LogError(this, string.Format("'{0}' cannot parse matched value of (1)'.", gameObject.name, match.Groups[1].Value));
                        return(false);
                    }
                    gameBoard[grid.x, grid.y] = new BlockAndLockBoardData(PieceCategory.MoveableObject, result);
                    if (gameObject.GetComponent <Collider>() == null)
                    {
                        gameObject.AddComponent <BoxCollider>();
                    }
                    gameObject.layer = LayerMask.NameToLayer("UI");
                    moveableObjects.Add(result, gameObject);
                    BlockAndLockPiece blockAndLockPiece = gameObject.GetComponent <BlockAndLockPiece>();
                    if (blockAndLockPiece == null)
                    {
                        blockAndLockPiece = gameObject.AddComponent <BlockAndLockPiece>();
                    }
                    blockAndLockPiece.Init(PieceCategory.MoveableObject);
                    continue;
                }
                Log.LogError(this, string.Format("'{0}' doesn't have an id, should be named like 'StartPostion (1)'.", gameObject.name, grid.x, grid.y));
                return(false);
            }
            obstacleContainer = base.gameObject.transform.Find("Obstacle Positions");
            if (obstacleContainer == null)
            {
                Log.LogError(this, $"could not find obstacle container");
                return(false);
            }
            foreach (Transform item4 in obstacleContainer)
            {
                GameObject gameObject = item4.transform.gameObject;
                if (uniqueNames.Contains(gameObject.name))
                {
                    Log.LogError(this, $"Found duplicate obstacle piece '{gameObject.name}'. Please make them unique");
                    return(false);
                }
                Grid2 grid = PositionToGrid(gameObject.transform.localPosition.x, gameObject.transform.localPosition.y);
                if (gameBoard[grid.x, grid.y].Category != 0)
                {
                    Log.LogError(this, $"'{gameObject.name}' can't go into grid position ({grid.x}, {grid.y}), it's not empty.");
                    return(false);
                }
                uniqueNames.Add(gameObject.name);
                Match match = Regex.Match(gameObject.name, "\\(([0-9]+)\\)", RegexOptions.None);
                if (match.Success)
                {
                    if (!int.TryParse(match.Groups[1].Value, out result))
                    {
                        Log.LogError(this, string.Format("'{0}' cannot parse matched value of (1)'.", gameObject.name, match.Groups[1].Value));
                        return(false);
                    }
                    gameBoard[grid.x, grid.y] = new BlockAndLockBoardData(PieceCategory.Obstacle, result);
                    if (gameObject.GetComponent <Collider>() == null)
                    {
                        gameObject.AddComponent <BoxCollider>();
                    }
                    gameObject.layer = LayerMask.NameToLayer("UI");
                    BlockAndLockPiece blockAndLockPiece = gameObject.GetComponent <BlockAndLockPiece>();
                    if (blockAndLockPiece == null)
                    {
                        blockAndLockPiece = gameObject.AddComponent <BlockAndLockPiece>();
                    }
                    blockAndLockPiece.Init(PieceCategory.Obstacle);
                    continue;
                }
                Log.LogError(this, string.Format("'O_o\t BlockAndLockController.Start: ''{0}' doesn't have an id, should be named like 'ObstaclePostion (1)'.", gameObject.name, grid.x, grid.y));
                return(false);
            }
            if (moveableObjects.Count != solveObjects.Count)
            {
                Log.LogError(this, $"the number of moveable positions and solve positions must match ({moveableObjects.Count} != {solveObjects.Count})");
                return(false);
            }
            pieceCount = solveObjects.Count;
            guiCam     = GameObject.Find("PopupCamera").GetComponentInChildren <Camera>();
            if (guiCam == null)
            {
                Log.LogError(this, $"Can't find the GUI camera");
                return(false);
            }
            CalculateScreenExtents();
            gameBoardSaved = new BlockAndLockBoardData[settings.GridWidth, settings.GridHeight];
            for (int i = 0; i < settings.GridHeight; i++)
            {
                for (int j = 0; j < settings.GridWidth; j++)
                {
                    gameBoardSaved[j, i] = gameBoard[j, i];
                }
            }
            touchPositionOrigin = INVALID_COORDINATE;
            hasInitalizedPuzzle = true;
            return(true);
        }
        public void Init(PieceCategory category)
        {
            if (SpriteNormal == null)
            {
                Log.LogError(null, $"O_o\t BlockAndLockPiece: ERROR -- Normal sprite name must be set on {base.gameObject.name}");
                return;
            }
            if (SpriteSelected == null)
            {
                Log.LogError(null, $"O_o\t BlockAndLockPiece: ERROR -- Selected sprite name must be set on {base.gameObject.name}");
                return;
            }
            if (SpriteLocked == null)
            {
                Log.LogError(null, $"O_o\t BlockAndLockPiece: ERROR -- Locked sprite name must be set on {base.gameObject.name}");
                return;
            }
            rend = base.gameObject.GetComponent <SpriteRenderer>();
            if (rend == null)
            {
                Log.LogError(null, $"O_o\t BlockAndLockPiece: ERROR -- Could not find SpriteRenderer component on {base.gameObject.name}");
                return;
            }
            settings = base.gameObject.GetComponentInParent <BlockAndLockSettings>();
            if (settings == null)
            {
                Log.LogError(null, $"O_o\t BlockAndLockPiece: ERROR -- Could not find settings component");
                return;
            }
            Category = category;
            switch (Category)
            {
            case PieceCategory.Obstacle:
                base.gameObject.SetActive(value: true);
                break;

            case PieceCategory.SolvePosition:
                base.gameObject.SetActive(value: true);
                break;

            case PieceCategory.MoveableObject:
                base.gameObject.SetActive(value: true);
                break;

            case PieceCategory.Arrow:
                base.gameObject.SetActive(value: false);
                break;
            }
            if (particleObj != null)
            {
                GameObject gameObject = Object.Instantiate(particleObj, base.gameObject.transform);
                gameObject.transform.localPosition = Vector3.zero;
                gameObject.transform.localScale    = Vector2.one;
                gameObject.layer = LayerMask.NameToLayer("UI");
                particleSys      = gameObject.GetComponent <ParticleSystem>();
                if (particleSys != null)
                {
                    particleSys.SetStartColor(particleColour);
                }
            }
        }