using System;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.Reflection;
using System.Xml;
using nft.framework;
using nft.framework.plugin;
using nft.core.game;
using nft.core.geometry;
using nft.core.structure;
using nft.util;
using nft.framework.drawing;
using System.Text;
using System.IO;
using System.Collections.Generic;

namespace nft.contributions.terrain
{
	/// <summary>
	/// CtbCliffTextureFactory の概要の説明です。
	/// </summary>
    public class CtbCliffTextureFactory : CtbCustomCtbFactory
	{
        public static readonly Color texBGColor = Color.Magenta;
        public static readonly Color texFGColor = Color.Cyan;

        //private static CtbTerrainTextureFactory theInstance;
        //public static ITexture GetSilhouetteTexture(Scaler scl, short id) {
        //    return theInstance.GetTexture(scl, id);
        //}

        // Template set of Cliff Images. Used for like a clipping mask.
        protected PlainCliffImgSet imageSet;

        public CtbCliffTextureFactory(Plugin p, ParamsReader contrib)
            : base(p, contrib) {
            imageSet = new PlainCliffImgSet(DataDirectory);
        }

        //protected override InitCompleteEventHandler Initialize() {
        //    return base.Initialize();
        //}

        public override void PrepareCacheData(bool forceUpdate) {
            // check existence or create pattern images.
            if (forceUpdate)
                imageSet.DeleteCache();
            imageSet.PrepareCache();
            int num = CliffPolygon.StockCount * (Enum.GetValues(typeof(ZoomScale)).Length + 1);
            if (textureCache != null) {
                textureCache.Clear();
            }
            textureCache = new Dictionary<Int32, ITextureOld>(num);
        }

        protected override Contribution Create(Plugin owner, ParamsReader e)
        {
            //TODO:将来テクスチャ画像対応の地形テクスチャも…
            return new CtbSimpleCliffTexture(owner, this, e);
        }

        private Dictionary<Int32,ITextureOld> textureCache;
        /// <summary>
        /// Returns two-tone colored cliff piece texture. Useful for clipping mask.
        /// </summary>
        /// <param name="scl"></param>
        /// <param name="id"></param>
        /// <param name="hint"></param>
        /// <returns></returns>
        public ITextureOld GetTexture(Scaler scl, ushort id, Point3DV hint) {
            Int32 key = id;
            key<<=16;
            key += (short)(scl.Value*0x1000);
            if (!textureCache.ContainsKey(key)) {
                IGraphicManagerOld gm = GlobalModules.GraphicManagerOld;
                CliffPolygon poly = CliffPolygon.GetPolygon(id);
                Rectangle region = poly.GetBounds(scl);
                Point off = new Point(region.Right, region.Bottom);
                ITextureOld tex = gm.CreateStaticTexture(imageSet[scl, id, hint], off);
                textureCache.Add(id, tex);
                return tex;
            } else {
                return textureCache[key];
            }
        }

        /// <summary>
        /// Returns two-tone colored cliff piece texture. Useful for clipping mask.
        /// </summary>
        /// <param name="scl"></param>
        /// <param name="id"></param>
        /// <param name="hint"></param>
        /// <returns></returns>
        public Image GetTextureBitmap(Scaler scl, ushort id, Point3DV hint) {
            try {
                return imageSet[scl, id, hint];
            } catch (FileNotFoundException) {
                return null;
            }
        }

        /// <summary>
        /// Two-tone colored sinple cliff piece textures
        /// </summary>
        protected class PlainCliffImgSet : AbstractCliffImgSet {
            public PlainCliffImgSet(string path) : base(path) { }

            protected override Bitmap CreateBitmap(Scaler sc, CliffPolygon polygon, Point3DV hint) {
                Point[] pts = polygon.GetVerticis(sc);
                Rectangle rect = new Rectangle();
                return PrimitiveTextrueFactory.CreatePolygonBitmap
                    (pts, texFGColor, texBGColor, ref rect);                
            }
        }

    }
}
