public SpellHandler.SpellType EndGesture()
    {
        //If the gesture was already ended
        if (lNextSample == -1 && rNextSample == -1)
        {
            return(SpellHandler.SpellType.NONE);
        }

        lNextSample = -1;
        rNextSample = -1;

        Gesture.GestureHand hands = currentGesture.GetCurHands();

        //If there's only 1 node in one of the hands just delete the gesture and stop cause otherwise bad things happen during conversion
        if ((hands == Gesture.GestureHand.LEFT && currentGesture.NumNodes(Gesture.GestureHand.LEFT) < 2) ||
            (hands == Gesture.GestureHand.RIGHT && currentGesture.NumNodes(Gesture.GestureHand.RIGHT) < 2) ||
            (hands == Gesture.GestureHand.BOTH && (currentGesture.NumNodes(Gesture.GestureHand.LEFT) < 2 || currentGesture.NumNodes(Gesture.GestureHand.RIGHT) < 2)))
        {
            currentGesture = null;
            return(SpellHandler.SpellType.NONE);
        }

        currentGesture.ChangeNumNodes(samplesPerGesture);

        return(FindBestMatch(currentGesture));
    }
    public void CastSpell(SpellType type, Gesture.GestureHand hand)
    {
        bool left = false;

        if (hand == Gesture.GestureHand.LEFT)
        {
            left = true;
        }

        Spell spell = null;

        switch (type)
        {
        case SpellType.ONE_QUICK:
            spell = QuickSpell(left);
            break;

        case SpellType.ONE_HEAVY:
            spell = HeavySpell(left);
            break;

        case SpellType.ONE_SPECIAL:
            spell = SpecialSpell(left);
            break;

        case SpellType.TWO_DEFENSE:
            spell = DefenseSpell();
            break;

        case SpellType.TWO_OFFENSE:
            spell = OffenseSpell();
            break;
        }

        if (spell != null)
        {
            spell.Cast(player, left);
        }
    }
    //Returns the index of the best match in validGestures or -1 if none are close enough
    private SpellHandler.SpellType FindBestMatch(Gesture inputGesture)
    {
        SpellHandler.SpellType bestMatch = SpellHandler.SpellType.NONE;
        float matchDiff = 0;

        Gesture.GestureHand hands = inputGesture.GetCurHands();

        if ((hands == Gesture.GestureHand.BOTH && (inputGesture.NumNodes(Gesture.GestureHand.LEFT) == 1 || inputGesture.NumNodes(Gesture.GestureHand.RIGHT) == 1)) ||
            (hands != Gesture.GestureHand.BOTH && inputGesture.NumNodes(hands) == 1))
        {
            return(bestMatch);
        }

        if (hands == Gesture.GestureHand.BOTH)
        {
            Debug.Log("both hands involved");

            //If there's only 1 node just stop
            if (inputGesture.NumNodes(Gesture.GestureHand.LEFT) < 2 || inputGesture.NumNodes(Gesture.GestureHand.RIGHT) < 2)
            {
                return(bestMatch);
            }

            foreach (Gesture g in twoHandGestures)
            {
                float diff = g.AverageDifference(inputGesture, lengthAccuracyFactor, Gesture.GestureHand.LEFT)
                             + g.AverageDifference(inputGesture, lengthAccuracyFactor, Gesture.GestureHand.RIGHT) / 2;

                //Debug.Log("diff = " + diff);

                if ((bestMatch == SpellHandler.SpellType.NONE && diff < accuracyPerSample) || diff < matchDiff)
                {
                    bestMatch = g.GetSpell();
                    matchDiff = diff;
                }
            }
        }
        else
        {
            //If there's only 1 node just stop
            if (inputGesture.NumNodes(hands) < 2)
            {
                return(bestMatch);
            }

            foreach (Gesture g in oneHandGestures)
            {
                float diff = g.AverageDifference(inputGesture, lengthAccuracyFactor, hands);

                //Debug.Log("diff = " + diff);

                if ((bestMatch == SpellHandler.SpellType.NONE && diff < accuracyPerSample) || diff < matchDiff)
                {
                    bestMatch = g.GetSpell();
                    matchDiff = diff;
                }
            }
        }

        return(bestMatch);
    }
    public void EndCalibratedGesture()
    {
        if (!calibrating || (lNextSample == -1 && rNextSample == -1))
        {
            return;
        }

        lNextSample = -1;
        rNextSample = -1;

        calibrating = false;

        Gesture.GestureHand hands = currentGesture.GetCurHands();

        //If there's only 1 node in one of the hands just delete the gesture and stop cause otherwise bad things happen during conversion
        if ((hands == Gesture.GestureHand.LEFT && currentGesture.NumNodes(Gesture.GestureHand.LEFT) < 2) ||
            (hands == Gesture.GestureHand.RIGHT && currentGesture.NumNodes(Gesture.GestureHand.RIGHT) < 2) ||
            (hands == Gesture.GestureHand.BOTH && (currentGesture.NumNodes(Gesture.GestureHand.LEFT) < 2 || currentGesture.NumNodes(Gesture.GestureHand.RIGHT) < 2)))
        {
            currentGesture = null;
            return;
        }

        currentGesture.ChangeNumNodes(samplesPerGesture);
        currentGesture.DuplicateHand();

        if (calibratedGestures.Count == numCalibrations - 1)
        {
            Debug.Log("Finishing gesture");

            //Average the gestures
            for (int i = 1; i < samplesPerGesture; i++)
            {
                Vector3 avgNode   = currentGesture.NodeAt(i, Gesture.GestureHand.LEFT);
                float   avgLength = avgNode.magnitude;

                for (int j = 0; j < calibratedGestures.Count; j++)
                {
                    Vector3 node = calibratedGestures[j].NodeAt(i, Gesture.GestureHand.LEFT);

                    avgNode   += node;
                    avgLength += node.magnitude;
                }

                avgNode   /= numCalibrations;
                avgLength /= numCalibrations;

                avgNode = avgNode.normalized * avgLength;

                currentGesture.SetNodeAt(i, Gesture.GestureHand.LEFT, avgNode);
            }

            //Save the gesture to the json
            switch (calibrationType)
            {
            case SpellHandler.SpellType.ONE_QUICK:
            case SpellHandler.SpellType.ONE_HEAVY:
            case SpellHandler.SpellType.ONE_SPECIAL:
                SaveLastGesture(calibrationType, false);
                break;

            case SpellHandler.SpellType.TWO_DEFENSE:
            case SpellHandler.SpellType.TWO_OFFENSE:
                SaveLastGesture(calibrationType, true);
                break;
            }

            //Clear the gestures
            calibratedGestures = new List <Gesture>();

            calibrationMenu.FinishedGesture();
        }
        else
        {
            Debug.Log("Ending gesture");

            //Add the gesture so it can be used once enough are recorded
            calibratedGestures.Add(currentGesture);

            calibrationMenu.DecreaseRemainingGestures();
        }
    }