public IndividualSkills( PresentationAction pa)
 {
     myPresentationAction = pa;
     InitializeComponent();
     currentInstruction = myPresentationAction.myMistake;
     introduction = new IndividualSkillsIntroduction();
     individualInstructions = new IndividualInstructions();
     finish = new IndividualFinish();
     Loaded += IndividualSkills_Loaded;
 }
        public IndividualPosture(MainWindow parent)
        {
            this.parent = parent;
            myVoiceAndMovementObject = new PresentationAction();
            periodicMovements = new PeriodicMovements();

            tempMistakeList = new ArrayList();
            mistakeList = new ArrayList();
            voiceAndMovementsList = new ArrayList();
            audioMovementMistakeTempList = new ArrayList();
            bodyMistakes = new ArrayList();
        }
        public JudgementMaker(MainWindow parent)
        {
           this.parent = parent;
           myVoiceAndMovementObject = new PresentationAction();
           periodicMovements = new PeriodicMovements();

           armMovementsCalc = new ArmMovementsCalc(this);
           tempMistakeList = new ArrayList();
           mistakeList = new ArrayList();
           voiceAndMovementsList = new ArrayList();
           audioMovementMistakeTempList = new ArrayList();
           bodyMistakes = new ArrayList();
            
        }
        private void handleTimeSpeaking()
        {
            double currentTime = DateTime.Now.TimeOfDay.TotalMilliseconds;
            if (currentTime - myVoiceAndMovementObject.timeStarted > apa.ThresholdIsSpeakingLongTime)
            {
                PresentationAction pa = new PresentationAction(PresentationAction.MistakeType.LONG_TALK);
                pa.timeStarted = myVoiceAndMovementObject.timeStarted;
                pa.isVoiceAndMovementMistake = true;
                if (currentTime - myVoiceAndMovementObject.timeStarted > apa.ThresholdIsSpeakingVeryLongTime)
                {
                    //pa.interrupt = true;
                }

                audioMovementMistakeTempList.Add(pa);
            }
        }
        public override void analyze()
        {
            bfpa = this.parent.bodyFrameHandler.bodyFramePreAnalysis;
            apa = this.parent.audioHandler.audioPreAnalysis;

            mistakeList = new System.Collections.ArrayList();

            if (bfpa.body != null)
            {
                if (periodicMovements.checPeriodicMovements(bfpa.body))
                {
                    PresentationAction pa = new PresentationAction(PresentationAction.MistakeType.DANCING);
                    mistakeList.Insert(0, pa);
                }
            }
        }
        //this method resets everything of this class. Used for going back to mainmenu
        public void resetAll()
        {
            feedbackedMistakes = new ArrayList();
            mistakes = new ArrayList();
            interruptionsList = new ArrayList();

            crossedArms = new PresentationAction[interruptionThreshold];
            handsUnderHips = new PresentationAction[interruptionThreshold];
            handsBehindBack = new PresentationAction[interruptionThreshold];
            hunchPosture = new PresentationAction[interruptionThreshold];
            leaningPosture = new PresentationAction[interruptionThreshold];
            highVolumes = new PresentationAction[interruptionThreshold];
            lowVolumes = new PresentationAction[interruptionThreshold];
            longPauses = new PresentationAction[interruptionThreshold];
            longTalks = new PresentationAction[interruptionThreshold];
            periodicMovements = new PresentationAction[interruptionThreshold];
            hmmms = new PresentationAction[interruptionThreshold];
            legsCrossed = new PresentationAction[interruptionThreshold];
            handsNotMoving = new PresentationAction[interruptionThreshold];
            handsMovingMuch = new PresentationAction[interruptionThreshold];
            noModulation = new PresentationAction[interruptionThreshold];

            crossedArmsList = new ArrayList();
            handsUnderHipsList = new ArrayList();
            handsBehindBackList = new ArrayList();
            hunchPostureList = new ArrayList();
            leaningPostureList = new ArrayList();
            highVolumesList = new ArrayList();
            lowVolumesList = new ArrayList();
            longPausesList = new ArrayList();
            longTalksList = new ArrayList();
            periodicMovementsList = new ArrayList();
            hmmmsList = new ArrayList();
            legsCrossedList = new ArrayList();
            handsNotMovingList = new ArrayList();
            handsMovingMuchList = new ArrayList();
            noModulationList = new ArrayList();

            previousAction = new PresentationAction();
            previousAction.myMistake = PresentationAction.MistakeType.NOMISTAKE;

            crossedArmsMistakes = 0;
            handsUnderHipsMistakes = 0;
            handsBehindBackMistakes = 0;
            hunchPostureMistakes = 0;
            leaningPostureMistakes = 0;
            highVolumesMistakes = 0;
            lowVolumesMistakes = 0;
            longPausesMistakes = 0;
            longTalksMistakes = 0;
            periodicMovementsMistakes = 0;
            hmmmsMistakes = 0;
            legsCrossedMistakes = 0;
            handsNotMovingMistakes = 0;
            handsMovingMuchMistakes = 0;
            noModulationMistakes = 0;

            crossedArmsCorrections = 0;
            handsUnderHipsCorrections = 0;
            handsBehindBackCorrections = 0;
            hunchPostureCorrections = 0;
            leaningPostureCorrections = 0;
            highVolumesCorrections = 0;
            lowVolumesCorrections = 0;
            longPausesCorrections = 0;
            longTalksCorrections = 0;
            periodicMovementsCorrections = 0;
            hmmmsCorrections = 0;
            legsCrossedCorrections = 0;
            handsNotMovingCorrections = 0;
            handsMovingMuchCorrections = 0;
            noModulationCorrections = 0;

            previouscrossedArmsMistakes = 0;
            previoushandsUnderHipsMistakes = 0;
            previoushandsBehindBackMistakes = 0;
            previoushunchPostureMistakes = 0;
            previousleaningPostureMistakes = 0;
            previoushighVolumesMistakes = 0;
            previouslowVolumesMistakes = 0;
            previouslongPausesMistakes = 0;
            previouslongTalksMistakes = 0;
            previousperiodicMovementsMistakes = 0;
            previoushmmmsMistakes = 0;
            previouslegsCrossedMistakes = 0;
            previoushandsNotMovingMistakes = 0;
            previoushandsMovingMuchMistakes = 0;
            previousnoModulationMistakes = 0;

            previouscrossedArmsCorrections = 0;
            previoushandsUnderHipsCorrections = 0;
            previoushandsBehindBackCorrections = 0;
            previoushunchPostureCorrections = 0;
            previousleaningPostureCorrections = 0;
            previoushighVolumesCorrections = 0;
            previouslowVolumesCorrections = 0;
            previouslongPausesCorrections = 0;
            previouslongTalksCorrections = 0;
            previousperiodicMovementsCorrections = 0;
            previoushmmmsCorrections = 0;
            previouslegsCrossedCorrections = 0;
            previoushandsNotMovingCorrections = 0;
            previoushandsMovingMuchCorrections = 0;
            previousnoModulationCorrections = 0;

            userName = null;
            session = 1;


            myJudgementMaker = new JudgementMaker(parent);
            noInterrupt = true;
        }
        public RulesAnalyzerImproved(MainWindow parent)
        {
            this.parent = parent;
            myJudgementMaker = new JudgementMaker(parent);
            feedbackedMistakes = new ArrayList();
            mistakes = new ArrayList();
            interruptionsList = new ArrayList();

            crossedArms = new PresentationAction[interruptionThreshold];
            handsUnderHips = new PresentationAction[interruptionThreshold];
            handsBehindBack = new PresentationAction[interruptionThreshold];
            hunchPosture = new PresentationAction[interruptionThreshold];
            leaningPosture = new PresentationAction[interruptionThreshold];
            highVolumes = new PresentationAction[interruptionThreshold];
            lowVolumes = new PresentationAction[interruptionThreshold];
            longPauses = new PresentationAction[interruptionThreshold];
            longTalks = new PresentationAction[interruptionThreshold];
            periodicMovements = new PresentationAction[interruptionThreshold];
            hmmms = new PresentationAction[interruptionThreshold];
            legsCrossed = new PresentationAction[interruptionThreshold];
            handsNotMoving = new PresentationAction[interruptionThreshold];
            handsMovingMuch = new PresentationAction[interruptionThreshold];
            noModulation = new PresentationAction[interruptionThreshold];

            crossedArmsList = new ArrayList();
            handsUnderHipsList = new ArrayList();
            handsBehindBackList = new ArrayList();
            hunchPostureList = new ArrayList();
            leaningPostureList = new ArrayList();
            highVolumesList = new ArrayList();
            lowVolumesList = new ArrayList();
            longPausesList = new ArrayList();
            longTalksList = new ArrayList();
            periodicMovementsList = new ArrayList();
            hmmmsList = new ArrayList();
            legsCrossedList = new ArrayList();
            handsNotMovingList = new ArrayList();
            handsMovingMuchList = new ArrayList();
            noModulationList = new ArrayList();

            previousAction = new PresentationAction();
            previousAction.myMistake = PresentationAction.MistakeType.NOMISTAKE;
        }
        public void getResetPosture()
        {
            bool useAngles = false;
            if (useAngles)
            {
                
            }
            else
            {
                float x = Math.Abs(body.Joints[JointType.HandTipRight].Position.X - body.Joints[JointType.HandTipLeft].Position.X);
                float y = Math.Abs(body.Joints[JointType.HandTipRight].Position.Y - body.Joints[JointType.HandTipLeft].Position.Y);
                float z = Math.Abs(body.Joints[JointType.HandTipRight].Position.Z - body.Joints[JointType.HandTipLeft].Position.Z);

                if (armsCrossed==false&& legsCrossed==false && 
                    rightHandBehindBack==false && leftHandBehindBack == false
                    && rightLean==false && leftLean==false && hunch==false
                    && body.HandRightState != HandState.Closed && body.HandLeftState!= HandState.Closed
                    && leftArmClosePosture == false && rightArmClosePosture == false
                    && x<0.04
                    && y<0.04 
                    && z<0.04)
                {
                    resetPosture = true;
                    bodyPosture = Posture.good;
                    PresentationAction pa = new PresentationAction(PresentationAction.GoodType.RESETPOSTURE);
                    currentGoodies.Add(pa);
                }
                else
                {
                    resetPosture = false;                    
                }
            }
               
        }
        //Here mistakes are added to their respective arrays. If the number threshold is reached, an interruption is made
        private void checkWhereToPutMistake(PresentationAction mistakeX)
        {
            int i = 0;
            //int x = 0;
            // sentMistakes;
            PresentationAction temp = new PresentationAction();
            temp = ((PresentationAction)mistakeX).Clone();

            switch (temp.myMistake)
            {
                case PresentationAction.MistakeType.ARMSCROSSED:
                    crossedArmsMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (crossedArms[i] == null)
                        {
                            crossedArms[i] = temp;
                            crossedArms[i].myMistake = PresentationAction.MistakeType.ARMSCROSSED;
                            break;
                        }
                    }
                    sentMistakes = crossedArms;
                    break;
                //case PresentationAction.MistakeType.BOTHHANDBEHINDBACK:
                //    handsBehindBackMistakes++;
                //    for (i = 0; i < interruptionThreshold; i++)
                //    {
                //        if (handsBehindBack[i] == null)
                //        {
                //            handsBehindBack[i] = temp;
                //            handsBehindBack[i].myMistake = PresentationAction.MistakeType.BOTHHANDBEHINDBACK;
                //            break;
                //        }
                //    }
                //    sentMistakes = handsBehindBack;
                //    break;
                case PresentationAction.MistakeType.LEFTHANDBEHINDBACK:
                    handsBehindBackMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (handsBehindBack[i] == null)
                        {
                            handsBehindBack[i] = temp;
                            handsBehindBack[i].myMistake = PresentationAction.MistakeType.LEFTHANDBEHINDBACK;
                            break;
                        }
                    }
                    sentMistakes = handsBehindBack;
                    break;
                case PresentationAction.MistakeType.RIGHTHANDBEHINDBACK:
                    handsBehindBackMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (handsBehindBack[i] == null)
                        {
                            handsBehindBack[i] = temp;
                            handsBehindBack[i].myMistake = PresentationAction.MistakeType.RIGHTHANDBEHINDBACK;
                            break;
                        }
                    }
                    sentMistakes = handsBehindBack;
                    break;
                case PresentationAction.MistakeType.LEGSCROSSED:
                    legsCrossedMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (legsCrossed[i] == null)
                        {
                            legsCrossed[i] = temp;
                            legsCrossed[i].myMistake = PresentationAction.MistakeType.LEGSCROSSED;
                            break;
                        }
                    }
                    sentMistakes = legsCrossed;
                    break;
                //case PresentationAction.MistakeType.BOTHHANDUNDERHIP:
                //    handsUnderHipsMistakes++;
                //    for (i = 0; i < interruptionThreshold; i++)
                //    {
                //        if (handsUnderHips[i] == null)
                //        {
                //            handsUnderHips[i] = temp;
                //            handsUnderHips[i].myMistake = PresentationAction.MistakeType.BOTHHANDUNDERHIP;
                //            break;
                //        }
                //    }
                //    sentMistakes = handsUnderHips;
                //    break;
                case PresentationAction.MistakeType.RIGHTHANDUNDERHIP:
                    handsUnderHipsMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (handsUnderHips[i] == null)
                        {
                            handsUnderHips[i] = temp;
                            handsUnderHips[i].myMistake = PresentationAction.MistakeType.RIGHTHANDUNDERHIP;
                            break;
                        }
                    }
                    sentMistakes = handsUnderHips;
                    break;
                case PresentationAction.MistakeType.LEFTHANDUNDERHIP:
                    handsUnderHipsMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (handsUnderHips[i] == null)
                        {
                            handsUnderHips[i] = temp;
                            handsUnderHips[i].myMistake = PresentationAction.MistakeType.LEFTHANDUNDERHIP;
                            break;
                        }
                    }
                    sentMistakes = handsUnderHips;
                    break;
                case PresentationAction.MistakeType.HUNCHBACK:
                    hunchPostureMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (hunchPosture[i] == null)
                        {
                            hunchPosture[i] = temp;
                            hunchPosture[i].myMistake = PresentationAction.MistakeType.HUNCHBACK;
                            break;
                        }
                    }
                    sentMistakes = hunchPosture;
                    break;
                case PresentationAction.MistakeType.RIGHTLEAN:
                case PresentationAction.MistakeType.LEFTLEAN:
                    leaningPostureMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (leaningPosture[i] == null)
                        {
                            leaningPosture[i] = temp;
                            leaningPosture[i].myMistake = PresentationAction.MistakeType.RIGHTLEAN;
                            break;
                        }
                    }
                    sentMistakes = leaningPosture;
                    break;
                case PresentationAction.MistakeType.DANCING:
                    periodicMovementsMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (periodicMovements[i] == null)
                        {
                            periodicMovements[i] = temp;
                            periodicMovements[i].myMistake = PresentationAction.MistakeType.DANCING;
                            break;
                        }
                    }
                    sentMistakes = periodicMovements;
                    break;
                case PresentationAction.MistakeType.HANDS_NOT_MOVING:
                    handsNotMovingMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (handsNotMoving[i] == null)
                        {
                            // System.Windows.Media.ImageSource im = parent.videoHandler.kinectImage.Source;  
                            handsNotMoving[i] = temp;
                            handsNotMoving[i].myMistake = PresentationAction.MistakeType.HANDS_NOT_MOVING;
                            // handsNotMoving[i].lastImage = im.CloneCurrentValue();

                            break;
                        }
                    }
                    sentMistakes = handsNotMoving;
                    break;
                case PresentationAction.MistakeType.HANDS_MOVING_MUCH:
                    handsMovingMuchMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (handsMovingMuch[i] == null)
                        {
                            handsMovingMuch[i] = temp;
                            handsMovingMuch[i].myMistake = PresentationAction.MistakeType.HANDS_MOVING_MUCH;

                            break;
                        }
                    }
                    sentMistakes = handsMovingMuch;
                    break;
                case PresentationAction.MistakeType.HIGH_VOLUME:
                    highVolumesMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (highVolumes[i] == null)
                        {
                            highVolumes[i] = temp;
                            highVolumes[i].myMistake = PresentationAction.MistakeType.HIGH_VOLUME;
                            break;
                        }
                    }
                    sentMistakes = highVolumes;
                    break;
                case PresentationAction.MistakeType.LOW_VOLUME:
                    lowVolumesMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (lowVolumes[i] == null)
                        {
                            lowVolumes[i] = temp;
                            lowVolumes[i].myMistake = PresentationAction.MistakeType.LOW_VOLUME;
                            break;
                        }
                    }
                    sentMistakes = lowVolumes;
                    break;
                case PresentationAction.MistakeType.LOW_MODULATION:
                    noModulationMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (noModulation[i] == null)
                        {
                            noModulation[i] = temp;
                            noModulation[i].myMistake = PresentationAction.MistakeType.LOW_MODULATION;
                            break;
                        }
                    }
                    sentMistakes = noModulation;
                    break;
                case PresentationAction.MistakeType.LONG_PAUSE:
                    longPausesMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (longPauses[i] == null)
                        {
                            longPauses[i] = temp;
                            longPauses[i].myMistake = PresentationAction.MistakeType.LONG_PAUSE;
                            break;
                        }
                    }
                    sentMistakes = longPauses;
                    break;
                case PresentationAction.MistakeType.LONG_TALK:
                    longTalksMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (longTalks[i] == null)
                        {
                            longTalks[i] = temp;
                            longTalks[i].myMistake = PresentationAction.MistakeType.LONG_TALK;
                            break;
                        }
                    }
                    sentMistakes = longTalks;
                    break;
                case PresentationAction.MistakeType.HMMMM:
                    hmmmsMistakes++;
                    for (i = 0; i < interruptionThreshold; i++)
                    {
                        if (hmmms[i] == null)
                        {
                            hmmms[i] = temp;
                            hmmms[i].myMistake = PresentationAction.MistakeType.HMMMM;
                            break;
                        }
                    }
                    sentMistakes = hmmms;
                    break;
            }
            if (i >= interruptionThreshold-1)
            {
                interruptionsList.Add(temp);
                doInterruptionThing();
            }
        }
 //Resets mistakes and judgementmaker after a pause
 public void resetAfterInterruption(PresentationAction mistakeX)
 {
     resetMistakeArray(mistakeX);
     mistakes = new ArrayList();
     previousAction.myMistake = PresentationAction.MistakeType.NOMISTAKE;
     myJudgementMaker = new JudgementMaker(parent);
     noInterrupt = true;
 }
        //MetaValue is how many lists are used under this meta category in this class.        
        private int getMetaValue(PresentationAction temp)
        {
            switch (temp.meta)
            {
                case PresentationAction.MetaType.POSTURE:
                    return 5;

                case PresentationAction.MetaType.HAND_MOVEMENT:
                    return 2;

                case PresentationAction.MetaType.VOLUME:
                    return 2;

                case PresentationAction.MetaType.PHONETIC_PAUSE:
                    return 1;

                case PresentationAction.MetaType.CADENCE:
                    return 3;

                case PresentationAction.MetaType.BODY_MOVEMENT:
                    return 1;

                default:
                    return 1;
            }
        }
        //Calculates the gravity (points) of the given mistake
        private double getGravity(PresentationAction temp)
        {
            double timePoints = 0.5; //every x seconds counts as a mistake.
            double metaMultiplier = 0.5; //how important a meta repetition is.
            double correctionMultiplier = 0.5; //How important a correction is.

            double gravity = 0;
            double lengthPoints = (temp.lengthScore()/1000) / timePoints; //lengthScore() gives back time of mistake in milliseconds

            int tempRep = getRepetition(temp) + 1; // can be zero since repetition is only updated after mistake ended.
            int tempMetaRep = getMetaRepetition(temp) + 1 - tempRep;//  Dont count the repetition of current mistake in meta Repetition

            double metaPoints = ((tempMetaRep / getMetaValue(temp)) * metaMultiplier);
            double tempCorr = getCorrections(temp) * correctionMultiplier;

            double repPoints = tempRep + metaPoints;
            gravity = lengthPoints + repPoints - tempCorr;

            return gravity;
        }
        private void handleMovementsWithAngles()
        {
            double currentTime = DateTime.Now.TimeOfDay.TotalMilliseconds;
            difTime = (currentTime - myVoiceAndMovementObject.timeStarted);
            armMovementsCalc.calcArmMovements();
            if(timeLastGesture==0)
            {
                timeLastGesture = currentTime;
            }
            if(armMovementsCalc.currentGesture!=PresentationTrainer.ArmMovementsCalc.Gesture.nogesture)
            {
                timeLastGesture = currentTime;
                timePreviousPauses = 0;
            }
            timeBetweenGestures = currentTime - timeLastGesture + timePreviousPauses;
            if (timeBetweenGestures>5000)
            { 
                PresentationAction pa = new PresentationAction(PresentationAction.MistakeType.HANDS_NOT_MOVING);
                pa.timeStarted = myVoiceAndMovementObject.timeStarted;
                pa.isVoiceAndMovementMistake = true;
                if (myVoiceAndMovementObject.firstImage != null)
                {
                    System.Windows.Media.ImageSource im = parent.videoHandler.kinectImage.Source;
                    //  pa.firstImage = myVoiceAndMovementObject.firstImage.CloneCurrentValue();
                    myVoiceAndMovementObject.lastImage = im.CloneCurrentValue();
                    //  pa.lastImage = im.CloneCurrentValue();
                }

                audioMovementMistakeTempList.Add(pa);
            }
        }
 private void handleHmmm()
 {
     if(apa.foundHmmm==true)
     {
         PresentationAction pa = new PresentationAction(PresentationAction.MistakeType.HMMMM);
         pa.timeStarted = myVoiceAndMovementObject.timeStarted;
         pa.isVoiceAndMovementMistake = true;
         audioMovementMistakeTempList.Add(pa);
     }
 }
        void getLeftLean()
        {
            bool useAngles = false;

            if (useAngles)
            {
            }
            else
            {
                if (body.Joints[JointType.ShoulderLeft].Position.X > body.Joints[JointType.HipLeft].Position.X)
                {
                    leftLean = true;
                    bodyPosture = Posture.bad;
                    PresentationAction pa = new PresentationAction(PresentationAction.MistakeType.LEFTLEAN);
                    currentMistakes.Add(pa);
                }
                else
                {
                    leftLean = false;
                }
            }
        }
        void getRightLean()
        {
            bool useAngles = false;

            if (useAngles)
            {
            }
            else
            {
                if (body.Joints[JointType.ShoulderRight].Position.X < body.Joints[JointType.HipRight].Position.X)
                {
                    rightLean = true;
                    bodyPosture = Posture.bad;
                    PresentationAction pa = new PresentationAction(PresentationAction.MistakeType.RIGHTLEAN);
                    currentMistakes.Add(pa);
                }
                else
                {
                    rightLean = false;
                }
            }
        }
        public void getLeftHandBehindBack()
        {
            bool useAngles = false;

            if (useAngles)
            {
                double x1 = body.Joints[JointType.HandLeft].Position.X * Math.Sin(shouldersAngle);
                double z1 = body.Joints[JointType.HandLeft].Position.Z * Math.Cos(shouldersAngle);

                double x2 = body.Joints[JointType.SpineMid].Position.X * Math.Sin(shouldersAngle);
                double z2 = body.Joints[JointType.SpineMid].Position.Z * Math.Cos(shouldersAngle);

                if (-x1 + z1 < -x2 + z2)
                {

                    leftHandBehindBack = true;
                    bodyPosture = Posture.bad;
                    PresentationAction pa = new PresentationAction(PresentationAction.MistakeType.LEFTHANDBEHINDBACK);
                    currentMistakes.Add(pa);
                }
                else
                {
                    leftHandBehindBack = false;
                }
            }
            else
            {
                if (body.Joints[JointType.HandLeft].Position.Z > body.Joints[JointType.SpineMid].Position.Z)
                {
                    leftHandBehindBack = true;
                    bodyPosture = Posture.bad;
                    PresentationAction pa = new PresentationAction(PresentationAction.MistakeType.LEFTHANDBEHINDBACK);
                    currentMistakes.Add(pa);
                }
                else
                {
                    leftHandBehindBack = false;
                }
            }
        }
 //Increases repetitions for given mistake
 private void increaseRepetitions(PresentationAction temp)
 {
     switch (temp.myMistake)
     {
         case PresentationAction.MistakeType.ARMSCROSSED:
             crossedArmsMistakes++;
             break;
         case PresentationAction.MistakeType.HANDS_MOVING_MUCH:
             handsMovingMuchMistakes++;
             break;
         case PresentationAction.MistakeType.HANDS_NOT_MOVING:
             handsNotMovingMistakes++;
             break;
         case PresentationAction.MistakeType.HIGH_VOLUME:
             highVolumesMistakes++;
             break;
         case PresentationAction.MistakeType.HMMMM:
             hmmmsMistakes++;
             break;
         case PresentationAction.MistakeType.HUNCHBACK:
             hunchPostureMistakes++;
             break;
         //case PresentationAction.MistakeType.BOTHHANDBEHINDBACK:
         case PresentationAction.MistakeType.LEFTHANDBEHINDBACK:
         case PresentationAction.MistakeType.RIGHTHANDBEHINDBACK:
             handsBehindBackMistakes++;
             break;
         //case PresentationAction.MistakeType.BOTHHANDUNDERHIP:
         case PresentationAction.MistakeType.LEFTHANDUNDERHIP:
         case PresentationAction.MistakeType.RIGHTHANDUNDERHIP:
             handsUnderHipsMistakes++;
             break;
         case PresentationAction.MistakeType.LONG_PAUSE:
             longPausesMistakes++;
             break;
         case PresentationAction.MistakeType.LONG_TALK:
             longTalksMistakes++;
             break;
         case PresentationAction.MistakeType.LOW_MODULATION:
             noModulationMistakes++;
             break;
         case PresentationAction.MistakeType.LOW_VOLUME:
             lowVolumesMistakes++;
             break;
         case PresentationAction.MistakeType.LEFTLEAN:
         case PresentationAction.MistakeType.RIGHTLEAN:
             leaningPostureMistakes++;
             break;
         case PresentationAction.MistakeType.DANCING:
             periodicMovementsMistakes++;
             break;
         default:
             break;
     }
 }
        //This method plays an event and handles getting the correct images for the given mistake entry.
        private void doFeedbackEventStuff()
        {
            double currentTime = DateTime.Now.TimeOfDay.TotalMilliseconds;


            // decision formula returns integer of the place of the mistake to be feedbacked within the mistakes list.
            int feedbackMistakeEntry = 0;
            feedbackMistakeEntry = decisionFormula();
            ((PresentationAction)mistakes[feedbackMistakeEntry]).timeFinished = currentTime;


            if (previousAction.myMistake != ((PresentationAction)mistakes[feedbackMistakeEntry]).myMistake)
            {
                if (((PresentationAction)mistakes[feedbackMistakeEntry]).myMistake == PresentationAction.MistakeType.HANDS_NOT_MOVING)
                {
                    ((PresentationAction)mistakes[feedbackMistakeEntry]).firstImage = myJudgementMaker.myVoiceAndMovementObject.firstImage;
                    ((PresentationAction)mistakes[feedbackMistakeEntry]).lastImage = myJudgementMaker.myVoiceAndMovementObject.lastImage;
                }
                feedBackEvent(this, (PresentationAction)mistakes[feedbackMistakeEntry]); //Somehow this gives null reference!?
                //checkWhereToPutMistake(); 
                if (noInterrupt == true)
                {
                    previousAction = (PresentationAction)mistakes[feedbackMistakeEntry];
                }

            }
            else if (((PresentationAction)mistakes[feedbackMistakeEntry]).interrupt == true)
            {
                //checkWhereToPutMistake(); 
                bigMistakeInterruption(feedbackMistakeEntry);

            }

        }
        private void handleVolume()
        {
            double currentTime = DateTime.Now.TimeOfDay.TotalMilliseconds;
            if(myVoiceAndMovementObject.minVolume==0)
            {
                myVoiceAndMovementObject.minVolume = apa.averageVolume;
                myVoiceAndMovementObject.maxVolume = apa.averageVolume;
            }
            if(apa.averageVolume<myVoiceAndMovementObject.minVolume)
            {
                myVoiceAndMovementObject.minVolume = apa.averageVolume;
            }
            if(apa.averageVolume>myVoiceAndMovementObject.maxVolume)
            {
                myVoiceAndMovementObject.maxVolume = apa.averageVolume;
            }
            if(apa.averageVolume>apa.ThresholdIsSpeakingLoud)
            {
                LowVolume = null;
                if(highVolume==null)
                {
                    highVolume = new PresentationAction(PresentationAction.MistakeType.HIGH_VOLUME);
                    highVolume.isVoiceAndMovementMistake = true;
                }
                if (currentTime - highVolume.timeStarted  > TIME_TO_CONSIDER_ACTION)
                {
                    
                    audioMovementMistakeTempList.Add(highVolume);
                }
            }
            else if(apa.averageVolume<apa.ThresholdIsSpeakingSoft)
            {
                highVolume = null;

                if (LowVolume == null)
                {
                    LowVolume = new PresentationAction(PresentationAction.MistakeType.LOW_VOLUME);
                    LowVolume.isVoiceAndMovementMistake = true;
                }
                if (currentTime - LowVolume.timeStarted > TIME_TO_CONSIDER_ACTION)
                {
                    audioMovementMistakeTempList.Add(LowVolume);
                }
            }
            else
            {
                highVolume = null;
                LowVolume = null;
            }
            if(currentTime - myVoiceAndMovementObject.timeStarted>3000 && 
                myVoiceAndMovementObject.maxVolume- myVoiceAndMovementObject.minVolume < 0.001)
            {
                PresentationAction pa = new PresentationAction(PresentationAction.MistakeType.LOW_MODULATION);
                {
                    pa.timeStarted = myVoiceAndMovementObject.timeStarted;
                    pa.isVoiceAndMovementMistake = true;
                    audioMovementMistakeTempList.Add(pa);
                }
            }


        }
        //Gets the repetition of the metamistake the given mistake belongs to.
        private int getMetaRepetition(PresentationAction temp)
        {
            int previousMistakes = 0;
            switch (temp.meta)
            {
                case PresentationAction.MetaType.POSTURE:
                    previousMistakes = (int) (previousleaningPostureMistakes + previoushunchPostureMistakes + previoushandsUnderHipsMistakes + previoushandsBehindBackMistakes + previouscrossedArmsMistakes);
                    return leaningPostureMistakes + hunchPostureMistakes + handsUnderHipsMistakes + handsBehindBackMistakes + crossedArmsMistakes + previousMistakes;

                case PresentationAction.MetaType.HAND_MOVEMENT:
                    previousMistakes = (int) (previoushandsNotMovingMistakes + previoushandsMovingMuchMistakes);
                    return handsNotMovingMistakes + handsMovingMuchMistakes + previousMistakes;

                case PresentationAction.MetaType.VOLUME:
                    previousMistakes = (int) (previouslowVolumesMistakes + previoushighVolumesMistakes);
                    return lowVolumesMistakes + highVolumesMistakes + previousMistakes;

                case PresentationAction.MetaType.PHONETIC_PAUSE:
                    previousMistakes = (int) previoushmmmsMistakes;
                    return hmmmsMistakes + previousMistakes;

                case PresentationAction.MetaType.CADENCE:
                    previousMistakes = (int) (previousnoModulationMistakes + previouslongPausesMistakes + previouslongTalksMistakes);
                    return noModulationMistakes + longPausesMistakes + longTalksMistakes + previousMistakes;

                case PresentationAction.MetaType.BODY_MOVEMENT:
                    previousMistakes = (int) previousperiodicMovementsMistakes;
                    return periodicMovementsMistakes + previousMistakes;

                default:
                    return 0;
            }
        }
        public void handlePauses()
        {
            double currentTime = DateTime.Now.TimeOfDay.TotalMilliseconds;
            timePausing =  currentTime - myVoiceAndMovementObject.timeStarted;
            if (timePausing > apa.ThresholdIsLongPauseTime)
            {
                PresentationAction pa = new PresentationAction(PresentationAction.MistakeType.LONG_PAUSE);
                pa.timeStarted = myVoiceAndMovementObject.timeStarted;
                pa.isVoiceAndMovementMistake = true;
                if (currentTime - myVoiceAndMovementObject.timeStarted > apa.ThresholdIsVeryLongPauseTime)
                {
                    //pa.interrupt = true;
                }

                audioMovementMistakeTempList.Add(pa);
                
            }
        }
 //Gets the number of corrections of the given mistake.
 private int getCorrections(PresentationAction temp)
 {
     int previousCorrections = 0;
     switch (temp.myMistake)
     {
         case PresentationAction.MistakeType.ARMSCROSSED:
             previousCorrections = (int)previouscrossedArmsCorrections;
             return crossedArmsCorrections + previousCorrections;
         case PresentationAction.MistakeType.HANDS_MOVING_MUCH:
             previousCorrections = (int)previoushandsMovingMuchCorrections;
             return handsMovingMuchCorrections + previousCorrections;
         case PresentationAction.MistakeType.HANDS_NOT_MOVING:
             previousCorrections = (int)previoushandsNotMovingCorrections;
             return handsNotMovingCorrections + previousCorrections;
         case PresentationAction.MistakeType.HIGH_VOLUME:
             previousCorrections = (int)previoushighVolumesCorrections;
             return highVolumesCorrections + previousCorrections;
         case PresentationAction.MistakeType.HMMMM:
             previousCorrections = (int)previoushmmmsCorrections;
             return hmmmsCorrections + previousCorrections;
         case PresentationAction.MistakeType.HUNCHBACK:
             previousCorrections = (int)previoushunchPostureCorrections;
             return hunchPostureCorrections + previousCorrections;
         //case PresentationAction.MistakeType.BOTHHANDBEHINDBACK:
         case PresentationAction.MistakeType.LEFTHANDBEHINDBACK:
         case PresentationAction.MistakeType.RIGHTHANDBEHINDBACK:
             previousCorrections = (int)previoushandsBehindBackCorrections;
             return handsBehindBackCorrections + previousCorrections;
         //case PresentationAction.MistakeType.BOTHHANDUNDERHIP:
         case PresentationAction.MistakeType.LEFTHANDUNDERHIP:
         case PresentationAction.MistakeType.RIGHTHANDUNDERHIP:
             previousCorrections = (int)previoushandsUnderHipsCorrections;
             return handsUnderHipsCorrections + previousCorrections;
         case PresentationAction.MistakeType.LONG_PAUSE:
             previousCorrections = (int)previouslongPausesCorrections;
             return longPausesCorrections + previousCorrections;
         case PresentationAction.MistakeType.LONG_TALK:
             previousCorrections = (int)previouslongTalksCorrections;
             return longTalksCorrections + previousCorrections;
         case PresentationAction.MistakeType.LOW_MODULATION:
             previousCorrections = (int)previousnoModulationCorrections;
             return noModulationCorrections + previousCorrections;
         case PresentationAction.MistakeType.LOW_VOLUME:
             previousCorrections = (int)previouslowVolumesCorrections;
             return lowVolumesCorrections + previousCorrections;
         case PresentationAction.MistakeType.LEFTLEAN:
         case PresentationAction.MistakeType.RIGHTLEAN:
             previousCorrections = (int)previousleaningPostureCorrections;
             return leaningPostureCorrections + previousCorrections;
         case PresentationAction.MistakeType.DANCING:
             previousCorrections = (int)previousperiodicMovementsCorrections;
             return periodicMovementsCorrections + previousCorrections;
         default:
             return 0;
     }
 }
 private bool checkTimeToPutMistake(PresentationAction fa)
 {
     bool result = false;
     double currentTime = DateTime.Now.TimeOfDay.TotalMilliseconds;
     if (currentTime - fa.timeStarted > TIME_TO_CONSIDER_ACTION)
     {
         result = true;
     }
     return result;
 }
 //Resets the mistake lists after an interruption.
 private void resetMistakeArray(PresentationAction mistakeX)
 {
     switch (((PresentationAction)mistakeX).myMistake)
     {
         case PresentationAction.MistakeType.ARMSCROSSED:
             crossedArmsList.AddRange(crossedArms);
             crossedArms = new PresentationAction[interruptionThreshold];
             //crossedArmsMistakes++;
             break;
         //case PresentationAction.MistakeType.BOTHHANDBEHINDBACK:
         case PresentationAction.MistakeType.LEFTHANDBEHINDBACK:
         case PresentationAction.MistakeType.RIGHTHANDBEHINDBACK:
             handsBehindBackList.AddRange(handsBehindBack);
             handsBehindBack = new PresentationAction[interruptionThreshold];
             //handsBehindBackMistakes++;
             break;
         case PresentationAction.MistakeType.LEGSCROSSED:
             legsCrossedList.AddRange(legsCrossed);
             legsCrossed = new PresentationAction[interruptionThreshold];
             //legsCrossedMistakes++;
             break;
         //case PresentationAction.MistakeType.BOTHHANDUNDERHIP:
         case PresentationAction.MistakeType.RIGHTHANDUNDERHIP:
         case PresentationAction.MistakeType.LEFTHANDUNDERHIP:
             handsUnderHipsList.AddRange(handsUnderHips);
             handsUnderHips = new PresentationAction[interruptionThreshold];
             //handsUnderHipsMistakes++;
             break;
         case PresentationAction.MistakeType.HUNCHBACK:
             hunchPostureList.AddRange(hunchPosture);
             hunchPosture = new PresentationAction[interruptionThreshold];
             //hunchPostureMistakes++;
             break;
         case PresentationAction.MistakeType.RIGHTLEAN:
         case PresentationAction.MistakeType.LEFTLEAN:
             leaningPostureList.AddRange(leaningPosture);
             leaningPosture = new PresentationAction[interruptionThreshold];
             //leaningPostureMistakes++;
             break;
         case PresentationAction.MistakeType.DANCING:
             periodicMovementsList.AddRange(periodicMovements);
             periodicMovements = new PresentationAction[interruptionThreshold];
             //periodicMovementsMistakes++;
             break;
         case PresentationAction.MistakeType.HANDS_NOT_MOVING:
             handsNotMovingList.AddRange(handsNotMoving);
             handsNotMoving = new PresentationAction[interruptionThreshold];
             //handsNotMovingMistakes++;
             break;
         case PresentationAction.MistakeType.HANDS_MOVING_MUCH:
             handsMovingMuchList.AddRange(handsMovingMuch);
             handsMovingMuch = new PresentationAction[interruptionThreshold];
             //handsMovingMuchMistakes++;
             break;
         case PresentationAction.MistakeType.HIGH_VOLUME:
             highVolumesList.AddRange(highVolumes);
             highVolumes = new PresentationAction[interruptionThreshold];
             //highVolumesMistakes++;
             break;
         case PresentationAction.MistakeType.LOW_VOLUME:
             lowVolumesList.AddRange(lowVolumes);
             lowVolumes = new PresentationAction[interruptionThreshold];
             //lowVolumesMistakes++;
             break;
         case PresentationAction.MistakeType.LOW_MODULATION:
             noModulationList.AddRange(noModulation);
             noModulation = new PresentationAction[interruptionThreshold];
             //noModulationMistakes++;
             break;
         case PresentationAction.MistakeType.LONG_PAUSE:
             longPausesList.AddRange(longPauses);
             longPauses = new PresentationAction[interruptionThreshold];
             //longPausesMistakes++;
             break;
         case PresentationAction.MistakeType.LONG_TALK:
             longTalksList.AddRange(longTalks);
             longTalks = new PresentationAction[interruptionThreshold];
             //longTalksMistakes++;
             break;
         case PresentationAction.MistakeType.HMMMM:
             hmmmsList.AddRange(hmmms);
             hmmms = new PresentationAction[interruptionThreshold];
             //hmmmsMistakes++;
             break;
     }
 }
 public void getLeftHandUnderHip()
 {
     if (body.Joints[JointType.HandLeft].Position.Y < body.Joints[JointType.HipLeft].Position.Y)
     {
         leftHandUnderHips = true;
         bodyPosture = Posture.bad;
         PresentationAction pa = new PresentationAction(PresentationAction.MistakeType.LEFTHANDUNDERHIP);
         currentMistakes.Add(pa);
     }
     else
     {
         leftHandUnderHips = false;
     }
 }
        private void searchMistakes()
        {

            addBodyMistakes();
            deleteBodyMistakes();
            findMistakesInVoiceAndMovement();
            deleteVoiceAndMovementsMistakes();
            mistakeList = new ArrayList(bodyMistakes);
            mistakeList.AddRange(audioMovementMistakeTempList);
            
            if(bfpa.body!=null)
            {
                if (periodicMovements.checPeriodicMovements(bfpa.body))
                {
                    PresentationAction pa = new PresentationAction(PresentationAction.MistakeType.DANCING);
                    //pa.interrupt = true;
                   // periodicMov = true;
                    mistakeList.Insert(0, pa);
                }

            }
           
            

           //todo add mistakes together
        }
        public void getLegsCrossed()
        {
             bool useAngles = false;
             if (useAngles)
             {

             }
             else
             {
                 if (body.Joints[JointType.FootRight].Position.X < body.Joints[JointType.FootLeft].Position.X)
                 {
                     legsCrossed = true;
                     bodyPosture = Posture.bad;
                     PresentationAction pa = new PresentationAction(PresentationAction.MistakeType.LEGSCROSSED);
                     currentMistakes.Add(pa);
                 }
                 else
                 {
                     legsCrossed = false;
                 }
             }
        }
 private bool findMistakeInMistakeList(PresentationAction fb)
 {
     bool found = false;
     foreach (PresentationAction fa in mistakeList)
     {
         if (fb.myMistake == fa.myMistake)
         {
             found = true;
             break;
         }
     }
     return found;
 }
        private void handleHandMovements()
        {

            double currentTime = DateTime.Now.TimeOfDay.TotalMilliseconds;

            CameraSpacePoint handLeft = bfpa.body.Joints[JointType.HandLeft].Position;
            CameraSpacePoint handRight = bfpa.body.Joints[JointType.HandRight].Position;
            CameraSpacePoint hipLeft = bfpa.body.Joints[JointType.HipLeft].Position;
            CameraSpacePoint hipRight = bfpa.body.Joints[JointType.HipRight].Position;

            double leftDistance = Math.Sqrt(
                (handLeft.X - hipLeft.X) * (handLeft.X - hipLeft.X) +
                (handLeft.Y - hipLeft.Y) * (handLeft.Y - hipLeft.Y) +
                (handLeft.Z - hipLeft.Z) * (handLeft.Z - hipLeft.Z));

            double rightDistance = Math.Sqrt(
                (handRight.X - hipRight.X) * (handRight.X - hipRight.X) +
                (handRight.Y - hipRight.Y) * (handRight.Y - hipRight.Y) +
                (handRight.Z - hipRight.Z) * (handRight.Z - hipRight.Z));

            if (myVoiceAndMovementObject.leftHandHipDistance == 0)
            {
                myVoiceAndMovementObject.leftHandHipDistance = leftDistance;
                myVoiceAndMovementObject.rightHandHipDistance = rightDistance;
            }

            double rightMovement = Math.Abs(myVoiceAndMovementObject.rightHandHipDistance - rightDistance);
            double leftMovement = Math.Abs(myVoiceAndMovementObject.leftHandHipDistance - leftDistance);

            myVoiceAndMovementObject.leftHandHipDistance = leftDistance;
            myVoiceAndMovementObject.rightHandHipDistance = rightDistance;

            double currentHandMovement = rightMovement;

            if (rightMovement > leftMovement)
            {
                myVoiceAndMovementObject.totalHandMovement = myVoiceAndMovementObject.totalHandMovement + rightMovement * HandMovementFactor;
            }
            else
            {
                currentHandMovement = leftMovement;
                myVoiceAndMovementObject.totalHandMovement = myVoiceAndMovementObject.totalHandMovement + leftMovement * HandMovementFactor;
            }

            double difTime = (currentTime - myVoiceAndMovementObject.timeStarted);
            if (difTime > 0)
            {
                myVoiceAndMovementObject.averageHandMovement = myVoiceAndMovementObject.totalHandMovement / difTime;
            }

            if (myVoiceAndMovementObject.averageHandMovement < 1)//&& currentHandMovement < 0.006)
            {
                PresentationAction pa = new PresentationAction(PresentationAction.MistakeType.HANDS_NOT_MOVING);
                pa.timeStarted = myVoiceAndMovementObject.timeStarted;
                pa.isVoiceAndMovementMistake = true;
                if (myVoiceAndMovementObject.firstImage != null)
                {
                    System.Windows.Media.ImageSource im = parent.videoHandler.kinectImage.Source;
                    //  pa.firstImage = myVoiceAndMovementObject.firstImage.CloneCurrentValue();
                    myVoiceAndMovementObject.lastImage = im.CloneCurrentValue();
                    //  pa.lastImage = im.CloneCurrentValue();
                }

                audioMovementMistakeTempList.Add(pa);
            }
            else if (difTime > 2000) //use for debugging
            {
                int aa = 0;
                aa++;
                //     myVoiceAndMovementObject.totalHandMovement = difTime + 1000;
            }
        }