using System.Collections.Generic;
using Toolbox.Declarations;
using Toolbox.Docking.Api.Data;
using Toolbox.Docking.Api.ExtraActions;
using Toolbox.Docking.Api.Objects;
using Toolbox.Docking.Api.Objects.Calculator;
using Toolbox.Docking.Api.Objects.Metabolism;
using Toolbox.Docking.Api.Objects.Profiler;
using Toolbox.Docking.Api.Objects.Qsar;
using Toolbox.Docking.Api.Units;

namespace Toolbox.Docking.Api.Control
{
    /// <summary>
    /// Provides access to information for all registered objects.
    /// Used in initialization functions to validate presence of required cross-used objects.
    /// </summary>
    public interface ITbObjectCatalog
    {
        #region ObjectIds

        /// <summary>
        /// QSAR Toolbox Calculators.
        /// </summary>
        IReadOnlyList<TbObjectId> Calculators { get; }

        /// <summary>
        /// QSAR Toolbox Metabolisms.
        /// </summary>
        IReadOnlyList<TbObjectId> Metabolisms { get; }

        /// <summary>
        /// QSAR Toolbox QSARs
        /// </summary>
        IReadOnlyList<TbObjectId> Qsars { get; }

        /// <summary>
        /// QSAR Toolbox Profilers.
        /// </summary>
        IReadOnlyList<TbObjectId> Profilers { get; }

        #endregion
        
        #region Object information

        /// <summary>
        /// Provides About information for a particular Toolbox object.
        /// </summary>
        /// <param name="id">The Toolbox object identifier.</param>
        /// <returns>
        /// About object for the Toolbox object.
        /// </returns>
        TbObjectAbout GetAbout(TbObjectId id);

        /// <summary>
        /// Provides calculator's info for a Calculator Toolbox object.
        /// </summary>
        /// <param name="id">The Toolbox object identifier.</param>
        /// <param name="initTask">This is required parameter because the call may
        /// trigger object initialization
        /// </param>
        /// <returns>
        /// Calculator information object for the Toolbox object.
        /// </returns>
        TbCalculatorInfo GetCalculatorInfo(TbObjectId id, ITbInitTask initTask);

        /// <summary>
        /// Provides metabolism's info for a Metabolism Toolbox object.
        /// </summary>
        /// <param name="id">The Toolbox object identifier.</param>
        /// <returns>
        /// Metabolism information object for the Toolbox object.
        /// </returns>
        TbMetabolismInfo GetMetabolismInfo(TbObjectId id);

        /// <summary>
        /// Provides profiler's info for a Profiler Toolbox object.
        /// </summary>
        /// <param name="id">The Toolbox object identifier.</param>
        /// <returns>
        /// Profiler information object for the Toolbox object.
        /// </returns>
        TbProfilerInfo GetProfilerInfo(TbObjectId id);

        /// <summary>
        /// Provides QSAR's info for a QSAR Toolbox object.
        /// </summary>
        /// <param name="id">The Toolbox object identifier.</param>
        /// <returns>
        /// QSAR information object for the Toolbox object.
        /// </returns>
        TbQsarInfo GetQsarInfo(TbObjectId id);

        #endregion

        #region Data

        /// <summary>
        /// Returns the ServerMode the objects in the catalog operate in.
        /// </summary>
        TbServerMode ServerMode { get; }

        #endregion

        #region Extra actoins

        /// <summary>
        /// Provide extra actions of other objects. Can be used if one object wrap another or for object-object communication.
        /// If the queried object factory not implement ITbObjectFactoryExtraAction the result is null 
        /// </summary>
        /// <param name="objectId">The target object</param>
        /// <returns>List of extra actions.</returns>
        IEnumerable<TbExtraActionDefinition> GetExtraActions(TbObjectId objectId);

        #endregion

        #region Options

        /// <summary>
        /// Provide access to client options module of another object. 
        /// </summary>
        /// <param name="objectId">The Toolbox object identifier.</param>
        /// <returns>Return ClientOptionsModule if objectId correspond to ITbObjectFactoryTunable, otherwise return null</returns>
        string GetClientOptionsModule(TbObjectId objectId);


        /// <summary>
        /// Provide access to client DefaultOptions of another object. 
        /// </summary>
        /// <param name="objectId">The Toolbox object identifier.</param>
        /// <returns>Return DefaultOptions if objectId correspond to ITbObjectFactoryTunable, otherwise return null</returns>
        string DefaultOptions(TbObjectId objectId);

        #endregion

        #region Services

        /// <summary>
        /// Prepares a canonized version of a SMILES that may be of an unknown origin.
        /// </summary>
        /// <param name="nonCanonicalSmiles">Input SMILES.</param>
        /// <returns>
        /// Resulting canonical SMILES.
        /// </returns>
        string UnifySmiles(string nonCanonicalSmiles);

        /// <summary>
        /// Convert a  <see cref="TbScalarData"/> or <see cref="TbData"/> value from it's unit to a new unit. 
        /// Chemical is provided because some conversions required Molecular weight
        /// </summary>
        /// <param name="data">Data to be converted</param>
        /// <param name="toUnit">Target unit of conversion</param>
        /// <param name="chemical">Chemical related with converted data</param>
        /// <returns>The prepared scalar data object.</returns>
        TbScalarData ConvertData(TbScalarData data, TbUnit toUnit, Chemical.Chemical chemical);

        /// <summary>
        /// Return a list with all registered in the system scales.
        /// </summary>
        /// <returns>
        /// List of Toolbox scales.
        /// </returns>
        List<TbScale> GetAllScales();


        #endregion
    }
}