using System;
using System.Text;
using System.Drawing;
using System.Runtime.InteropServices;

namespace Mix.Tool.ArchiveEditor
{
    /// <summary>
    /// ユーティリティクラス
    /// </summary>
    public class Utility
    {
        /// <summary>
        /// アイコンの種類
        /// </summary>
        public enum IconType
        {
            /// <summary>
            /// スモールアイコン
            /// </summary>
            Small,

            /// <summary>
            /// ラージアイコン
            /// </summary>
            Large,
        };

        private const uint SHGFI_ICON      = 0x100; // アイコン・リソースの取得
        private const uint SHGFI_LARGEICON = 0x0; // 大きいアイコン
        private const uint SHGFI_SMALLICON = 0x1; // 小さいアイコン
        private const uint SHGFI_TYPENAME  = 0x400;//ファイルの種類

        private struct SHFILEINFO
        {
            public IntPtr hIcon;
            public IntPtr iIcon;
            public uint dwAttributes;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string szDisplayName;

            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
            public string szTypeName;
        };

        [DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
        private static extern long StrFormatByteSize(long fileSize, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder buffer, uint bufferSize);

        [DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
        private static extern long StrFormatByteSizeW(Int64 fileSize, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder buffer, uint bufferSize);

        [DllImport("shell32.dll")]
        private static extern IntPtr SHGetFileInfo( string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);

        /// <summary>
        /// ファイルサイズを文字列に変換
        /// </summary>
        /// <param name="fileSize">ファイルサイズ</param>
        /// <returns>文字列にしたファイルサイズ</returns>
        public static string FileSizeToString(long fileSize)
        {
            StringBuilder builder = new StringBuilder(32);
            StrFormatByteSize(fileSize, builder, 32);

            return builder.ToString();
        }

        /// <summary>
        /// ファイルサイズを文字列に変換
        /// </summary>
        /// <param name="fileSize">ファイルサイズ</param>
        /// <returns>文字列にしたファイルサイズ</returns>
        public static string FileSizeToString64(Int64 fileSize)
        {
            StringBuilder builder = new StringBuilder(32);
            StrFormatByteSizeW(fileSize, builder, 32);

            return builder.ToString();
        }

        /// <summary>
        /// ファイルの種類を文字列で取得
        /// </summary>
        /// <param name="filePath">ファイルパス</param>
        /// <returns>ファイルの種類</returns>
        public static string GetFileType(string filePath)
        {
            SHFILEINFO shfi = new SHFILEINFO();
            shfi.szDisplayName = new String(Convert.ToChar(0), 260);
            shfi.szTypeName = new String(Convert.ToChar(0), 80);

            IntPtr hSuccess = SHGetFileInfo(filePath, 0, ref shfi, (uint)Marshal.SizeOf(shfi), SHGFI_TYPENAME);

            return shfi.szTypeName;
        }

        /// <summary>
        /// ファイルのアイコンを取得
        /// </summary>
        /// <param name="filePath">ファイルパス</param>
        /// <param name="type">アイコンの種類</param>
        /// <returns>アイコン</returns>
        public static Icon GetFileIcon(string filePath, IconType type)
        {
            uint flags = 0;
            SHFILEINFO shinfo = new SHFILEINFO();
            IntPtr hSuccess;
            Icon icon = null;

            switch (type)
            {
                case IconType.Small:
                    flags = (SHGFI_ICON | SHGFI_SMALLICON);
                    break;

                case IconType.Large:
                    flags = (SHGFI_ICON | SHGFI_LARGEICON);
                    break;
            }

            hSuccess = SHGetFileInfo(filePath, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), flags);
            if (hSuccess != IntPtr.Zero)
            {
                icon = Icon.FromHandle(shinfo.hIcon);
            }

            return icon;
        }
    }
}
