using System;
using System.Collections.Generic;
using System.Drawing;
using FastReport.Cloud.StorageClient;
using FastReport.Messaging;
using FastReport.Wizards;

namespace FastReport.Utils
{
    partial class ObjectInfo
    {
        #region Private Fields

        private int imageIndex;
        private int buttonIndex;
        private int flags;
        private bool multiInsert;

        #endregion Private Fields

        #region Public Properties

        /// <summary>
        /// Image index.
        /// </summary>
        public int ImageIndex
        {
            get { return imageIndex; }
            set { imageIndex = value; }
        }

        /// <summary>
        /// Button index.
        /// </summary>
        public int ButtonIndex
        {
            get { return buttonIndex; }
            set { buttonIndex = value; }
        }

        /// <summary>
        /// Flags that will be used to create an object instance in the designer.
        /// </summary>
        public int Flags
        {
            get { return flags; }
            set { flags = value; }
        }

        /// <summary>
        /// Indicates whether this object can be inserted several times simultaneously.
        /// </summary>
        /// <remarks>
        /// This is applied to Line object only.
        /// </remarks>
        public bool MultiInsert
        {
            get { return multiInsert; }
            set { multiInsert = value; }
        }


        #endregion Public Properties

        #region Private Methods

        private void UpdateDesign(Bitmap image, int imageIndex, int buttonIndex = -1)
        {
            ButtonIndex = buttonIndex;
            ImageIndex = imageIndex;
            if (image != null)
                ImageIndex = Res.AddImage(image);
        }


        private void UpdateDesign(int flags, bool multiInsert, Bitmap image, int imageIndex, int buttonIndex = -1)
        {
            UpdateDesign(image, imageIndex, buttonIndex);
            Flags = flags;
            MultiInsert = multiInsert;
        }

        #endregion Private Methods
    }


    enum ItemWizardEnum : int
    {
        /// <summary>
        /// 
        /// </summary>
        Report = 0,
        /// <summary>
        /// 
        /// </summary>
        ReportItem = 1,
        /// <summary>
        /// 
        /// </summary>
        Game = 2
    }

    partial class RegisteredObjects
    {
        #region Public Methods

        /// <summary>
        /// Registers a new cloud storage client.
        /// </summary>
        /// <param name="obj">Type of cloud storage client.</param>
        /// <param name="text">Text for cloud storage client's menu item.</param>
        /// <remarks>
        /// The <b>obj</b> must be of <see cref="CloudStorageClient"/> type.
        /// </remarks>
        /// <example>
        /// <code>
        /// // register own cloud storage client
        /// RegisteredObjects.AddCloud(typeof(MyCloud), "My Cloud");
        /// </code>
        /// </example>
        public static void AddCloud(Type obj, string text)
        {
            if (!obj.IsSubclassOf(typeof(Cloud.StorageClient.CloudStorageClient)))
            {
                throw new Exception("The 'obj' parameter must be of CloudStorageClient type.");
            }
            InternalAdd(obj, "", null, -1, text);
        }

        /// <summary>
        /// Registers a new messenger.
        /// </summary>
        /// <param name="obj">Type of messenger.</param>
        /// <param name="text">Text messenger's menu item.</param>
        /// <remarks>
        /// The <b>obj</b> must be of <see cref="MessengerBase"/> type.
        /// </remarks>
        /// <example>
        /// <code>
        /// // register own messenger
        /// RegisteredObjects.AddMessenger(typeof(MyMessenger), "My Messenger");
        /// </code>
        /// </example>
        public static void AddMessenger(Type obj, string text)
        {
            if (!obj.IsSubclassOf(typeof(Messaging.MessengerBase)))
            {
                throw new Exception("The 'obj' parameter must be of MessengerBase type.");
            }
            InternalAddMessenger(obj, text);
        }

        internal static ObjectInfo InternalAddMessenger(Type obj, string text)
        {
            return InternalAdd(obj, "", null, -1, text);
        }

        /// <summary>
        /// Registers a new wizard.
        /// </summary>
        /// <param name="obj">Type of wizard.</param>
        /// <param name="image">Image for wizard item.</param>
        /// <param name="text">Text for wizard item.</param>
        /// <param name="isReportItemWizard"><b>true</b> if this wizard creates some items in existing report.</param>
        /// <remarks>
        /// The <b>obj</b> must be of <see cref="WizardBase"/> type.
        /// </remarks>
        /// <example>This example shows how to register own wizard that is used to create some items in the
        /// current report. If you want to register a wizard that will be used to create a new report,
        /// set the <b>isReportItemWizard</b> to <b>false</b>.
        /// <code>
        /// // register own wizard
        /// RegisteredObjects.AddWizard(typeof(MyWizard), myWizBmp, "My Wizard", true);
        /// </code>
        /// </example>
        public static void AddWizard(Type obj, Bitmap image, string text, bool isReportItemWizard)
        {
            if (!obj.IsSubclassOf(typeof(WizardBase)))
                throw new Exception("The 'obj' parameter must be of WizardBase type.");
            InternalAdd(obj, "", image, -1, text, isReportItemWizard ? 1 : 0, false);
        }

        #endregion Public Methods


        #region Internal Methods

        internal static ObjectInfo AddCloud(Type obj, string text, int imageIndex)
        {
            if (!obj.IsSubclassOf(typeof(Cloud.StorageClient.CloudStorageClient)))
            {
                throw new Exception("The 'obj' parameter must be of CloudStorageClient type.");
            }
            return InternalAdd(obj, "", null, imageIndex, text);
        }

        internal static void AddMessenger(Type obj, string text, int imageIndex)
        {
            if (!obj.IsSubclassOf(typeof(Messaging.MessengerBase)))
            {
                throw new Exception("The 'obj' parameter must be of MessengerBase type.");
            }
            InternalAdd(obj, "", null, imageIndex, text);
        }

        internal static void AddWizard(Type obj, int imageIndex, string text, ItemWizardEnum itemWizardEnum)
        {
            InternalAdd(obj, "", null, imageIndex, text, (int)itemWizardEnum, false);
        }

        internal static FunctionInfo FindFunctionsRoot()
        {
            List<FunctionInfo> list = new List<FunctionInfo>();
            Functions.EnumItems(list);

            foreach (FunctionInfo item in list)
            {
                if (item.Name == "Functions")
                    return item;
            }
            return null;
        }

        #endregion Internal Methods
    }
}