using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Diagnostics;

namespace nft.framework.drawing {
    public class PrimitiveTextrueFactory {
        private static Bitmap bmpWork = new Bitmap(1, 1);
        private static Color bgDefault = Color.Magenta;

        /// <summary>
        /// Create edged text texture
        /// </summary>
        public static ITextureOld CreateTextTexture(Font font, string text, Color fore, Color edge) {
            Size sz;
            using (Graphics g = Graphics.FromImage(bmpWork)) {
                sz = GDIDrawer.GetEdgedTextSize(g, text, font).ToSize();
            }
            Bitmap bmp = new Bitmap(sz.Width, sz.Height, PixelFormat.Format24bppRgb);
            Color bg = bgDefault;
            Point pt = new Point();
            using (Graphics g = Graphics.FromImage(bmp)) {
                if (fore.Equals(bg)) {
                    bg = Color.Cyan;
                }
                using (Brush br = new SolidBrush(bg)) {
                    g.FillRectangle(br, 0, 0, sz.Width, sz.Height);
                }
                GDIDrawer.DrawEdgedText(g, text, font, pt, fore, edge);
            }
            return CreateTexture(bmp, bg, pt);
        }

        /// <summary>
        /// create bitmap which has drawn outline bounds of cell groups.
        /// </summary>
        public static ITextureOld CreateCellOutlineTexture(QuaterViewRect rect, Color c, int width) {
            Color bg = bgDefault;
            if (c.Equals(bg)) {
                bg = Color.Cyan;
            }
            Bitmap bmp = CreateCellOutlineBitmap(rect, c, bg, width);
            return CreateTexture(bmp, bg, rect.TextureOffset); 
        }

        /// <summary>
        /// create texture which shows outline bounds of cell groups.
        /// </summary>
        public static Bitmap CreateCellOutlineBitmap(QuaterViewRect rect, Color c, Color bg, int width) {
            Rectangle bounds = rect.GetBounds();
            Size sz = bounds.Size;
            Bitmap bmp = new Bitmap(sz.Width, sz.Height, PixelFormat.Format24bppRgb);
            rect.X -= bounds.X;
            rect.Y -= bounds.Y;
            using (Graphics g = Graphics.FromImage(bmp)) {
                using (Brush br = new SolidBrush(bg)) {
                    g.FillRectangle(br, 0, 0, sz.Width, sz.Height);
                }
                GDIDrawer.DrawCellBounds(g, c, rect, Math.Max(1,width));
            }
            return bmp;
        }

        /// <summary>
        /// create bitmap which has drawn wireframed box of cell groups.
        /// </summary>
        public static ITextureOld CreateCellWireframeTexture(QuaterViewRect rect, Color c, int width) {
            Color bg = bgDefault;
            if (Math.Abs((int)c.GetHue() - 360) == Math.Abs((int)bg.GetHue() - 360)) {
                bg = Color.Cyan;
            }
            Bitmap bmp = CreateCellWireframeBitmap(rect, c, bg, width);
            return CreateTexture(bmp, bg, rect.TextureOffset);
        }

        /// <summary>
        /// create texture which shows wireframed box of cell groups.
        /// </summary>
        public static Bitmap CreateCellWireframeBitmap(QuaterViewRect rect, Color c, Color bg, int width) {
            Rectangle bounds = rect.GetBounds();
            Size sz = bounds.Size;
            Bitmap bmp = new Bitmap(sz.Width, sz.Height, PixelFormat.Format24bppRgb);
            int w = Math.Max(1, width);
            Color cbr = ColorUtil.GetBlighter(c,0.25);
            Color cdk = ColorUtil.GetDarker(c,0.25);
            rect.X -= bounds.X;
            rect.Y -= bounds.Y;
            using (Graphics g = Graphics.FromImage(bmp)) {

                using (Brush br = new SolidBrush(bg)) {
                    g.FillRectangle(br, 0, 0, sz.Width, sz.Height);
                }
                QuaterViewRect rtmp = new QuaterViewRect(rect.X, rect.Y, rect.LWidth, rect.RWidth);
                GDIDrawer.DrawCellBounds(g, c, rtmp, w);
                QuaterViewRect rB = new QuaterViewRect(rect.X + rect.RWidth, rect.Y - rect.RWidth / 2, rect.LWidth, 0, rect.Height);
                GDIDrawer.DrawCellBounds(g, cbr, rB, w);
                QuaterViewRect rD = new QuaterViewRect(rect.X - rect.LWidth, rect.Y - rect.LWidth / 2, 0, rect.RWidth, rect.Height);
                GDIDrawer.DrawCellBounds(g, cdk, rD, w);
                rtmp.Y -= rect.Height;
                GDIDrawer.DrawCellBounds(g, c, rtmp, w);
                rD.X = rect.X; rD.Y = rect.Y;
                GDIDrawer.DrawCellBounds(g, cdk, rD, w);
                rB.X = rect.X; rB.Y = rect.Y;
                GDIDrawer.DrawCellBounds(g, cbr, rB, w);
            }
            return bmp;
        }
        /// <summary>
        /// create bitmap which has drawn silhouette of cell groups.
        /// </summary>
        public static ITextureOld CreateCellSilhouetteTexture(QuaterViewRect rect, Color c) {
            Color bg = bgDefault;
            if (c.Equals(bg)) {
                bg = Color.Cyan;
            }
            Bitmap bmp = CreateCellSilhouetteBitmap(rect, c, bg);
            return CreateTexture(bmp, bg, rect.TextureOffset);
        }

        /// <summary>
        /// create texture which shape is silhouette of cell groups.
        /// </summary>
        public static Bitmap CreateCellSilhouetteBitmap(QuaterViewRect rect, Color c, Color bg) {
            Rectangle bounds = rect.GetBounds();
            Size sz = bounds.Size;
            Bitmap bmp = new Bitmap(sz.Width, sz.Height, PixelFormat.Format24bppRgb);
            rect.X -= bounds.X;
            rect.Y -= bounds.Y;            
            using (Graphics g = Graphics.FromImage(bmp)) {
                using (Brush br = new SolidBrush(bg)) {
                    g.FillRectangle(br, 0, 0, sz.Width, sz.Height);
                }
                GDIDrawer.FillCellBounds(g, c, rect);
            }
            return bmp;
        }

                /// <summary>
        /// create bitmap which has drawn 3D shaded box of cell groups.
        /// </summary>
        public static ITextureOld CreateCell3DBoxTexture(QuaterViewRect rect, Color c) {
            Color bg = bgDefault;
            if ((c.GetHue() / 10) == (bg.GetHue() / 10)) {
                bg = Color.Cyan;
            }
            Bitmap bmp = CreateCell3DBoxBitmap(rect, c, bg);
            return CreateTexture(bmp, bg, rect.TextureOffset);
        }

        /// <summary>
        /// create texture of 3D shaded box.
        /// </summary>
        public static Bitmap CreateCell3DBoxBitmap(QuaterViewRect rect, Color c, Color bg) {
            Rectangle bounds = rect.GetBounds();
            Size sz = bounds.Size;
            Bitmap bmp = new Bitmap(sz.Width, sz.Height, PixelFormat.Format24bppRgb);
            Color cbr = ColorUtil.GetBlighter(c,0.25);
            Color cdk = ColorUtil.GetDarker(c,0.25);
            rect.X -= bounds.X;
            rect.Y -= bounds.Y;
            using (Graphics g = Graphics.FromImage(bmp)) {
                using (Brush br = new SolidBrush(bg)) {
                    g.FillRectangle(br, 0, 0, sz.Width, sz.Height);
                }
                QuaterViewRect rB = new QuaterViewRect(rect.X, rect.Y, rect.LWidth, 0, rect.Height);
                GDIDrawer.FillCellBounds(g, cbr, rB);
                QuaterViewRect rD = new QuaterViewRect(rect.X, rect.Y, 0, rect.RWidth, rect.Height);
                GDIDrawer.FillCellBounds(g, cdk, rD);
                QuaterViewRect rtmp = new QuaterViewRect(rect.X, rect.Y - rect.Height, rect.LWidth, rect.RWidth);
                GDIDrawer.FillCellBounds(g, c, rtmp);
            }
            return bmp;
        }

        public static ITextureOld CreateCellBoundsTexture(QuaterViewRect rect, Font font, String txt, Color c) {
            Color bg = bgDefault;
            if ((c.GetHue() / 10) == (bg.GetHue() / 10)) {
                bg = Color.Cyan;
            }
            Bitmap bmp = CreateCellWireframeBitmap(rect, c, bg, 2);
            using (Graphics g = Graphics.FromImage(bmp)) {
                int v = (rect.RWidth+rect.LWidth)/2;
                int x = v;
                int y = bmp.Height - v;
                SizeF sz = g.MeasureString(txt, font);
                Point pt = new Point(x - (int)(sz.Width / 2), y);
                GDIDrawer.DrawEdgedText(g, txt, font, pt, ColorUtil.GetBlighter(c, 0.75), ColorUtil.GetDarker(c, 0.75));
            }
            return CreateTexture(bmp, bg, rect.TextureOffset);
        }

        /// <summary>
        /// create polygon texture.
        /// </summary>
        /// <param name="vrtics"></param>
        /// <param name="bounds">Specify verticis bounds for quick process. If bounds rectangle is 'Empty', minimum bounce will be settled.</param>
        /// <param name="c"></param>
        /// <returns></returns>
        public static ITextureOld CreatePolygonTexture(Point[] vrtics, Color c, ref Rectangle bounds ) {
            Color bg = bgDefault;
            if (c.Equals(bg)) {
                bg = Color.Cyan;
            }
            Bitmap bmp = CreatePolygonBitmap(vrtics, c, bg, ref bounds);
            ITextureOld tex= null;
            if (bmp != null) {
                tex = CreateTexture(bmp, bg, bounds.Location, bounds.Size);
            }
            return tex;
        }

        /// <summary>
        /// create polygon image
        /// </summary>
        /// <param name="vrtics"></param>
        /// <param name="fore"></param>
        /// <param name="back"></param>
        /// <param name="bounds">Specify verticis bounds for quick process. If bounds rectangle is 'Empty', minimum bounce will be settled.</param>
        /// <returns></returns>
        public static Bitmap CreatePolygonBitmap(Point[] vrtics, Color fore, Color back, ref Rectangle bounds) {
            if (bounds.IsEmpty) {
                bounds = RectUtil.GetBounds(vrtics);
            }
            Size sz = bounds.Size;
            if (sz.Height <= 0 || sz.Width <= 0) {
                return null;
            }
            Bitmap bmp = null;
            try {
                bmp = new Bitmap(sz.Width, sz.Height, PixelFormat.Format24bppRgb);
            } catch (ArgumentException ae) {
                Debug.WriteLine("Error:Invalid Image size="+sz);
            }
            using (Graphics g = Graphics.FromImage(bmp)) {
                using (Brush br = new SolidBrush(back)) {
                    g.FillRectangle(br, 0, 0, sz.Width, sz.Height);
                }
                //Point pt = new Point(-bounds.Width, -bounds.Height);
                GDIDrawer.FillPolygon(g, fore, vrtics, /*pt*/bounds.Location);
            }
            return bmp;
        }

        protected static ITextureOld CreateTexture(Bitmap bmp, Color bg, Point off) {
            return CreateTexture(bmp, bg, off, bmp.Size);
        }

        protected static ITextureOld CreateTexture(Bitmap bmp, Color bg, Point off, Size sz) {
            IGraphicManagerOld gm = GlobalModules.GraphicManagerOld;
            ISurfaceOld sur = gm.CreateSurfaceFromBitmap(bmp);
            sur.ColorKey = bg;
            ITextureOld tex = gm.CreateStaticTexture(sur, new Rectangle(new Point(0,0), sz), off, false);
            return tex;
        }
    }
}
