/// <summary>
        ///  Gets the distance between the played frequency to the open note by percentage.
        /// </summary>
        /// <param name="twoClosestOpenNotes">The two closest open notes to the frequency.</param> 
        /// <param name="closestNote">The most closest note, out of the two closest notes, 
        /// which will be used as a reference to calculate the difference between this and the playedFrequency.</param>
        /// <param name="playedFrequency">The note that the user hits translated to frequency [Hz].</param>
        /// <returns>How close the users' frequency is from the desired note.</returns>
        private NoteDifference CalculateRatioOfCloseness(UpperAndLowerNotes twoClosestOpenNotes, Note closestNote, Hz playedFrequency)
        {
            float closenessToMark; //Closeness to the exact note mark. Number between 0 and 1.
            NoteDifference noteDiff = new NoteDifference();

            //Represents how close the frequency is from the closestNote.
            float difference = Math.Abs(playedFrequency - closestNote.Hertz);

            float middleOfTwoOpenNotes = Math.Abs(twoClosestOpenNotes.Upper.Hertz - twoClosestOpenNotes.Lower.Hertz) / 2;

            if (middleOfTwoOpenNotes != 0)
                //Calculate the closness to the closestNote.
                closenessToMark = difference / middleOfTwoOpenNotes; //FIX: Why is that?
            else
                closenessToMark = difference;
            //Calculate the alpha (opacity) of the note indicator.
            //noteDiff.ClosnessAlpha = NoteDifference.FULL_ALPHA - closenessToMark;
            //Calculate the closness by a precentage of base 90.
            noteDiff.ClosnessByPercentage_Base90 = closenessToMark * 90; //FIX: This is not a precentage!
            noteDiff.ClosestNote = closestNote.Name;

            if (playedFrequency < closestNote.Hertz)
            {
                //from -90 to 0 degrees.
                noteDiff.ClosnessByPercentage_Base90 *= (-1);
                //if (closestNote.Alias != null)
                //    noteDiff.ClosestNote = closestNote.Alias;
            }

            return noteDiff;
        }
        /// <summary>
        /// Constructs a new representation as a visual ball with a number of string in its center.
        /// </summary>
        /// <param name="currentActivity">The activity on which the ball should be drawn.</param>
        /// <param name="note">The note that should be played correspondingly when visually arriving to the guitar's neck.</param>
        public NoteRepresentation(Activity currentActivity, Note note)
        {
            //Basic values.
            _currentActivity = currentActivity;
            _note = note;

            //The color of the ball.
            BallColor ballColor = (BallColor)note.Position.String; //note.Position.Fret;
            //Which string the number on the ball should represent.
            //GuitarString stringNum = note.Position.String;

            _noteCircle = new TextView(_currentActivity);

            //Select the ball's color.
            switch (ballColor)
            {
                case BallColor.Red:
                    _noteCircle.SetBackgroundResource(Resource.Drawable.ball_red);
                    break;
                case BallColor.Purple:
                    _noteCircle.SetBackgroundResource(Resource.Drawable.ball_purple);
                    break;
                case BallColor.Blue:
                    _noteCircle.SetBackgroundResource(Resource.Drawable.ball_blue);
                    break;
                case BallColor.Green:
                    _noteCircle.SetBackgroundResource(Resource.Drawable.ball_green);
                    break;
                case BallColor.Orange:
                    _noteCircle.SetBackgroundResource(Resource.Drawable.ball_orange);
                    break;
                case BallColor.Aqua:
                    _noteCircle.SetBackgroundResource(Resource.Drawable.ball_aqua);
                    break;
                case BallColor.Yellow:
                    _noteCircle.SetBackgroundResource(Resource.Drawable.ball_yellow);
                    break;
            }

            //Set dimensions.
            _noteCircle.Layout(0, 0, BUTTON_WIDTH, BUTTON_HEIGHT);
            //Center text.
            _noteCircle.Gravity = GravityFlags.Center;
            //Set text.
            //_noteCircle.SetText(((int)stringNum).ToString(), TextView.BufferType.Normal);
            //Refresh view.
            _noteCircle.RequestLayout();

            //Add the newly created note circle to the current activity.
            _currentActivity.AddContentView(_noteCircle, new ViewGroup.LayoutParams(BUTTON_WIDTH, BUTTON_HEIGHT));
        }
 public void SpotAnimateAllPositionsOfANote(Note note)
 {
     List<ObjectAnimator> animationsList = new List<ObjectAnimator>();
     foreach (Position position in note.Positions)
     {
         //Create a new visual representation of that note.
         NoteRepresentation noteRep = new NoteRepresentation(_activity, note);
         //Set name on note.
         noteRep.SetText(note.Name);
         //Create the note's animation, and add that animation to the animations array.
         animationsList.Add(noteRep.CreateNoteAnimation_FadeOnly(position));
     }
     AnimatorSet animatorSet = new AnimatorSet();
     animatorSet.PlayTogether(animationsList.ToArray());
     animatorSet.Start();
 }
        /// <summary>
        /// Get the position which has the
        /// closest fret, unless it's on the same string and it's open.
        /// </summary>
        /// <param name="previousNote">The note from which to measure.</param>
        /// <param name="currentNote">The note which its position needs to be calculated.</param>
        /// <returns>Returns a position of the currentNote which is relativly closest from previousNote.</returns>
        private Position CalculateClosestPositionFromPreviousNote(Note previousNote, Note currentNote)
        {
            if (currentNote.Positions.Length == 1)
                return currentNote.Positions[0];

            int[] fretsDistances = new int[currentNote.Positions.Length];
            int[] stringsDistances = new int[currentNote.Positions.Length];
            Position closestPosition = null;

            for (int i = 0; i < currentNote.Positions.Length; i++)
            {
                fretsDistances[i] = Math.Abs(previousNote.Position.Fret - currentNote.Positions[i].Fret);
                stringsDistances[i] = Math.Abs(previousNote.Position.Fret - currentNote.Positions[i].Fret);

                if (i > 0)
                {
                    if (stringsDistances[i] == 0 && currentNote.Positions[i].Fret == GuitarFret.OpenString)
                        closestPosition = currentNote.Positions[i];
                    else if ((stringsDistances[i - 1] == 0 && currentNote.Positions[i - 1].Fret == GuitarFret.OpenString)
                        || fretsDistances[i - 1] < fretsDistances[i])
                        closestPosition = currentNote.Positions[i - 1];
                    else
                        closestPosition = currentNote.Positions[i];
                }
            }

            return closestPosition;
        }
        /// <summary>
        /// Reads a sequence from a *.vgts file.
        /// </summary>
        /// <param name="fileName">The file's name (no extension).</param>
        /// <returns>Returns the sequence of that file.</returns>
        protected Sequence SequenceReader(string fileName)
        {
            //string songsFolderPath = _activity.Resources.GetString(Resource.String.SongsFolderPath);

            string[] sequenceLines = GetFileLinesFromAssets(fileName + SONG_FILE_EXTENSION, _activity.Assets);

            DiscardCommentsAndEmptyLines(ref sequenceLines);

            Sequence sequence = new Sequence(sequenceLines.Length);
            string[] lineSegments;
            Notes notesReference = new Notes();

            for (int i = 0; i < sequenceLines.Length; i++)
            {
                string line = sequenceLines[i];
                lineSegments = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                NoteName noteName;
                double delay, duration;

                bool isNoteName = NoteName.TryParse(lineSegments[0], out noteName);
                bool isDouble1 = double.TryParse(lineSegments[1], out delay);
                bool isDouble2 = double.TryParse(lineSegments[2], out duration);
                
                if (!(isNoteName && isDouble1 && isDouble2))
                    throw new Exception("Parsing segments of song file failed. "
                        + "Only the following format is allowed: string double double. "
                        + "And make sure the string name is spelled correctly.");

                Note note = notesReference[noteName];

                if (i == 0)
                    note = new Note(noteName,
                    note.Positions[0],
                    delay,
                    duration);
                else
                    note = new Note(noteName,
                    CalculateClosestPositionFromPreviousNote(sequence[i - 1], note),
                    delay,
                    duration);

                sequence[i] = note;
            }
            return sequence;
        }
 public UpperAndLowerNotes(Note lower, Note upper)
 {
     //Initial values.
     _upper = upper;
     _lower = lower;
 }