/// <summary>
        /// Update the preview for the pixel font
        /// </summary>
        private void UpdatePixelFontPreview()
        {
            Console.WriteLine("UpdatePreview called...");
            SingleCharInfoDisplay ciDisplay = null;

            foreach (Control c in _fontDesignPage.Controls)
            {
                if (c.GetType() == typeof(SingleCharInfoDisplay))
                {
                    ciDisplay = (SingleCharInfoDisplay)c;
                    break;
                }
            }
            if (ciDisplay != null)
            {
                Bitmap bmp = null;
                if (_previewPanel.BackgroundImage != null)
                {
                    _previewPanel.BackgroundImage.Dispose();
                    _previewPanel.BackgroundImage = null;
                }
                //refresh everytime...//TODO::improve
                bmp = DrawFontPreviewBitmap(ciDisplay.FontSize.Width, ciDisplay.FontSize.Height,
                                            ciDisplay.FontPixelsMap, Color.Aqua, Color.Black);
                _previewPanel.BackgroundImage       = (Image)bmp;
                _previewPanel.BackgroundImageLayout = ImageLayout.Center;

                _previewPanel.BackgroundImage = bmp;
                _previewPanel.Update();
                _previewPanel.Refresh();
            }
        }
        /// <summary>
        /// Paint all the pixel drawing containers
        /// </summary>
        private void PopulateFontDesignCanvas()
        {
            _fontDesignPage.Controls.Clear();

            char c = ((AsciiCode)_asciiCodeCbx.Items[_asciiCodeCbx.SelectedIndex]).Value;

            if (!_allPixelMaps.ContainsKey(c))
            {
                return;                                //not yet populated
            }
            SingleCharInfoDisplay ciDisplay = _allPixelMaps[c];

            /*
             * Each UInt32 entry in the array, represents a single row of pixels (max 32 pixels).
             * If height in pixel is 7 pixels, then we need to read 7 rows.
             * If width in pixel is 5 pixels, then for each entry, we need to check for bit '1' from left to right
             */
            ciDisplay.Left = (_fontDesignPage.Left + _fontDesignPage.Width - ciDisplay.Width) / 2;
            ciDisplay.Top  = (_fontDesignPage.Top + _fontDesignPage.Height - ciDisplay.Height) / 2;

            if (_previewPanel.BackgroundImage != null)
            {
                _previewPanel.BackgroundImage.Dispose();
                _previewPanel.BackgroundImage = DrawFontPreviewBitmap(ciDisplay.FontSize.Width, ciDisplay.FontSize.Height, ciDisplay.FontPixelsMap, Color.Aqua, Color.Black);
            }
            SuspendLayout();
            _fontDesignPage.Controls.Add(ciDisplay);
            ResumeLayout();
            Update();
            Refresh();
        }
 /// <summary>
 /// Called when the pixel is clicked on the editor
 /// </summary>
 /// <param name="source"></param>
 private void OnPixelClicked(SingleCharInfoDisplay source)
 {
     Console.WriteLine("OnPixelClicked...");
     //Show current character being edited
     if (source.BackColor != Color.LightGoldenrodYellow)
     {
         source.BackColor = Color.LightGoldenrodYellow;
         source.Update();
         source.Refresh();
     }
     _docDirty = true;
     UpdatePixelFontPreview();
 }
        /// <summary>
        /// User wants to create a new file
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnNewFile(object sender, EventArgs e)
        {
            if (_docDirty &&
                MessageBox.Show(this, "Current changes not saved. Do you want to proceed?", "Question", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
            {
                return;
            }

            FontSizeForm itemSizeDlg = new FontSizeForm();

            if (itemSizeDlg.ShowDialog(this) == DialogResult.OK)
            {
                _docDirty = false;
                Cursor    = Cursors.WaitCursor;

                _asciiCodeCbx.Items.Clear();
                if (_allPixelMaps != null)
                {
                    _allPixelMaps.Clear();
                }
                _allPixelMaps = null;
                _filePath     = null;


                Text = "Pixel Font Generator";

                //Populate the supported character codes
                PopulateAsciiCodes();
                //A new file is being created...populate the character editor
                _allPixelMaps = new Dictionary <char, SingleCharInfoDisplay>();

                foreach (AsciiCode ac in _asciiCodeCbx.Items)
                {
                    SingleCharInfoDisplay ciDisplay = new SingleCharInfoDisplay((byte)itemSizeDlg.PixelHeight, (byte)itemSizeDlg.PixelWidth, ac.Value);
                    ciDisplay.CharEdit += OnPixelClicked;
                    _allPixelMaps.Add(ac.Value, ciDisplay);
                }

                _canvasTabs.SelectTab(0);
                _asciiCodeCbx.SelectedIndex = 0;//select the first item by default

                PopulateFontDesignCanvas();

                _fontSizeLbl.Text = itemSizeDlg.PixelWidth + " (W) X " + itemSizeDlg.PixelHeight + " (H)";

                Cursor = Cursors.Default;
            }
        }
        /// <summary>
        /// Export font file as an image
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnExportToImage(object sender, EventArgs e)
        {
            if (_allPixelMaps == null || _allPixelMaps.Count == 0)
            {
                MessageBox.Show(this, "Nothing to export", "Pixel Font Generator", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            SaveFileDialog saveFile = new SaveFileDialog()
            {
                AddExtension     = true,
                CheckPathExists  = true,
                DefaultExt       = ".bmp",
                Filter           = "Image Files|*.bmp",
                OverwritePrompt  = true,
                RestoreDirectory = true,
                ValidateNames    = true
            };

            if (saveFile.ShowDialog(this) == DialogResult.OK)
            {
                try
                {
                    int totalItems = _allPixelMaps.Count;
                    int fontHeight = _allPixelMaps[(char)' '].FontSize.Height;
                    int fontWidth  = _allPixelMaps[(char)' '].FontSize.Width;

                    //create a new bitmap to hold all images
                    int      xPos      = 0;
                    int      yPos      = 0;
                    int      sqrt      = (int)Math.Ceiling(Math.Sqrt(totalItems));
                    int      bmpHW     = 50;//48x48 BMP with 2 pixel gutter width
                    Bitmap   container = new Bitmap(sqrt * bmpHW, sqrt * bmpHW);
                    Graphics canvas    = Graphics.FromImage(container);
                    foreach (var c in _allPixelMaps.Keys)
                    {
                        //get each font pixel map and construct the font
                        SingleCharInfoDisplay ciDisplay = _allPixelMaps[c];
                        Bitmap fontImage = DrawFontPreviewBitmap(fontWidth, fontHeight, ciDisplay.FontPixelsMap, Color.Black, Color.WhiteSmoke);

                        Bitmap   fontContainer = new Bitmap(bmpHW - 2, bmpHW - 2);
                        Graphics fcGraphics    = Graphics.FromImage(fontContainer);
                        fcGraphics.FillRectangle(Brushes.Black, 0, 0, fontContainer.Width, 15);
                        fcGraphics.FillRectangle(Brushes.WhiteSmoke, 0, 15, 48, 48 - 15);
                        fcGraphics.DrawString(c + "", new Font("Arial", 8), Brushes.White, 20, 0);

                        fcGraphics.DrawImage(fontImage, (fontContainer.Width - fontWidth) / 2, (33 - fontHeight) / 2 + 15);

                        canvas.DrawImage(fontContainer, xPos, yPos);

                        xPos += bmpHW;
                        if (xPos > container.Width)
                        {
                            xPos  = 1; //reset to left
                            yPos += bmpHW;
                        }
                        fontImage.Dispose();
                        fontContainer.Dispose();
                    }
                    container.Save(saveFile.FileName);
                    MessageBox.Show(this, "Font image exported successfully", "Pixel Font Generator", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    container.Dispose();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this, ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }
        /// <summary>
        /// Open a font file to edit
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnFileOpen(object sender, EventArgs e)
        {
            if (_docDirty)
            {
                if (MessageBox.Show(this, "You have unsaved changes. If you proceed without saving the current document, your changes will be lost. " +
                                    "Do you want to proceed?", "Save Changes", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
                {
                    return;
                }
                else
                {
                    _docDirty = false;
                }
            }
            OpenFileDialog ofDlg = new OpenFileDialog()
            {
                AddExtension     = true,
                CheckFileExists  = true,
                CheckPathExists  = true,
                DefaultExt       = ".cs",
                Filter           = "C# Files|*.cs",
                Multiselect      = false,
                RestoreDirectory = true,
                ShowReadOnly     = true
            };

            if (ofDlg.ShowDialog(this) == DialogResult.OK)
            {
                try
                {
                    StreamReader sr       = File.OpenText(ofDlg.FileName);
                    String       contents = sr.ReadToEnd();
                    sr.Close();

                    string firstId  = "//7ede8a4c-223c-4389-a683-cb2c5de448d5";
                    string secondId = "//f3b635d2-e762-4110-b202-488f5b6ca5df";
                    //Validate file
                    if (contents.IndexOf(firstId) < 0 || contents.IndexOf(secondId) < 0)
                    {
                        MessageBox.Show(this, "Invalid font mapping file", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else
                    {
                        Cursor = Cursors.WaitCursor;
                        string temp = "";
                        //First extract pixel map
                        string pixelMap = "";
                        temp = contents.Substring(contents.IndexOf(secondId) + secondId.Length);
                        temp = temp.Substring(0, temp.IndexOf(secondId));

                        pixelMap = temp.Replace("\t", "").Trim();

                        //Now extract size
                        contents = contents.Replace("\r\n", "");
                        temp     = contents.Substring(contents.IndexOf(firstId) + firstId.Length + 2);
                        string wh         = temp.Substring(0, temp.IndexOf("//"));
                        int    fontWidth  = int.Parse(wh.Split(new char[] { ';' })[0]);
                        int    fontHeight = int.Parse(wh.Split(new char[] { ';' })[1]);

                        string[] lines = pixelMap.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);

                        _allPixelMaps = new Dictionary <char, SingleCharInfoDisplay>();
                        char c = (char)32;
                        foreach (string line in lines)
                        {
                            if (line.Trim().StartsWith("//"))
                            {
                                Console.WriteLine("Reading..." + line);
                                //extract the char
                                if (line.Trim().StartsWith("// Space"))
                                {
                                    c = (char)32;
                                }
                                else
                                {
                                    c = line.Trim().Substring(3)[0];
                                }
                            }
                            else
                            {
                                List <UInt32> charPixels = new List <UInt32>();
                                string[]      pixelVals  = line.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                                foreach (string entry in pixelVals)
                                {
                                    charPixels.Add(Convert.ToUInt32(entry.Trim(), 16));
                                }
                                SingleCharInfoDisplay ciDisplay = new SingleCharInfoDisplay((byte)fontHeight, (byte)fontWidth, c);
                                ciDisplay.SetPixelMap(charPixels.ToArray());
                                ciDisplay.CharEdit += OnPixelClicked;
                                _allPixelMaps.Add(c, ciDisplay);
                            }
                        }
                        //Now setup window state
                        PopulateAsciiCodes();
                        _asciiCodeCbx.SelectedIndex = 0;
                        _fontSizeLbl.Text           = fontWidth + " (W) X " + fontHeight + " (H)";
                        Text      = "Pixel Font Generator :" + ofDlg.FileName;
                        _filePath = ofDlg.FileName;
                        //Now redraw
                        PopulateFontDesignCanvas();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(this, "Seems like an invalid file !\r\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                finally
                {
                    Cursor = Cursors.Default;
                }
            }
        }