using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;

namespace Flipmind.Drawing
{
    /// <summary>
    /// 
    /// </summary>
    public class FontUtility
    {
        /// <summary>
        /// Takes a string and the desired font and returns the cloest bounding box size that will fit the string
        /// - only expands width
        /// </summary>
        /// <param name="g"></param>
        /// <param name="font"></param>
        /// <param name="text"></param>
        /// <param name="size"></param>
        /// <param name="minimumPointSize"></param>
        /// <param name="currentBounds"></param>
        /// <returns></returns>
        public static RectangleF GetClosestBoundsFit(Graphics g, Font font, String text,  SizeF size, RectangleF currentBounds)
        {
            RectangleF newBounds = new RectangleF(currentBounds.Location, currentBounds.Size);
            
            SizeF textSize = g.MeasureString(text,font);
            if (textSize.Width > newBounds.Width)
            {
                // increase width to text width + 5%
                newBounds.Width = textSize.Width + (textSize.Width * 1.05F);
            }

            return newBounds;
        }

        /// <summary>
        /// Takes a string and the desired font and returns the cloest font size that will fit within the
        /// allowed boundaries.
        /// </summary>
        /// <param name="g">The graphics object we are measuring the font on</param>
        /// <param name="font">The font and size we would like to display the text in if possible</param>
        /// <param name="text">The text to display in the given area and font</param>
        /// <param name="size">The size that the text can be displayed within</param>
        /// <param name="minimumPointSize">A font smaller then this point size will not be used and if the text needs to be smaller then this to fit then a font of the size will be returned and the text will be clipped for display</param>
        /// <returns></returns>
        public static Font GetClosestFit(Graphics g, Font font, String text,  SizeF size, float minimumPointSize)
        {
            //loop until the correct font size is found 
            do
            {
                //Get the size of the current string in the font 
                SizeF textSize = g.MeasureString(text,font, (int) size.Width);
                if (textSize.Width > size.Width || textSize.Height > size.Height)
                {
                    float newSize = font.Size - 0.5f; // Try one size smaller and see if it fits
                    if (newSize < minimumPointSize)
                    {
                        font = new Font(font.Name, minimumPointSize, font.Style, font.Unit);
                        break; // Use the minimum font size.  It will be to hard to see if we make it any smaller
                    }
                    else
                    {
                        font = new Font(font.Name, newSize, font.Style, font.Unit);
                    }
                }
                else
                {
                    break; // We have found a fit.  Lets exit
                }
            }
            while (true);
            return font;
        }
    }
}
