using System;
using System.Collections.Generic;
using System.Text;
using Yanesdk.Draw;
using OpenGl;
using Yanesdk.System;
using Yanesdk.Ytl;

namespace Yamalib.Util
{
    /// <summary>
    /// yaneSDK関連のユーティリティを集めたクラス
    /// </summary>
    public static class YanesdkUtil
    {

        public static readonly String FILE_READ_ON_MEMORY_FLG = "MEM:";

        /// <summary>
        /// サウンドの無限ループ
        /// </summary>
        public static readonly int SOUND_INFINITY_LOOP = -1;

        /// <summary>
        /// 白を表すColr4ubインスタンス
        /// </summary>
        public static readonly Color4ub WHITE_COLOR = new Color4ub(255, 255, 255, 255);
        /// <summary>
        /// 黒を表すColor4ubインスタンス
        /// </summary>
        public static readonly Color4ub BLOCK_COLOR = new Color4ub(0, 0, 0, 255);

        /// <summary>
        /// 現在のスクリーンカラーをColor4ubで取得
        /// </summary>
        /// <param name="screen"></param>
        /// <returns></returns>
        public static Color4ub GetNowScreenColor(IScreen screen)
        {
            int r, g, b, a;
            screen.GetColor(out r, out g, out b, out a);
            return new Color4ub((byte)r, (byte)g, (byte)b, (byte)a);
        }

        /// <summary>
        /// 矩形の中にx,yが入っているかどうか
        /// </summary>
        /// <param name="drawRc"></param>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <returns></returns>
        public static bool IsInRect(ref Rect rc, int x, int y)
        {
            return (x >= rc.Left && x < rc.Right
                && y >= rc.Top && y < rc.Bottom);
        }

        /// <summary>
        /// "AABBCCDD" という文字列からColor4ubを取得する。
        /// </summary>
        /// <param name="str">文字列</param>
        /// <returns>
        ///     変換した色。
        ///     不正な文字列の場合、白が返却される
        /// </returns>
        public static Color4ub ToColor4ub(String str)
        {
            Color4ub color4ub = new Color4ub(255,255,255,255);

            if (str != null && str.Length >= 6)
            {
                // ごにょごにょする
                byte r, g, b, a = 255;

                r = Convert.ToByte(str.Substring(0, 2), 16);

                g = Convert.ToByte(str.Substring(2, 2), 16);

                b = Convert.ToByte(str.Substring(4, 2), 16);

                if (str.Length >= 8)
                {
                    a = Convert.ToByte(str.Substring(6, 2), 16);
                }

                color4ub.SetColor(r, g, b, a);
            }

            return color4ub;
        }

        public static string Color4ubToString(Color4ub color)
        {
            const int RADIX = 16;
            StringBuilder buffer = new StringBuilder();
            string r, g, b, a;
            r = Convert.ToString(color.R, RADIX);
            if (r.Length < 2)
            {
                buffer.Append('0');
            }
            buffer.Append(r);
            
            g = Convert.ToString(color.G, RADIX);
            if (g.Length < 2)
            {
                buffer.Append('0');
            }
            buffer.Append(g);
            
            b = Convert.ToString(color.B, RADIX);
            if (b.Length < 2)
            {
                buffer.Append('0');
            }
            buffer.Append(b);
            
            a = Convert.ToString(color.A, RADIX);
            if (a.Length < 2)
            {
                buffer.Append('0');
            }
            buffer.Append(a);
            return buffer.ToString();
        }

        /// <summary>
        /// OpneGLを使用しているとき、フレームバッファからテクスチャを生成し返却する。
        /// この処理は重いので、使う場合は代替手段を検討すること
        /// </summary>
        public static GlTexture CopyGlFlameBuffer(Screen2DGl screen)
        {
            GlTexture texture1 = new GlTexture();
            Surface surface = new Surface();
            surface.CreateDIB(screen.Width, screen.Height, false);
            texture1.SetSurface(surface);

            texture1.Bind();
            Gl.glCopyTexSubImage2D(
                (uint)texture1.TextureType, 0, 0, 0, 0, 0, screen.Width, screen.Height);
            texture1.Unbind();

            return texture1;
        }

        /// <summary>
        /// OpneGLを使用しているとき、フレームバッファからテクスチャを生成し返却する。
        /// この処理は重いので、使う場合は代替手段を検討すること
        /// </summary>
        public static GlTexture CopyGlFlameBufferNormalize(Screen2DGl screen)
        {
            GlTexture texture1 = CopyGlFlameBuffer(screen); 

            // 正規化するためにもう一度描画してからバッファコピー
            screen.Blt(texture1, 0, 0);

            return CopyGlFlameBuffer(screen);
        }

        /// <summary>
        /// テクスチャリソースを解放する
        /// </summary>
        /// <param name="Texture">解放するテクスチャインスタンス</param>
        /// <returns>実際に解放すればtrue</returns>
        public static bool TextureSafeRelease(ITexture texture)
        {
            if (null != texture)
            {
                texture.Dispose();
                texture = null;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 定義ファイルから、要素数をカウントして返却する
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public static int GetElementNum(string filename)
        {
            FilenamelistReader reader = new FilenamelistReader();
            YanesdkResult result = reader.LoadDefFile(filename, 1);
            if (result == YanesdkResult.NoError)
            {
                return reader.Data.Count;
            }
            return 0;
        }




    }
}
