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

using System.Drawing;
using Microsoft.Win32;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace FileTypeRegist
{
    public class FileIconInfo
    {

        public FileIconInfo(string iconFile, int index)
        {
            this.iconFile = iconFile;
            this.index = index;
        }

        public FileIconInfo(string iconpath)
        {
            string[] data = iconpath.Split(',');
            this.iconFile = data[0];
            this.index = int.Parse(data[1]);
        }

        string iconFile;

        public string IconFile
        {
            get { return iconFile; }
        }

        int index;

        public int Index
        {
            get { return index; }
        }

        public string IconInfo
        {
            get { return iconFile + "," + index.ToString(); }
        }

    }
    class FileTypeRegister
    {
        string extendName;
        RegistryKey fileKey;
        RegistryKey iconKey;

        const string iconKeyName = "DefaultIcon";
        public FileTypeRegister(string extendName)
        {
            this.extendName = extendName;
            RegistryKey extendkey = Registry.ClassesRoot.OpenSubKey("." + extendName);
            string fileKeyPath = extendkey.GetValue("").ToString();

            fileKey = Registry.ClassesRoot.OpenSubKey(fileKeyPath, true);
            iconKey = fileKey.OpenSubKey(iconKeyName, true);
            if (iconKey == null)
            {
                iconKey = fileKey.CreateSubKey(iconKeyName, RegistryKeyPermissionCheck.ReadWriteSubTree);
                iconKey.SetValue("", @"shell32.dll,0", RegistryValueKind.String);
            }

            string pp = iconKey.GetValue("").ToString();
            icoInfo = new FileIconInfo(iconKey.GetValue("").ToString());  
        }

        public void GetFileInfo(System.Drawing.Graphics g)
        {
            FileIconInfo fi = new FileIconInfo(iconKey.GetValue("").ToString());
            IconExactor ie = new IconExactor(fi.IconFile);
            g.DrawIcon(ie.IconList[fi.Index], 0, 0);
        }

        private FileIconInfo icoInfo;

        public FileIconInfo IconInfo
        {
            get { return icoInfo; }
            set
            {
                icoInfo = value;
                iconKey.SetValue("", icoInfo.IconInfo, RegistryValueKind.String);
            }
        }

        public string FileDescription
        {
            get 
            {
                object obj = fileKey.GetValue("");
                if (obj == null)
                    return "";
                else
                    return obj.ToString(); 
            }
            set { fileKey.SetValue("", value, RegistryValueKind.String); }
        }

        [DllImport("shell32.dll")]
        public static extern void SHChangeNotify(
            long eventID,
            uint flags,
            IntPtr item1,
            IntPtr item2);


        public static void Refresh()
        {
            SHChangeNotify(0x08000000, 0, IntPtr.Zero, IntPtr.Zero);
        }



    }

    class IconExactor
    {
        string filePath;
        public IconExactor(string filePath)
        {
            this.filePath = filePath;
            int count = ExtractIcon(0, filePath, -1);

            for (int i = 0; i < count; i++)
            {
                int hIcon = ExtractIcon(0, filePath, i);
                Icon ico = Icon.FromHandle(new IntPtr(hIcon));

                icoList.Add(ico);
            }
        }

        [DllImport("shell32.dll", EntryPoint = "ExtractIcon")]
        static extern int ExtractIcon(
            int hInst,
            string lpszExeFileName,
            int nIconIndex
        );

        private List<Icon> icoList = new List<Icon>();
        public List<Icon> IconList
        {
            get { return icoList; }
        }
    }
}
