using MuEditor.Properties;
using System;
using System.Collections;
using System.Drawing;
using System.IO;
using System.Windows.Forms;

namespace MuEditor
{
    public class EquipImageCache
    {
        private class Nested
        {
            internal static readonly EquipImageCache instance;

            static Nested()
            {
                instance = new EquipImageCache();
            }
        }

        private Hashtable cache = new Hashtable();

        public static EquipImageCache Instance => Nested.instance;

        private EquipImageCache()
        {
        }

        public static byte[] BitmapToBytes(Bitmap Bitmap)
        {
            MemoryStream memoryStream = null;
            try
            {
                memoryStream = new MemoryStream();
                Bitmap.Save(memoryStream, Bitmap.RawFormat);
                long length = memoryStream.Length;
                return memoryStream.ToArray();
            }
            catch (ArgumentNullException ex)
            {
                throw ex;
            }
            finally
            {
                memoryStream.Close();
            }
        }

        private Image byteArrayToImage(byte[] Bytes)
        {
            using (MemoryStream stream = new MemoryStream(Bytes))
            {
                return Image.FromStream(stream);
            }
        }

        public static bool ExistsFile(string FilePath)
        {
            if (File.Exists(FilePath))
            {
                return true;
            }
            return false;
        }

        public EquipItem getItem(string name)
        {
            EquipItem equipItem = null;
            EquipItem equipItem2 = (EquipItem)cache[name];
            equipItem = equipItem2;
            if (equipItem2 == null)
            {
                lock (cache)
                {
                    EquipItem equipItem3 = (EquipItem)cache[name];
                    equipItem = equipItem3;
                    if (equipItem3 == null)
                    {
                        equipItem = (getItemFromDb(name) ?? EquipItem.UnknownItem);
                        cache[name] = equipItem;
                        cache[equipItem.CodeType] = equipItem;
                        return equipItem;
                    }
                    return equipItem;
                }
            }
            return equipItem;
        }

        public EquipItem getItemByCodeType(string codeType)
        {
            EquipItem equipItem = null;
            EquipItem equipItem2 = (EquipItem)cache[codeType];
            equipItem = equipItem2;
            if (equipItem2 == null)
            {
                lock (cache)
                {
                    EquipItem equipItem3 = (EquipItem)cache[codeType];
                    equipItem = equipItem3;
                    if (equipItem3 == null)
                    {
                        equipItem = (getItemFromDb(EquipItem.getItemCode(codeType), EquipItem.getItemType(codeType)) ?? EquipItem.UnknownItem);
                        cache[codeType] = equipItem;
                        cache[equipItem.Name] = equipItem;
                        return equipItem;
                    }
                    return equipItem;
                }
            }
            return equipItem;
        }

        protected EquipItem getItemFromDb(string ItemName)
        {
            byte[] numArray = null;
            EquipItem equipItem = null;
            try
            {
                int num = 0;
                while (num < (int)EquipEditor.xItem.Length)
                {
                    if (EquipEditor.xItem[num] == null || !(frmMain.ByteToString(EquipEditor.xItem[num].Name, 30) == ItemName))
                    {
                        num++;
                    }
                    else
                    {
                        int wIZARD = EquipEditor.xItem[num].iClassNumber.WIZARD + EquipEditor.xItem[num].iClassNumber.KNIGHT << (1 + EquipEditor.xItem[num].iClassNumber.ELF & 31) << (2 + EquipEditor.xItem[num].iClassNumber.MAGUMSA & 31) << (3 + EquipEditor.xItem[num].iClassNumber.DARKLORD & 31) << 4;
                        bool flag = (EquipEditor.xItem[num].iClassNumber.WIZARD != 0 ? true : EquipEditor.xItem[num].iClassNumber.SUMMONER != 0);
                        equipItem = new EquipItem(EquipEditor.xItem[num].Index, frmMain.ByteToString(EquipEditor.xItem[num].Name, 30), EquipEditor.xItem[num].TwoHand, EquipEditor.xItem[num].Group, EquipEditor.xItem[num].X, EquipEditor.xItem[num].Y, wIZARD, flag);
                        string str = string.Concat(Application.StartupPath, "\\Item\\{0}-{1}.jpg");
                        str = string.Format(str, EquipEditor.xItem[num].Index, EquipEditor.xItem[num].Group);
                        numArray = (!EquipImageCache.ExistsFile(str) ? EquipImageCache.BitmapToBytes(Resources.unknownItem) : this.imageToByteArray(str));
                        equipItem.Img = this.byteArrayToImage(numArray);
                        break;
                    }
                }
            }
            catch (Exception exception1)
            {
                Exception exception = exception1;
                string[] message = new string[] { "getItemFromDb：\nError:", exception.Message, "\nSource:", exception.Source, "\nTrace:", exception.StackTrace };
                Utils.WarningMessage(string.Concat(message));
            }
            return equipItem;
        }

        protected EquipItem getItemFromDb(ushort ItemIndex, ushort ItemType)
        {
            byte[] numArray = null;
            EquipItem equipItem = null;
            try
            {
                int itemType = ItemType * 512 + ItemIndex;
                if (EquipEditor.xItem[itemType] != null)
                {
                    int wIZARD = EquipEditor.xItem[itemType].iClassNumber.WIZARD + EquipEditor.xItem[itemType].iClassNumber.KNIGHT << (1 + EquipEditor.xItem[itemType].iClassNumber.ELF & 31) << (2 + EquipEditor.xItem[itemType].iClassNumber.MAGUMSA & 31) << (3 + EquipEditor.xItem[itemType].iClassNumber.DARKLORD & 31) << 4;
                    bool flag = (EquipEditor.xItem[itemType].iClassNumber.KNIGHT != 0 ? false : string.Concat(EquipEditor.xItem[itemType].iClassNumber.WIZARD.ToString(), EquipEditor.xItem[itemType].iClassNumber.SUMMONER.ToString()).Replace("0", "") != "");
                    equipItem = new EquipItem(EquipEditor.xItem[itemType].Index, frmMain.ByteToString(EquipEditor.xItem[itemType].Name, 30), EquipEditor.xItem[itemType].TwoHand, EquipEditor.xItem[itemType].Group, EquipEditor.xItem[itemType].X, EquipEditor.xItem[itemType].Y, wIZARD, flag);
                    string str = string.Concat(Application.StartupPath, "\\Item\\{0}-{1}.jpg");
                    str = string.Format(str, EquipEditor.xItem[itemType].Index, EquipEditor.xItem[itemType].Group);
                    numArray = (!EquipImageCache.ExistsFile(str) ? EquipImageCache.BitmapToBytes(Resources.unknownItem) : this.imageToByteArray(str));
                    equipItem.Img = this.byteArrayToImage(numArray);
                }
            }
            catch (Exception exception1)
            {
                Exception exception = exception1;
                string[] message = new string[] { "getItemFromDb：\nError:", exception.Message, "\nSource:", exception.Source, "\nTrace:", exception.StackTrace };
                Utils.WarningMessage(string.Concat(message));
            }
            return equipItem;
        }

        private byte[] imageToByteArray(string FilePath)
        {
            using (MemoryStream memoryStream = new MemoryStream())
            {
                using (Image image = Image.FromFile(FilePath))
                {
                    using (Bitmap bitmap = new Bitmap(image))
                    {
                        bitmap.Save(memoryStream, image.RawFormat);
                    }
                }
                return memoryStream.ToArray();
            }
        }
    }
}