/// <summary>
        /// Render a note.
        /// </summary>
        /// <param name="note">Information for the note to render</param>
        /// <returns>A note rendered on a Fraemwork Element</returns>
        private static FrameworkElement RenderNoteHead(Note note, double fontSize)
        {
            //todo: chords
            //todo: different shapes of note heads
            Panel noteHeadGrid = WPFRendering.CreateAutoSizingGrid();
            FrameworkElement noteHead = new Label();
            FrameworkElement noteHeadInside = new Label();

            if (string.IsNullOrEmpty(note.color))
                note.color = Constants.Colors.DEFAULT_NOTE_COLOR;
            Brush noteBrush = new SolidColorBrush((Color)ColorConverter.ConvertFromString(note.color));

            RotateTransform hollowRT = new RotateTransform();

            bool rotateHead = false;
            bool hollow = false;
            double noteHeadHeight = WPFRendering.GetFontFraction(12, fontSize);
            double noteHeadWidth = noteHeadHeight * 1.5;

            switch (note.type.Value)
            {
                //todo: size note heads using width expected for font
                case NoteTypeValue.whole:
                    // make outside
                    // todo: made this into a function
                    noteHead = new Ellipse() { Fill = noteBrush, Height = noteHeadHeight, Width = noteHeadWidth };
                    hollow = true;
                    // make hole
                    noteHeadInside = new Ellipse() { Fill = new SolidColorBrush(Colors.White), Height = noteHeadHeight * 0.6, Width = noteHeadWidth / 2 };
                    hollowRT.Angle = Constants.Note.HeadRotations.WHOLE_NOTE_HOLLOW; //todo: make this rotation a constant, note same as head rotation
                    break;
                case NoteTypeValue.half:
                    // make outside
                    noteHead = new Ellipse() { Fill = noteBrush, Height = noteHeadHeight, Width = noteHeadWidth };
                    rotateHead = true;
                    hollow = true;
                    // make hole
                    noteHeadInside = new Ellipse() { Fill = new SolidColorBrush(Colors.White), Height = noteHeadHeight * 0.7, Width = noteHeadWidth * .8 };
                    hollowRT.Angle = Constants.Note.HeadRotations.HALF_NOTE_HOLLOW; //todo: make this rotation a constant, note same as head rotation
                    break;
                case NoteTypeValue.quarter:
                    noteHead = new Ellipse() { Fill = noteBrush, Height = noteHeadHeight, Width = noteHeadWidth };
                    rotateHead = true;
                    break;
                case NoteTypeValue.eighth:
                    noteHead = new Ellipse() { Fill = noteBrush, Height = noteHeadHeight, Width = noteHeadWidth };
                    rotateHead = true;
                    break;
                case NoteTypeValue.Item16th:
                    noteHead = new Ellipse() { Fill = noteBrush, Height = noteHeadHeight, Width = noteHeadWidth };
                    rotateHead = true;
                    break;
                case NoteTypeValue.Item32nd:
                    noteHead = new Ellipse() { Fill = noteBrush, Height = noteHeadHeight, Width = noteHeadWidth };
                    rotateHead = true;
                    break;
                case NoteTypeValue.Item64th:
                    noteHead = new Ellipse() { Fill = noteBrush, Height = noteHeadHeight, Width = noteHeadWidth };
                    rotateHead = true;
                    break;
                case NoteTypeValue.Item128th:
                    noteHead = new Ellipse() { Fill = noteBrush, Height = noteHeadHeight, Width = noteHeadWidth };
                    rotateHead = true;
                    break;
                case NoteTypeValue.Item256th:
                    rotateHead = true;
                    break;
                case NoteTypeValue.Item512th:
                    rotateHead = true;
                    break;
            }

            // perform head rotation and add to the notehead grid
            if (rotateHead)
                RotateNoteHead(noteHead);
            noteHeadGrid.Children.Add(noteHead);

            // if it is hallow, add the hallow center
            if (hollow)
            {
                noteHeadInside.LayoutTransform = hollowRT;
                noteHeadGrid.Children.Add(noteHeadInside);
            }

            WPFRendering.RecalculateSize(noteHead);
            WPFRendering.RecalculateSize(noteHeadGrid);
            //todo: Render modifiers

            return noteHeadGrid;
        }
        /// <summary>
        /// Render a rest
        /// </summary>
        /// <param name="note">Representation of the rest to render</param>
        /// <returns>The rest rendered on a Framework Element</returns>
        private static FrameworkElement RenderRest(Note note, double fontSize)
        {
            string restChar = "";
            switch (note.type.Value)
            {
                case NoteTypeValue.whole:
                    restChar = Constants.RestCharacters.WHOLE_REST;
                    break;
                case NoteTypeValue.half:
                    restChar = Constants.RestCharacters.HALF_REST;
                    break;
                case NoteTypeValue.quarter:
                    restChar = Constants.RestCharacters.QUARTER_REST;
                    break;
                case NoteTypeValue.eighth:
                    restChar = Constants.RestCharacters.EIGHTH_REST;
                    break;
                case NoteTypeValue.Item16th:
                    restChar = Constants.RestCharacters.SIXTEETH_REST;
                    break;
                case NoteTypeValue.Item32nd:
                    restChar = Constants.RestCharacters.THIRTYSECOND_REST;
                    break;
                case NoteTypeValue.Item64th:
                    restChar = Constants.RestCharacters.SIXTYFOURTH_REST;
                    break;
                case NoteTypeValue.Item128th:
                    restChar = Constants.RestCharacters.ONETWENTYEIGHTH_REST;
                    break;
                case NoteTypeValue.Item256th:
                    restChar = "!";
                    break;
                case NoteTypeValue.Item512th:
                    restChar = "!";
                    break;
            }
            //todo: it is a rest
            FrameworkElement restLabel = WPFRendering.GetMusicalLabel(restChar, fontSize);

            WPFRendering.RecalculateSize(restLabel);
            return restLabel;
        }
        //todo: put note rendering into its own class
        /// <summary>
        /// Parse the contents of a note and prepare the basic label
        /// </summary>
        /// <param name="note">The note to parse and create a label for</param>
        /// <param name="fontSize">The size of the font being used</param>
        /// <param name="clefSign">The sign of the clef for this note. Default is G</param>
        /// <returns>A label with the note in it</returns>
        public static Panel RenderNoteOrRest(Note note, double fontSize, ClefSign clefSign = ClefSign.G)
        {
            double yOffset = WPFRendering.GetFontFraction(-2, fontSize); //offset cause not exactly in right spot
            //todo: Render appropriate connectors
            //todo: render barline
            //todo: tuplets, triplets, beams

            //todo: likely remove this whole function because will need to draw own notes due to stem when beaming
            String noteChar = Constants.Note.Characters.WHOLE_NOTE;
            Panel grid = WPFRendering.CreateAutoSizingGrid();

            //todo: if it has a rest, then parse as rest, otherwise parse as note
            bool isRest = note.Items.SingleOrDefault(i => i.GetType() == typeof(Rest)) != null;
            if (!isRest)
            {
                FrameworkElement noteHead = RenderNoteHead(note, fontSize);
                noteHead.Margin = new Thickness(noteHead.Margin.Left, noteHead.Margin.Top + yOffset, noteHead.Margin.Right, noteHead.Margin.Bottom);
                grid.Children.Add(noteHead);

                //todo: stems when beamed... This will likely require stems to be drawn after the note heads of the beaming
                //      however, beaming is not supposed to go over measures so this will save some of the problems that this could have

                //get pitch object
                Pitch pitch = (Pitch)note.Items.SingleOrDefault(t => t.GetType() == typeof (Pitch));

                if (pitch != null)
                {
                    //todo: make into function
                    //move grid up or down appropriately
                    Pitch clefDefaultPitch = GetDefaultPitch(clefSign);

                    int stepDifference = clefDefaultPitch.step - pitch.step + (int.Parse(Constants.Note.TrebelDefaults.PITCH.octave) - int.Parse(pitch.octave)) * 8;
                    if(pitch.step == Step.A || pitch.step == Step.B)
                    {
                        stepDifference -= 7;
                    }

                    // todo: octave
                    var difference = (int.Parse(pitch.octave) - int.Parse(clefDefaultPitch.octave));
                    if (difference != 0)
                    {
                        difference *= 7;
                        stepDifference += (difference < 0) ? difference : -difference;
                    }

                    const double stepDistance = 5.5;
                    double topOffset = WPFRendering.GetFontFraction(39, fontSize);
                    double marginTop = noteHead.Margin.Top + (stepDifference * WPFRendering.GetFontFraction(stepDistance, fontSize)) + topOffset;

                    // create and add note stem
                    System.Windows.Shapes.Line noteStem = new System.Windows.Shapes.Line();
                    if (note.stem.Value != stemvalue.none)
                        noteStem = CreateNoteStem(yOffset, note, noteHead, fontSize);
                    grid.Children.Add(noteStem);

                    // add the note head
                    noteHead.Margin = new Thickness(noteHead.Margin.Left, marginTop, noteHead.Margin.Right, noteHead.Margin.Bottom);
                    noteStem.Margin = new Thickness(noteStem.Margin.Left, marginTop, noteStem.Margin.Right, noteStem.Margin.Bottom);

                    //debug: remove
                    Console.Out.WriteLine("default: " + Constants.Note.TrebelDefaults.PITCH.step + "  " + pitch.step + pitch.octave + "   " + stepDifference);
                }

                // render ledger line if necessary
                if(LineThroughNoteHead(pitch, clefSign))
                {
                    FrameworkElement ledgerLine = RenderLedgerLine(noteHead, fontSize);
                    grid.Children.Add(ledgerLine);
                }

                //todo: accidentals
                //todo: clef change on note
                //todo: other notes?

                //todo: make into function
                //todo: if is above half of the staff, rotate so everything points down
                // rotate head
                /*
                RotateTransform rt = new RotateTransform(180);
                rt.CenterX = noteHead.ActualWidth / 2;
                rt.CenterY = 10 * 3 / 4; //todo: use note height calculation from render notehead
                grid.RenderTransform = rt;
                */
            }
            else
            {
                FrameworkElement restElement = RenderRest(note, fontSize);
                restElement.Margin = new Thickness(0, -WPFRendering.GetFontHeight(fontSize, Constants.MusicFonts.DEFAULT) / 4, 0, 0);
                grid.Children.Add(restElement);
            }

            //grid.VerticalAlignment = VerticalAlignment.Top;
            WPFRendering.RecalculateSize(grid);
            return grid;
        }
        private static System.Windows.Shapes.Line CreateNoteStem(double yOffset, Note note, FrameworkElement noteHead, double fontSize)
        {
            if (String.IsNullOrEmpty(note.stem.color))
                note.stem.color = Constants.Colors.DEFAULT_NOTE_COLOR;

            double stemHeight = WPFRendering.GetFontHeight(fontSize, Constants.MusicFonts.DEFAULT) * 2.5 / 5;

            double y1 = 0;
            double y2 = 0;
            if (note.stem.Value == stemvalue.up)
            {
                y1 = yOffset + noteHead.ActualHeight / 2;
                y2 = yOffset + noteHead.ActualHeight / 2 - stemHeight;
            }
            else if (note.stem.Value == stemvalue.down)
            {
                y1 = yOffset + noteHead.ActualHeight / 2;
                y2 = yOffset + noteHead.ActualHeight / 2 + stemHeight;
            }
            else if (note.stem.Value == stemvalue.@double)
            {
                //TODO: figure this out
            }

            return new System.Windows.Shapes.Line()
            {
                X1 = noteHead.ActualWidth - WPFRendering.GetFontFraction(Constants.Note.STEM_X_OFFSET, fontSize),
                X2 = noteHead.ActualWidth - WPFRendering.GetFontFraction(Constants.Note.STEM_X_OFFSET, fontSize),
                Y1 = y1,
                Y2 = y2,
                StrokeThickness = CalculateLineWidth(fontSize),
                Stroke = new SolidColorBrush((Color)ColorConverter.ConvertFromString(note.stem.color))
            };
        }
        public void ParseSimpleOneNoteStringTest()
        {
            String testString1 = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n" +
                                "<!DOCTYPE score-partwise PUBLIC\n" +
                                "\"-//Recordare//DTD MusicXML 3.0 Partwise//EN\"\n" +
                                "\"http://www.musicxml.org/dtds/partwise.dtd\">\n" +
                                "<score-partwise version=\"3.0\">\n" +
                                "<part-list><score-part id=\"P1\"><part-name>Music</part-name></score-part></part-list>" +
                                "<part id=\"P1\"><measure number=\"1\"><attributes><divisions>1</divisions><key>" +
                                "<fifths>0</fifths></key><time><beats>4</beats><beat-type>4</beat-type></time>" +
                                "<clef><sign>G</sign><line>2</line></clef></attributes>" +
                                "<note><pitch><step>C</step><octave>4</octave></pitch><duration>4</duration>" +
                                "<type>whole</type><stem>up</stem></note></measure></part></score-partwise>";
            // create the expected structure
            Note n = new Note()
            {
                type = new NoteType { Value = NoteTypeValue.whole },
                stem = new Stem { Value = stemvalue.up },
                Items = new object[] { new Pitch { step = Step.C, octave = "4" }, new decimal(4) },
                ItemsElementName = new[] { ItemsChoiceType1.pitch, ItemsChoiceType1.duration }
            };

            ScorePartwisePartMeasure m = new ScorePartwisePartMeasure()
            {
                number = "1",
                Items = new object[]{
                    new Attributes()
                    {
                        divisions = 1,
                        key = new[]
                        {
                            new Key
                                {
                                Items = new object[]
                                {
                                    0
                                },
                                ItemsElementName = new[]
                                {
                                    ItemsChoiceType8.fifths
                                },
                            }
                        },
                        time = new[]
                        {
                            new Time { Beats = "4", BeatType = "4"}
                        },
                        clef = new[]
                        {
                            new Clef
                            {
                                sign = ClefSign.G,
                                line = "2"
                            }
                        }
                    },
                n
                }
            };

            // set expected
            ScorePartwise expected = new ScorePartwise { version = "3.0", part = new ScorePartwisePart[1] };

            // measure part and information
            expected.part[0] = new ScorePartwisePart { measure = new ScorePartwisePartMeasure[1] };
            expected.part[0].measure[0] = m;
            expected.part[0].id = "P1";

            // part list
            expected.partList = new PartList() { scorepart = new ScorePart() { id = "P1", partName = new PartName { Value = "Music" } } };

            ScorePartwise actual = ScorePartwise.Deserialize(testString1);
            CompareProperties(actual.GetType(), actual, expected);
        }
 public static bool LoadFromFile(string fileName, out Note obj)
 {
     Exception exception = null;
     return LoadFromFile(fileName, out obj, out exception);
 }
 /// <summary>
 ///   Deserializes xml markup from file into an note object
 /// </summary>
 /// <param name = "fileName">string xml file to load and deserialize</param>
 /// <param name = "obj">Output note object</param>
 /// <param name = "exception">output Exception value if deserialize failed</param>
 /// <returns>true if this XmlSerializer can deserialize the object; otherwise, false</returns>
 public static bool LoadFromFile(string fileName, out Note obj, out Exception exception)
 {
     exception = null;
     obj = default(Note);
     try
     {
         obj = LoadFromFile(fileName);
         return true;
     }
     catch (Exception ex)
     {
         exception = ex;
         return false;
     }
 }
 public static bool Deserialize(string xml, out Note obj)
 {
     Exception exception = null;
     return Deserialize(xml, out obj, out exception);
 }
 /// <summary>
 ///   Deserializes workflow markup into an note object
 /// </summary>
 /// <param name = "xml">string workflow markup to deserialize</param>
 /// <param name = "obj">Output note object</param>
 /// <param name = "exception">output Exception value if deserialize failed</param>
 /// <returns>true if this XmlSerializer can deserialize the object; otherwise, false</returns>
 public static bool Deserialize(string xml, out Note obj, out Exception exception)
 {
     exception = null;
     obj = default(Note);
     try
     {
         obj = Deserialize(xml);
         return true;
     }
     catch (Exception ex)
     {
         exception = ex;
         return false;
     }
 }