private TouchPhaseExtended getTouchPhase(out Vector3 touchPosition)
        {
            TouchPhaseExtended touchPhaseExtended = TouchPhaseExtended.NoEvent;

            touchPhaseExtended = ((!InputWrapper.GetMouseButtonDown(0)) ? (InputWrapper.GetMouseButton(0) ? TouchPhaseExtended.Moved : ((!InputWrapper.GetMouseButtonUp(0)) ? TouchPhaseExtended.Mouse : TouchPhaseExtended.Ended)) : TouchPhaseExtended.Began);
            if (UnityEngine.Input.touchSupported && InputWrapper.touchCount > 0)
            {
                touchPhaseExtended = (TouchPhaseExtended)InputWrapper.GetTouch(0).phase;
                touchPosition      = InputWrapper.GetTouch(0).position;
            }
            else
            {
                touchPosition = InputWrapper.mousePosition;
            }
            return(touchPhaseExtended);
        }
        private void Update()
        {
            if (!hasInitalizedPuzzle || isSolved || isMoving || isRestarting || isClosing)
            {
                return;
            }
            Vector3            touchPosition;
            TouchPhaseExtended touchPhaseExtended = getTouchPhase(out touchPosition);

            if (moveableObjects.Count == 1 && !isAutoSelectDone)
            {
                touchPhaseExtended = TouchPhaseExtended.Ended;
                foreach (KeyValuePair <int, GameObject> moveableObject in moveableObjects)
                {
                    focusObj = moveableObject.Value;
                }
                previousSelection = null;
                isAutoSelectDone  = true;
                touchPosition     = (oldPos = focusObj.transform.position);
            }
            RaycastHit hitInfo;

            switch (touchPhaseExtended)
            {
            case TouchPhaseExtended.Began:
                isTap = false;
                if (touchPositionOrigin == INVALID_COORDINATE)
                {
                    touchPositionOrigin = touchPosition;
                }
                oldPos   = touchPosition;
                focusHit = GetPixelHit(touchPosition);
                if (focusHit.collider != null)
                {
                    focusObj = focusHit.collider.gameObject;
                }
                else
                {
                    focusObj = null;
                }
                if (focusObj != oldFocus)
                {
                    if (oldFocus != null)
                    {
                        BlockAndLockPiece component = oldFocus.GetComponent <BlockAndLockPiece>();
                        component.PixelMouseExit();
                    }
                    if (focusObj != null)
                    {
                        BlockAndLockPiece component = focusObj.GetComponent <BlockAndLockPiece>();
                        component.PixelMouseOver();
                    }
                    oldFocus = focusObj;
                }
                if (focusObj != null && bkgArtworkColl.Raycast(guiCam.ScreenPointToRay(touchPosition), out hitInfo, 500f))
                {
                    pickupOffset   = focusObj.transform.position - hitInfo.point;
                    pickupOffset.z = 0f;
                }
                break;

            case TouchPhaseExtended.Moved:
                if (focusObj != null && bkgArtworkColl.Raycast(guiCam.ScreenPointToRay(touchPosition), out hitInfo, 500f))
                {
                    BlockAndLockPiece component = focusObj.GetComponent <BlockAndLockPiece>();
                    Vector3           newPos    = hitInfo.point + pickupOffset;
                    newPos.z = 0f;
                    if (newPos.x < xMin)
                    {
                        newPos.x = xMin;
                    }
                    else if (newPos.x > xMax)
                    {
                        newPos.x = xMax;
                    }
                    if (newPos.y < yMin)
                    {
                        newPos.y = yMin;
                    }
                    else if (newPos.y > yMax)
                    {
                        newPos.y = yMax;
                    }
                    component.PixelMouseDrag(newPos);
                }
                break;

            case TouchPhaseExtended.Ended:
            {
                if (!(focusObj != null))
                {
                    break;
                }
                if (Vector3.Distance(oldPos, touchPosition) < swipeThreshold)
                {
                    isTap = true;
                }
                else
                {
                    isTap = false;
                }
                BlockAndLockPiece component = focusObj.GetComponent <BlockAndLockPiece>();
                if (component != null)
                {
                    if (component.Category == PieceCategory.MoveableObject)
                    {
                        if (isTap)
                        {
                            Grid2 grid;
                            if (focusObj == previousSelection)
                            {
                                grid = turnArrowOff;
                                previousSelection = null;
                                playAudioEvent(settings.audioDeselectPiece);
                            }
                            else
                            {
                                if (previousSelection != null)
                                {
                                    previousSelection.GetComponent <BlockAndLockPiece>().PixelMouseTapped(touchPosition);
                                }
                                previousSelection = focusObj;
                                grid = PositionToGrid(focusObj.transform.localPosition.x, focusObj.transform.localPosition.y);
                                playAudioEvent(settings.audioSelectPiece);
                            }
                            component.PixelMouseTapped(touchPosition);
                            setArrowState(arrowLeft, new Grid2(grid.x - 1, grid.y));
                            setArrowState(arrowRight, new Grid2(grid.x + 1, grid.y));
                            setArrowState(arrowUp, new Grid2(grid.x, grid.y - 1));
                            setArrowState(arrowDown, new Grid2(grid.x, grid.y + 1));
                        }
                        else
                        {
                            float num  = touchPosition.x - touchPositionOrigin.x;
                            float num2 = touchPositionOrigin.y - touchPosition.y;
                            component.Select();
                            Grid2      grid  = PositionToGrid(focusObj.transform.localPosition.x, focusObj.transform.localPosition.y);
                            Grid2      grid2 = new Grid2(grid.x, grid.y);
                            GameObject gameObject;
                            if (Mathf.Abs(num) >= Mathf.Abs(num2))
                            {
                                gameObject = ((!(num < 0f)) ? arrowRight : arrowLeft);
                                grid2.x   += (int)Mathf.Sign(num);
                            }
                            else
                            {
                                gameObject = ((!(num2 < 0f)) ? arrowDown : arrowUp);
                                grid2.y   += (int)Mathf.Sign(num2);
                            }
                            if (isWithinGrid(grid2))
                            {
                                if (previousSelection != null && previousSelection != focusObj)
                                {
                                    component = previousSelection.GetComponent <BlockAndLockPiece>();
                                    if (component != null)
                                    {
                                        component.Deselect();
                                    }
                                }
                                BlockAndLockBoardData blockAndLockBoardData = gameBoard[grid2.x, grid2.y];
                                if (blockAndLockBoardData.Category == PieceCategory.Empty || blockAndLockBoardData.Category == PieceCategory.SolvePosition)
                                {
                                    previousSelection = focusObj;
                                    focusObj          = gameObject;
                                    component         = gameObject.GetComponent <BlockAndLockPiece>();
                                }
                                else
                                {
                                    setArrowState(arrowLeft, new Grid2(grid.x - 1, grid.y));
                                    setArrowState(arrowRight, new Grid2(grid.x + 1, grid.y));
                                    setArrowState(arrowUp, new Grid2(grid.x, grid.y - 1));
                                    setArrowState(arrowDown, new Grid2(grid.x, grid.y + 1));
                                    previousSelection = focusObj;
                                }
                            }
                        }
                    }
                    if (component.Category == PieceCategory.Arrow)
                    {
                        playAudioEvent(settings.audioArrowTapped);
                        setArrowState(arrowLeft, turnArrowOff);
                        setArrowState(arrowRight, turnArrowOff);
                        setArrowState(arrowUp, turnArrowOff);
                        setArrowState(arrowDown, turnArrowOff);
                        Grid2 grid = PositionToGrid(previousSelection.transform.localPosition.x, previousSelection.transform.localPosition.y);
                        int   id   = gameBoard[grid.x, grid.y].Id;
                        Grid2 grid3;
                        int   num3;
                        if (focusObj.name == "ArrowLeft")
                        {
                            grid3 = new Grid2(-1, 0);
                            num3  = grid.x;
                        }
                        else if (focusObj.name == "ArrowRight")
                        {
                            grid3 = new Grid2(1, 0);
                            num3  = settings.GridWidth - grid.x - 1;
                        }
                        else if (focusObj.name == "ArrowUp")
                        {
                            grid3 = new Grid2(0, -1);
                            num3  = grid.y;
                        }
                        else if (focusObj.name == "ArrowDown")
                        {
                            grid3 = new Grid2(0, 1);
                            num3  = settings.GridHeight - grid.y - 1;
                        }
                        else
                        {
                            grid3 = new Grid2(0, 0);
                            num3  = 0;
                        }
                        Grid2 grid4    = new Grid2(grid.x, grid.y);
                        Grid2 grid5    = new Grid2(grid.x, grid.y);
                        bool  flag     = false;
                        int   num4     = 0;
                        bool  hitPiece = false;
                        for (int i = 0; i < num3; i++)
                        {
                            grid4.x += grid3.x;
                            grid4.y += grid3.y;
                            num4++;
                            BlockAndLockBoardData blockAndLockBoardData2 = gameBoard[grid4.x, grid4.y];
                            if (blockAndLockBoardData2.Category != 0)
                            {
                                bool flag2 = true;
                                if (blockAndLockBoardData2.Category == PieceCategory.SolvePosition)
                                {
                                    if (blockAndLockBoardData2.Id == id)
                                    {
                                        grid5 = new Grid2(grid4.x, grid4.y);
                                        flag  = true;
                                    }
                                    else
                                    {
                                        flag2 = false;
                                    }
                                }
                                else
                                {
                                    if (blockAndLockBoardData2.Category == PieceCategory.MoveableObject)
                                    {
                                        hitPiece = true;
                                    }
                                    num4--;
                                }
                                if (flag2)
                                {
                                    break;
                                }
                            }
                            grid5 = new Grid2(grid4.x, grid4.y);
                        }
                        currentContents = gameBoard[grid5.x, grid5.y];
                        float num5 = 0f;
                        float num6 = settings.MoveTimePerCell;
                        for (int i = 0; i < num4; i++)
                        {
                            num5 += num6;
                            num6 -= settings.MoveDecayPerCell;
                        }
                        Vector2 vector  = GridToPosition(grid5.x, grid5.y);
                        Vector3 vector2 = new Vector3(vector.x, vector.y, 0f);
                        isMoving = true;
                        if (!hasMadeMove)
                        {
                            hasMadeMove = true;
                            restartButton.SetActive(value: true);
                        }
                        playAudioEvent(settings.audioMovePiece);
                        if (flag)
                        {
                            gameBoard[grid.x, grid.y] = prevBoardData[id];
                            int id2 = gameBoard[grid5.x, grid5.y].Id;
                            iTween.MoveTo(previousSelection, iTween.Hash("islocal", true, "position", vector2, "easeType", settings.PieceMoveEaseType, "time", num5, "oncomplete", "onMovementLockComplete", "oncompleteparams", id2, "oncompletetarget", base.gameObject));
                            ParticleSystem component2 = previousSelection.GetComponent <ParticleSystem>();
                            float          num7       = 1f;
                            if (component2 != null)
                            {
                                num7 = component2.main.duration;
                            }
                            float delayTime = num5 + num7;
                            CoroutineRunner.Start(checkIfPuzzleSolved(component, delayTime), this, "checkIfPuzzleSolved");
                        }
                        else
                        {
                            gameBoard[grid5.x, grid5.y] = gameBoard[grid.x, grid.y];
                            gameBoard[grid.x, grid.y]   = prevBoardData[id];
                            MoveData moveData = new MoveData(grid5, hitPiece);
                            iTween.MoveTo(previousSelection, iTween.Hash("islocal", true, "position", vector2, "easeType", settings.PieceMoveEaseType, "time", num5, "oncomplete", "onMovementNonLockComplete", "oncompleteparams", moveData, "oncompletetarget", base.gameObject));
                        }
                        prevBoardData[id] = currentContents;
                        focusObj          = null;
                    }
                }
                touchPositionOrigin = INVALID_COORDINATE;
                break;
            }

            case TouchPhaseExtended.Canceled:
                break;

            case TouchPhaseExtended.Mouse:
                if (oldPos == touchPosition)
                {
                    break;
                }
                oldPos   = touchPosition;
                focusHit = GetPixelHit(touchPosition);
                if (focusHit.collider != null)
                {
                    focusObj = focusHit.collider.gameObject;
                }
                else
                {
                    focusObj = null;
                }
                if (!(focusObj != oldFocus))
                {
                    break;
                }
                if (oldFocus != null)
                {
                    BlockAndLockPiece component = oldFocus.GetComponent <BlockAndLockPiece>();
                    if (component != null)
                    {
                        component.PixelMouseExit();
                    }
                }
                if (focusObj != null)
                {
                    BlockAndLockPiece component = focusObj.GetComponent <BlockAndLockPiece>();
                    if (component != null)
                    {
                        component.PixelMouseOver();
                    }
                }
                oldFocus = focusObj;
                break;

            case TouchPhaseExtended.NoEvent:
                break;

            case TouchPhaseExtended.Stationary:
                break;
            }
        }