private void saveGlyphIconToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var sizes = new[] { 16, 32, 48, 64, 128, 256 };

            var sfd = new FolderBrowserDialog();

            if (sfd.ShowDialog(this) == DialogResult.OK)
            {
                foreach (var s in sizes)
                {
                    using (var bmp = GlyphPart.BuildGlyph(glyph, s))
                        bmp.Save(Path.Combine(sfd.SelectedPath, s + ".png"), ImageFormat.Png);
                }
            }
        }
        void UpdateGlyph()
        {
            foreach (var g in glyph.Where(t => t != null))
            {
                g.BorderWidth = (Single)nudBorderWidth.Value;
            }
            var gBitmap = GlyphPart.BuildGlyph(glyph, GlyphSize);
            var old     = imageGlyph.Image;

            imageGlyph.Image = gBitmap;
            if (old != null)
            {
                old.Dispose();
            }
        }
        private void generateRandomGlyphToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var rand = new Random();

            for (int i = 0; i < 4; i++)
            {
                var partIndex = rand.Next(0, glyphParts.Count);
                selectedPart = glyphParts[partIndex];

                var t = rand.Next(0, 8);
                for (int k = 0; k < t; k++)
                {
                    var transform = (GlyphPartTransform)rand.Next(0, 3);
                    selectedPart = selectedPart.ApplyTransforms(transform);
                }

                glyph[i] = selectedPart;
            }

            UpdateGlyph();
        }
        public static Bitmap BuildGlyph(GlyphPart[] parts, Int32 size)
        {
            if (size % 16 != 0)
                throw new ArgumentException("Size of the bitmap has to be a multiple of 8!");

            var cellSize = size / 2;

            var bitmap = new Bitmap(size, size);
            using (var gfx = Graphics.FromImage(bitmap))
            {

                if (parts[0] != null)
                    gfx.DrawImageUnscaled(parts[0].GetBitmap(cellSize), 0, 0);
                if (parts[1] != null)
                    gfx.DrawImageUnscaled(parts[1].GetBitmap(cellSize), cellSize, 0);
                if (parts[2] != null)
                    gfx.DrawImageUnscaled(parts[2].GetBitmap(cellSize), 0, cellSize);
                if (parts[3] != null)
                    gfx.DrawImageUnscaled(parts[3].GetBitmap(cellSize), cellSize, cellSize);
            }

            return bitmap;
        }
        private void saveGlyphImageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            int size;

            var sizeDlg = new SizeDialog();

            if (sizeDlg.ShowDialog(this) == DialogResult.OK)
            {
                size = sizeDlg.Size;
            }
            else
            {
                return;
            }

            var sfd = new SaveFileDialog();

            if (sfd.ShowDialog(this) == DialogResult.OK)
            {
                using (var bmp = GlyphPart.BuildGlyph(glyph, size))
                    bmp.Save(sfd.FileName, ImageFormat.Png);
            }
        }
        void AttachEventHandlers()
        {
            lvGlyphs.ItemSelectionChanged += (@s, e) =>
            {
                if (lvGlyphs.SelectedItems.Count == 0) {
                    selectedPart = null;
                    pbPartSelection.Image = null;
                    gbCustomization.Enabled = false;
                }
                else
                {
                    selectedPart = (GlyphPart)lvGlyphs.SelectedItems[0].Tag;
                    pbPartSelection.Image = selectedPart.GetBitmap(128);
                    UpdateColors();
                    gbCustomization.Enabled = true;
                }
            };

            btnRotCW.Click += (@s, e) =>
            {
                if (selectedPart == null)
                    return;

                selectedPart = selectedPart.ApplyTransforms(GlyphPartTransform.Rotate,
                    GlyphPartTransform.Rotate, GlyphPartTransform.Rotate);

                var old = pbPartSelection.Image;
                pbPartSelection.Image = selectedPart.GetBitmap(128);
                old.Dispose();
            };
            btnRotCCW.Click += (@s, e) =>
            {
                if (selectedPart == null)
                    return;

                selectedPart = selectedPart.ApplyTransforms(GlyphPartTransform.Rotate);

                var old = pbPartSelection.Image;
                pbPartSelection.Image = selectedPart.GetBitmap(128);
                old.Dispose();
            };
            btnFlipX.Click += (@s, e) =>
            {
                if (selectedPart == null)
                    return;

                selectedPart = selectedPart.ApplyTransforms(GlyphPartTransform.FlipX);

                var old = pbPartSelection.Image;
                pbPartSelection.Image = selectedPart.GetBitmap(128);
                old.Dispose();
            };
            btnFlipY.Click += (@s, e) =>
            {
                if (selectedPart == null)
                    return;

                selectedPart = selectedPart.ApplyTransforms(GlyphPartTransform.FlipY);

                var old = pbPartSelection.Image;
                pbPartSelection.Image = selectedPart.GetBitmap(128);
                old.Dispose();
            };

            btnNW.Click += (@s, e) =>
            {
                glyph[0] = selectedPart;
                UpdateGlyph();
                selectedPart = (GlyphPart)selectedPart.Clone();
            };
            btnNE.Click += (@s, e) =>
            {
                glyph[1] = selectedPart;
                UpdateGlyph();
                selectedPart = (GlyphPart)selectedPart.Clone();
            };
            btnSW.Click += (@s, e) =>
            {
                glyph[2] = selectedPart;
                UpdateGlyph();
                selectedPart = (GlyphPart)selectedPart.Clone();
            };
            btnSE.Click += (@s, e) =>
            {
                glyph[3] = selectedPart;
                UpdateGlyph();
                selectedPart = (GlyphPart)selectedPart.Clone();
            };

            lblMainColor.Click += (@s, e) =>
            {

                var dlg = new ColorDialog();
                if (dlg.ShowDialog() == DialogResult.OK) {
                    selectedPart.MainColor = dlg.Color;
                    pbPartSelection.Image = selectedPart.GetBitmap(128);
                    UpdateColors();
                }
            };
            lblBorderColor.Click += (@s, e) =>
            {

                var dlg = new ColorDialog();
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    selectedPart.BorderColor = dlg.Color;
                    pbPartSelection.Image = selectedPart.GetBitmap(128);
                    UpdateColors();
                }
            };
            nudBorderWidth.ValueChanged += (@s, e) =>
            {
                selectedPart.BorderWidth = (Single)nudBorderWidth.Value;
                pbPartSelection.Image = selectedPart.GetBitmap(128);
                UpdateColors();
            };
        }
        private void generateRandomGlyphToolStripMenuItem_Click(object sender, EventArgs e)
        {
            var rand = new Random();

            for (int i = 0; i < 4; i++) {
                var partIndex = rand.Next(0, glyphParts.Count);
                selectedPart = glyphParts[partIndex];

                var t = rand.Next(0, 8);
                for (int k = 0; k < t; k++) {
                    var transform = (GlyphPartTransform) rand.Next(0, 3);
                    selectedPart = selectedPart.ApplyTransforms(transform);
                }

                glyph[i] = selectedPart;
            }

            UpdateGlyph();
        }
        void AttachEventHandlers()
        {
            lvGlyphs.ItemSelectionChanged += (@s, e) =>
            {
                if (lvGlyphs.SelectedItems.Count == 0)
                {
                    selectedPart            = null;
                    pbPartSelection.Image   = null;
                    gbCustomization.Enabled = false;
                }
                else
                {
                    selectedPart          = (GlyphPart)lvGlyphs.SelectedItems[0].Tag;
                    pbPartSelection.Image = selectedPart.GetBitmap(128);
                    UpdateColors();
                    gbCustomization.Enabled = true;
                }
            };

            btnRotCW.Click += (@s, e) =>
            {
                if (selectedPart == null)
                {
                    return;
                }

                selectedPart = selectedPart.ApplyTransforms(GlyphPartTransform.Rotate,
                                                            GlyphPartTransform.Rotate, GlyphPartTransform.Rotate);

                var old = pbPartSelection.Image;
                pbPartSelection.Image = selectedPart.GetBitmap(128);
                old.Dispose();
            };
            btnRotCCW.Click += (@s, e) =>
            {
                if (selectedPart == null)
                {
                    return;
                }

                selectedPart = selectedPart.ApplyTransforms(GlyphPartTransform.Rotate);

                var old = pbPartSelection.Image;
                pbPartSelection.Image = selectedPart.GetBitmap(128);
                old.Dispose();
            };
            btnFlipX.Click += (@s, e) =>
            {
                if (selectedPart == null)
                {
                    return;
                }

                selectedPart = selectedPart.ApplyTransforms(GlyphPartTransform.FlipX);

                var old = pbPartSelection.Image;
                pbPartSelection.Image = selectedPart.GetBitmap(128);
                old.Dispose();
            };
            btnFlipY.Click += (@s, e) =>
            {
                if (selectedPart == null)
                {
                    return;
                }

                selectedPart = selectedPart.ApplyTransforms(GlyphPartTransform.FlipY);

                var old = pbPartSelection.Image;
                pbPartSelection.Image = selectedPart.GetBitmap(128);
                old.Dispose();
            };

            btnNW.Click += (@s, e) =>
            {
                glyph[0] = selectedPart;
                UpdateGlyph();
                selectedPart = (GlyphPart)selectedPart.Clone();
            };
            btnNE.Click += (@s, e) =>
            {
                glyph[1] = selectedPart;
                UpdateGlyph();
                selectedPart = (GlyphPart)selectedPart.Clone();
            };
            btnSW.Click += (@s, e) =>
            {
                glyph[2] = selectedPart;
                UpdateGlyph();
                selectedPart = (GlyphPart)selectedPart.Clone();
            };
            btnSE.Click += (@s, e) =>
            {
                glyph[3] = selectedPart;
                UpdateGlyph();
                selectedPart = (GlyphPart)selectedPart.Clone();
            };

            lblMainColor.Click += (@s, e) =>
            {
                var dlg = new ColorDialog();
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    selectedPart.MainColor = dlg.Color;
                    pbPartSelection.Image  = selectedPart.GetBitmap(128);
                    UpdateColors();
                }
            };
            lblBorderColor.Click += (@s, e) =>
            {
                var dlg = new ColorDialog();
                if (dlg.ShowDialog() == DialogResult.OK)
                {
                    selectedPart.BorderColor = dlg.Color;
                    pbPartSelection.Image    = selectedPart.GetBitmap(128);
                    UpdateColors();
                }
            };
            nudBorderWidth.ValueChanged += (@s, e) =>
            {
                selectedPart.BorderWidth = (Single)nudBorderWidth.Value;
                pbPartSelection.Image    = selectedPart.GetBitmap(128);
                UpdateColors();
            };
        }