void CallEndStatus(InputStatusMonitor inputStatusMonitor, eStatus NewStatus)
    {
        eStatus OldStatus = inputStatusMonitor.Status;

        inputStatusMonitor.Status = NewStatus;
        switch (OldStatus)
        {
        case eStatus.free:
        {
            PointerDown(inputStatusMonitor);
            break;
        }

        case eStatus.holding:
        {
            PointerHoldEnd(inputStatusMonitor);
            break;
        }

        case eStatus.swiping:
        {
            PointerSwipeEnd(inputStatusMonitor);
            break;
        }
        }

        return;
    }
    void UpdateLine(InputStatusMonitor inputStatusMonitor)
    {
        Plane p = new Plane(-Cam.transform.forward, Cam.transform.forward + Cam.transform.position);


        List <Vector3> poss = new List <Vector3>();
        Vector3        pos  = Vector3.zero;
        float          f;
        Ray            r;

        foreach (SwipeWaypoint e in inputStatusMonitor.currentSwipe.Waypoints)
        {
            pos = Vector3.zero;
            r   = Cam.ScreenPointToRay(e.ScreenPosition);
            if (!p.Raycast(r, out f))
            {
                continue;
            }
            pos = r.origin + r.direction * f;
            poss.Add(pos);
        }
        pos = Vector3.zero;
        r   = Cam.ScreenPointToRay(inputStatusMonitor.currentScreenPosition);
        if (p.Raycast(r, out f))
        {
            pos = r.origin + r.direction * f;
            poss.Add(pos);
        }
        if (LR != null)
        {
            LR.positionCount = poss.Count;
            LR.SetPositions(poss.ToArray());
        }
    }
 void PointerHoldEnd(InputStatusMonitor inputStatusMonitor)
 {
     //Debug.Log("HoldEnd");
     foreach (IInputListener c in PointerHoldEndCalls)
     {
         c.OnPointerHoldEnd(new PointerInfo(inputStatusMonitor.inputSource, inputStatusMonitor.currentScreenPosition), Time.timeSinceLevelLoad - inputStatusMonitor.holdStart);
     }
 }
 void PointerSwipeStart(InputStatusMonitor inputStatusMonitor)
 {
     foreach (IInputListener c in PointerSwipeStartCalls)
     {
         c.OnPointerSwipeStart(new PointerInfo(inputStatusMonitor.inputSource, inputStatusMonitor.currentScreenPosition), inputStatusMonitor.currentSwipe);
     }
     //Debug.Log("SwipeStart");
 }
 void PointerMove(InputStatusMonitor inputStatusMonitor)
 {
     //       //Debug.Log("");
     foreach (IInputListener c in PointerMoveCalls)
     {
         c.OnPointerMove(new PointerInfo(inputStatusMonitor.inputSource, inputStatusMonitor.currentScreenPosition));
     }
 }
 void PointerDoubleClick(InputStatusMonitor inputStatusMonitor)
 {
     doubleTapFrame = true;
     //Debug.Log("DoubleClick");
     foreach (IInputListener c in PointerDoubleClickCalls)
     {
         c.OnPointerDoubleClick(new PointerInfo(inputStatusMonitor.inputSource, inputStatusMonitor.currentScreenPosition));
     }
 }
    void PointerSwipeEnd(InputStatusMonitor inputStatusMonitor)
    {
        inputStatusMonitor.currentSwipe.AddWP(inputStatusMonitor.currentScreenPosition);
        inputStatusMonitor.swipeBuffer.Clear();
        //Debug.Log("SwipeEnd");

        foreach (IInputListener c in PointerSwipeEndCalls)
        {
            c.OnPointerSwipeEnd(new PointerInfo(inputStatusMonitor.inputSource, inputStatusMonitor.currentScreenPosition), inputStatusMonitor.currentSwipe);
        }
    }
    private bool SwipeThreshold(InputStatusMonitor inputStatusMonitor)
    {
        float speedTh = ScreenPercent((inputStatusMonitor.currentScreenPosition - inputStatusMonitor.oldScreenPosition).magnitude) / Time.deltaTime / MinimumSwipeVelocity;
        float distTH  = (ScreenPercent((inputStatusMonitor.currentScreenPosition - inputStatusMonitor.contactStartScreenPosition).magnitude) / MinSwipeScreenPercent);

        float th = (swipeThresholdFunct.Evaluate(speedTh) * swipeThresholdFunct.Evaluate(distTH)) / 2;

        if (th >= 1)
        {
            // Debug.Log("speedTh " + speedTh + " distTH " + distTH + " th " + th);
            return(true);
        }

        return(false);
    }
    IEnumerator MonitorLoop()
    {
        isMonitoring = true;
        while (HasListeners())
        {
            if (inputStatus.inputSource != source)
            {
                inputStatus = new InputStatusMonitor(source);
            }

            DetermineStatus(inputStatus);

            yield return(new WaitForEndOfFrame());
        }


        isMonitoring = false;
    }
    void PointerSwipeUpdate(InputStatusMonitor inputStatusMonitor)
    {
        bool WPAdded = false;

        if (inputStatusMonitor == null)
        {
            //Debug.LogError("inputStatusMonitor null"); return;
        }
        if (inputStatusMonitor.swipeDirection == Vector2.zero)
        {
            inputStatusMonitor.swipeDirection = (inputStatusMonitor.currentScreenPosition - inputStatusMonitor.oldScreenPosition).normalized;
        }
        else
        {
            // Vector2 oldp = ((inputStatusMonitor.currentSwipe.Waypoints.Count > 0) ? inputStatusMonitor.currentSwipe.Waypoints[inputStatusMonitor.currentSwipe.Waypoints.Count - 1].ScreenPosition : inputStatusMonitor.oldScreenPosition);

            if (inputStatusMonitor.currentSwipe.Waypoints.Count == 0)
            {
                inputStatusMonitor.currentSwipe.Waypoints.Add(new SwipeWaypoint((inputStatusMonitor.contactStartScreenPosition)));
            }
            Vector2 oldp = inputStatusMonitor.currentSwipe.Waypoints[inputStatusMonitor.currentSwipe.Waypoints.Count - 1].ScreenPosition;

            float delta = (inputStatusMonitor.currentScreenPosition - inputStatusMonitor.currentSwipe.Waypoints[inputStatusMonitor.currentSwipe.Waypoints.Count - 1].ScreenPosition).magnitude;

            bool trackback = false;
            if (inputStatusMonitor.highestDelta < delta)
            {
                inputStatusMonitor.highestDelta = delta;
            }
            else
            {
                trackback = ScreenPercent(inputStatusMonitor.highestDelta - delta) >= MinSwipeScreenPercent;
            }
            if (Vector2.Angle((inputStatusMonitor.currentScreenPosition - oldp).normalized, inputStatusMonitor.swipeDirection) >= MinSwipeAngleDelta && ScreenPercent((inputStatusMonitor.currentScreenPosition - oldp).magnitude) >= MinSwipeDelta || ScreenPercent((inputStatusMonitor.currentScreenPosition - oldp).magnitude) >= MaxSwipeDelta || trackback)
            {
                Vector2 newWP = inputStatusMonitor.currentScreenPosition;
                if (inputStatusMonitor.swipeBuffer.Count > 0)
                {
                    int   k    = 0;
                    float topD = 0;//^^
                    for (int i = 0; i < inputStatusMonitor.swipeBuffer.Count; i++)
                    {
                        float d = ((inputStatusMonitor.swipeBuffer[i] - oldp).magnitude + (inputStatusMonitor.swipeBuffer[i] - inputStatusMonitor.currentScreenPosition).magnitude);
                        if (d > topD)
                        {
                            k    = i;
                            topD = d;
                        }
                    }
                    newWP = inputStatusMonitor.swipeBuffer[k];
                    for (int i = 0; i <= k; i++)
                    {
                        inputStatusMonitor.swipeBuffer.RemoveAt(0);
                    }
                }

                inputStatusMonitor.currentSwipe.AddWP(newWP);
                WPAdded = true;
                inputStatusMonitor.highestDelta   = 0;
                inputStatusMonitor.swipeDirection = (newWP - oldp).normalized;
            }
            else
            {
                inputStatusMonitor.swipeBuffer.Add(inputStatusMonitor.currentScreenPosition);
            }
        }


        UpdateLine(inputStatusMonitor);

        foreach (IInputListener c in PointerSwipeUpdateCalls)
        {
            c.OnPointerSwipeUpdate(new PointerInfo(inputStatusMonitor.inputSource, inputStatusMonitor.currentScreenPosition), inputStatusMonitor.currentSwipe, WPAdded);
        }

        //      //Debug.Log("");
    }
    void DetermineStatus(InputStatusMonitor inputStatusMonitor)
    {
        switch (inputStatusMonitor.Status)
        {
        case eStatus.free:
        {
            if (IsControlFree(inputStatusMonitor.inputSource))
            {
                if (inputStatusMonitor.Status != eStatus.free)
                {
                    CallEndStatus(inputStatusMonitor, eStatus.free);
                    PointerUp(inputStatusMonitor);
                    return;
                }
                else
                {
                    // OnPointerUpUpdate();
                }
                return;
            }
            else
            {
                goto case eStatus.down;
            }
        }

        case eStatus.down:
        {
            if (inputStatusMonitor.Status != eStatus.down)
            {
                if (inputStatusMonitor.Status == eStatus.free)
                {
                    inputStatusMonitor.contactStart = Time.timeSinceLevelLoad;
                    inputStatusMonitor.contactStartScreenPosition = GetCurrentPos(inputStatusMonitor.inputSource);
                    inputStatusMonitor.currentScreenPosition      = inputStatusMonitor.contactStartScreenPosition;
                    inputStatusMonitor.oldScreenPosition          = inputStatusMonitor.currentScreenPosition;
                }
                if (Time.timeSinceLevelLoad - inputStatusMonitor.lastTap <= DoubleTapwindow && (inputStatusMonitor.currentScreenPosition - inputStatusMonitor.lastTapScreenPosition).magnitude <= TapDistanceThreshold)
                {
                    //goto case eStatus.dbltap;
                    PointerDoubleClick(inputStatusMonitor);
                }
                else
                {
                    CallEndStatus(inputStatusMonitor, eStatus.down);
                }
            }
            else
            {
                if (IsControlFree(inputStatusMonitor.inputSource))
                {
                    inputStatusMonitor.lastTap               = Time.timeSinceLevelLoad;
                    inputStatusMonitor.oldScreenPosition     = inputStatusMonitor.currentScreenPosition;
                    inputStatusMonitor.currentScreenPosition = GetCurrentPos(inputStatusMonitor.inputSource);
                    inputStatusMonitor.lastTapScreenPosition = inputStatusMonitor.currentScreenPosition;
                    PointerClick(inputStatusMonitor);
                    goto case eStatus.free;
                }
                else
                {
                    inputStatusMonitor.oldScreenPosition     = inputStatusMonitor.currentScreenPosition;
                    inputStatusMonitor.currentScreenPosition = GetCurrentPos(inputStatusMonitor.inputSource);



                    if (SwipeThreshold(inputStatusMonitor))
                    {
                        goto case eStatus.swiping;
                    }
                    if (Time.timeSinceLevelLoad - inputStatusMonitor.contactStart >= HoldDelay)
                    {
                        goto case eStatus.holding;
                    }
                }
            }
            //            OnPointerDownUpdate();
            inputStatusMonitor.Status = eStatus.down;
            return;
        }


        case eStatus.holding:
        {
            if (IsControlFree(inputStatusMonitor.inputSource))
            {
                inputStatusMonitor.lastTap               = Time.timeSinceLevelLoad;
                inputStatusMonitor.oldScreenPosition     = inputStatusMonitor.currentScreenPosition;
                inputStatusMonitor.currentScreenPosition = GetCurrentPos(inputStatusMonitor.inputSource);
                inputStatusMonitor.lastTapScreenPosition = inputStatusMonitor.currentScreenPosition;

                //OnPointerHoldEnd();
                goto case eStatus.free;
            }
            else
            {
                if (inputStatusMonitor.Status != eStatus.holding)
                {
                    CallEndStatus(inputStatusMonitor, eStatus.holding);
                    PointerHoldStart(inputStatusMonitor);
                    return;
                }
                inputStatusMonitor.oldScreenPosition     = inputStatusMonitor.currentScreenPosition;
                inputStatusMonitor.currentScreenPosition = GetCurrentPos(inputStatusMonitor.inputSource);
                if (SwipeThreshold(inputStatusMonitor))
                {
                    //OnPointerHoldEnd();
                    goto case eStatus.swiping;
                }
            }
            PointerHoldUpdate(inputStatusMonitor);
            return;
        }

        case eStatus.swiping:
        {
            if (inputStatusMonitor.Status != eStatus.swiping)
            {
                //    if (Status == eStatus.down || Status == eStatus.holding)
                //    {
                inputStatusMonitor.swipeStartScreenPosition = inputStatusMonitor.currentScreenPosition;


                swipetimer = SwipeReleaseDelay;
                //    }
                CallEndStatus(inputStatusMonitor, eStatus.swiping);
                inputStatusMonitor.currentSwipe.Clear();
                inputStatusMonitor.swipeDirection = Vector2.zero;
                inputStatusMonitor.currentSwipe.AddWP(inputStatusMonitor.swipeStartScreenPosition);
                PointerSwipeStart(inputStatusMonitor);
            }
            else
            {
                if (IsControlFree(inputStatusMonitor.inputSource))
                {
                    inputStatusMonitor.lastTap               = Time.timeSinceLevelLoad;
                    inputStatusMonitor.oldScreenPosition     = inputStatusMonitor.currentScreenPosition;
                    inputStatusMonitor.currentScreenPosition = GetCurrentPos(inputStatusMonitor.inputSource);
                    inputStatusMonitor.lastTapScreenPosition = inputStatusMonitor.currentScreenPosition;


                    //OnPointerSwipeEnd();
                    goto case eStatus.free;
                }
                else
                {
                    inputStatusMonitor.oldScreenPosition     = inputStatusMonitor.currentScreenPosition;
                    inputStatusMonitor.currentScreenPosition = GetCurrentPos(inputStatusMonitor.inputSource);

                    if ((inputStatusMonitor.currentScreenPosition - inputStatusMonitor.oldScreenPosition).magnitude / Time.deltaTime <= MinimumSwipeVelocity)
                    {
                        swipetimer -= Time.deltaTime;
                        if (swipetimer <= 0)
                        {
                            //OnPointerSwipeEnd();

                            goto case eStatus.holding;
                        }
                    }
                    else
                    {
                        swipetimer = SwipeReleaseDelay;
                    }
                }
            }
            inputStatusMonitor.Status = eStatus.swiping;
            PointerSwipeUpdate(inputStatusMonitor);
            return;
        }
        }
    }