using System;
using System.Collections.Generic;
using Toolbox.Docking.Api.Data;
using Toolbox.Docking.Api.ExtraActions;
using Toolbox.Docking.Api.Objects;

namespace Toolbox.Docking.Api.Control
{
    /// <summary>
    /// This provides docked modules with access to Toolbox services.
    /// </summary>
    public interface ITbCalcService : ITbObjectCatalog
    {
        /// <summary>
        /// Indicates what mode the ITbCalcService operates in.
        /// </summary>
        bool StereoMode { get; }

        /// <summary>
        /// Return the current options of an object.
        /// If object has no options will return null.
        /// The obtained options can be used as parameter for any other service call.
        /// All service calls which requires options can be called with null in which case the default options for the object will be used.
        /// The purpose of this function is to store current options for later usages
        /// </summary>
        /// <param name="objectId">The Toolbox object identifier.</param>
        /// <returns>The Toolbox options encoded to string.</returns>
        string GetCurrentOptions(TbObjectId objectId);

        #region Domain
        /// <summary>
        /// Predict domain of a target chemical.
        /// If specified object not implements ITbDomainProvider the result is TbDomainStatus.Undefined
        /// </summary>
        /// <param name="objectId">Identifier of the Toolbox object that will perform the check</param>
        /// <param name="target">Target chemical for the domain check.</param>
        /// <returns>Domain status result.</returns>
        TbDomainStatus CheckDomain(TbObjectId objectId, ITbBasket target);

        /// <summary>
        /// Predict domain of a list of chemicals.
        /// If specified object not implements ITbDomainProvider the results are TbDomainStatus.Undefined
        /// </summary>
        /// <param name="objectId">Identifier of the Toolbox object that will perform the check</param>
        /// <param name="task">The task to be used for notifications and flow control.</param>
        /// <param name="targets">The target chemicals</param>
        /// <returns>Domain status result.</returns>
        IReadOnlyList<TbDomainStatus> CheckDomain(TbObjectId objectId, ITbWorkTask task, IReadOnlyList<Chemical.Chemical> targets);
        #endregion

        #region Extra actoins
        /// <summary>
        /// Execute an extra action of another object. Can be used when one object wrap another to re-address execution to wrapped object.
        /// If the queried object factory not implement ITbObjectFactoryExtraAction the result is null  
        /// </summary>
        /// <param name="objectId">Toolbox object id that will be executing the action.</param>
        /// <param name="action">GUID of the actuion.</param>
        /// <param name="command">Integer code of the executed command.</param>
        /// <param name="payload">Payload encoded as string that will be transported from to/from the client/server side modules of the Toolbox addin. </param>
        /// <param name="target">Target chemical the Toolbox action would be performed over.</param>
        /// <returns>The extra action's result</returns>
        TbExtraActionResult ExecuteExtraAction(TbObjectId objectId, Guid action, int command, string payload, ITbBasket target);

        #endregion

        #region Calculate parameter
        /// <summary>
        /// Calculates a parameter value for a <see cref="Chemical"/>.
        /// </summary>
        /// <param name="calculatorId">The Toolbox ID of the calculator performing the calculation.</param>
        /// <param name="options">Options for the calculation. Use <b>string.Empty</b> if no options are needed. 
        /// </param>
        /// <param name="target">The target basket, containing the <see cref="Chemical"/>. </param>
        /// <returns>
        /// Resulting TbScalarData object with the calculation. 
        /// </returns>
        TbScalarData CalculateParameter(TbObjectId calculatorId, string options, ITbBasket target);
        /// <summary>
        /// Calculates parameter values for a list of Chemicals. 
        /// </summary>
        /// <param name="calculatorId">The Toolbox ID of the calculator performing the calculation.</param>
        /// <param name="options">Options for the calculation. Use <b>string.Empty</b> if no options are needed.</param>
        /// <param name="task">The task governing the calculation. This is to be used for progress updates and/or access 
        /// to Toolbox services.
        /// </param>
        /// <param name="targets">The list chemicals for calculations.</param>
        /// <returns>
        /// The list with calculation results, corresponding to target list.
        /// </returns>
        IReadOnlyList<TbScalarData> CalculateParameter(TbObjectId calculatorId, string options, ITbWorkTask task, IReadOnlyList<Chemical.Chemical> targets);
        #endregion

        #region Profiling
        /// <summary>
        /// Return the list of categories a <see cref="Chemical"/> for a given Profiler
        /// </summary>
        /// <param name="profilerId">The Toolbox ID of the Profiler</param>
        /// <param name="options">Options for the calculation. Use <b>string.Empty</b> if no options are needed.</param>
        /// <param name="target">The target basket, containing the <see cref="Chemical"/> </param>
        /// Parameters for the Profiler application.
        /// <returns>
        /// Resulting list of categories for the profiled chemical.
        /// </returns>
        IReadOnlyList<string> GetCategoriesOf(TbObjectId profilerId, string options, ITbBasket target);

        /// <summary>
        /// Return the list of categories for a <see cref="Chemical"/> list for a given Profiler
        /// </summary>
        /// <param name="profilerId">The Toolbox ID of the Profiler</param>
        /// <param name="options">Options for the calculation. Use <b>string.Empty</b> if no options are needed</param>
        /// <param name="task">The task governing the Profiler application. This is to be used for progress updates and/or access 
        /// to Toolbox services.
        /// </param>
        /// <param name="targets">The list chemicals up for Profiler assessment</param>
        /// <returns>
        /// Resulting list of lists of categories for the profiled chemicals.
        /// </returns>
        IReadOnlyList<IReadOnlyList<string>> GetCategoriesOf(TbObjectId profilerId, string options, ITbWorkTask task, IReadOnlyList<Chemical.Chemical> targets);
        #endregion

        #region QSAR
        /// <summary>
        /// Calculates a QSAR prediction value for a <see cref="Chemical"/>. 
        /// </summary>
        /// <param name="qsarId">The Toolbox ID of the QSAR performing the calculation.</param>
        /// <param name="options">Options for the calculation. Use <b>string.Empty</b> if no options are needed.</param>
        /// <param name="target">The target basket, containing the <see cref="Chemical"/> </param>
        /// <returns> Resulting TbScalarData object with the QSAR prediction. </returns>
        TbScalarData CalculateQsar(TbObjectId qsarId, string options, ITbBasket target);

        /// <summary>
        /// Calculates QSAR prediction values for a list of Chemicals. 
        /// </summary>
        /// <param name="qsarId">The Toolbox ID of the QSAR performing the calculation.</param>
        /// <param name="options">Options for the calculation. Use <b>string.Empty</b> if no options are needed.</param>
        /// <param name="task">The task governing the calculation. This is to be used for progress updates and/or access 
        /// to Toolbox services.
        /// </param>
        /// <param name="targets">The list of chemicals for calculations.</param>
        /// <returns>
        /// The list with prediction results, corresponding to target list.
        /// </returns>
        IReadOnlyList<TbScalarData> CalculateQsar(TbObjectId qsarId, string options, ITbWorkTask task, IReadOnlyList<Chemical.Chemical> targets);
        #endregion

        #region Metabolism
        /// <summary>
        /// Metabolizes a <see cref="Chemical"/> using a Toolbox Metabolizer object. 
        /// </summary>
        /// <param name="metabolizerId">The Toolbox ID of the Toolbox object metabolizing the chemical.</param>
        /// <param name="options">Options for the calculation. Use <b>string.Empty</b> if no options are needed.</param>
        /// <param name="target">The target basket, containing the <see cref="Chemical"/>.</param>
        /// <returns>
        /// Resulting list of Chemicals(products)
        /// </returns>
        IReadOnlyList<Chemical.Chemical> GetMetabolites(TbObjectId metabolizerId, string options, ITbBasket target);

        /// <summary>
        /// Metabolizes a list of Chemicals using a Toolbox Metabolizer object. 
        /// </summary>
        /// <param name="metabolizerId">The Toolbox ID of the Toolbox object performing the metabolization the chemicals.</param>
        /// <param name="options">Options for the calculation. Use <b>string.Empty</b> if no options are needed.</param>
        /// <param name="task">The task governing the calculation. This is to be used for progress updates and/or access 
        /// to Toolbox services.</param>
        /// <param name="targets">The list of chemicals to be metabolized.</param>
        /// <returns>
        /// The list with metabolism results(list of products), corresponding to target list.
        /// </returns>
        IReadOnlyList<IReadOnlyList<Chemical.Chemical>> GetMetabolites(TbObjectId metabolizerId, string options, ITbWorkTask task, IReadOnlyList<Chemical.Chemical> targets);
        #endregion
    }
}