using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Pluto.Api;

namespace Pluto.MSL.Api
{
    public class API
    {
        #region Construction

        private static HiddenMainForm _hiddenFrm = null;
        static API()
        {            
            _hiddenFrm = new HiddenMainForm();
            _hiddenFrm.Opacity = 0;
            _hiddenFrm.Show();
            _hiddenFrm.Visible = false;
        }

        #endregion

        #region Change Network Settings

        /// <summary>
        /// Use this function to change the URL and port for the client to use when
        /// communicating (affects entire API)
        /// </summary>
        /// <param name="url"></param>
        /// <param name="port"></param>
        public static void SetNetworkSettings(string url, uint port)
        {
            bool bChangeOccured = false;
            if (!String.IsNullOrEmpty(url) && String.Compare(_hiddenFrm.ClientChannel.Hostname, url, true) != 0)
            {
                bChangeOccured = true;
                _hiddenFrm.ClientChannel.Hostname = url;
            }
            if (port > 0 && _hiddenFrm.ClientChannel.Port != (int)port)
            {
                bChangeOccured = true;
                _hiddenFrm.ClientChannel.Port = (int)port;
            }
            if (bChangeOccured)
            {
                _hiddenFrm.ClientChannel.TargetUrl = String.Format("tcp://{0}:{1}/bin", _hiddenFrm.ClientChannel.Hostname, _hiddenFrm.ClientChannel.Port);
            }            
        }

        #endregion

        #region IMSLMobileConnect

        /// <summary>
        /// Called by Lytec/Medisoft when the mobile About Dialog is called to retrieve the UserApiKey and Pin
        /// </summary>
        /// <param name="SharedConnectionDataSource"></param>
        /// <param name="PracticeName"></param>
        /// <param name="UserApiKey"></param>
        /// <param name="UserPin"></param>
        /// <returns></returns>
        public static bool MobileAboutDialog_GotCalled(string SharedConnectionDataSource, string RegisteredName, string PracticeName, string DataBaseNameOrDataSetName, out string UserApiKey, out string UserPin)
        {
            UserApiKey = String.Empty;
            UserPin = String.Empty;

            if (!String.IsNullOrEmpty(SharedConnectionDataSource) && !String.IsNullOrEmpty(PracticeName))
            {
                ApiKeyNPin key = _hiddenFrm.fMSLSpecific.MobileAboutDialogCalled(SharedConnectionDataSource, RegisteredName, PracticeName, DataBaseNameOrDataSetName);
                if (key == null)
                    return false;

                UserApiKey = key.UserApiKey;
                UserPin = key.UserPin;
                return true;
            }
            return false;
        }

        /// <summary>
        /// Called by Lytec/Medisoft once product setup is complete (product is registered and 
        /// connected to a database), but before the user logs in. This will setup the Mobile service
        /// on the server.
        /// </summary>        
        /// <param name="string SharedConnectionDataSource"></param>
        /// <returns></returns>
        public static bool ProductSetupCompleted_PriorUserLogin(string SharedConnectionDataSource, string RegisteredName)
        {
            if (!String.IsNullOrEmpty(SharedConnectionDataSource))
            {
                bool bResult = _hiddenFrm.fMSLSpecific.ProductSetupCompleted(SharedConnectionDataSource, RegisteredName);
                return bResult;
            }
            return false;
        }

        /// <summary>
        /// Called by Lytec/Medisoft after a Practice Name Change occurred on their end to let
        /// the Mobile solution know and update it's information
        /// </summary>
        /// <param name="SharedConnectionDataSource"></param>
        /// <param name="NewPracticeName"></param>
        /// <returns></returns>
        public static bool PracticeName_ChangeOccured(string SharedConnectionDataSource, string NewPracticeName, string DataBaseNameOrDataSetName)
        {
            if (!String.IsNullOrEmpty(SharedConnectionDataSource) && !String.IsNullOrEmpty(NewPracticeName))
            {
                bool bResult = _hiddenFrm.fMSLSpecific.PracticeNameChangeOccured(SharedConnectionDataSource, NewPracticeName, DataBaseNameOrDataSetName);
                return bResult;
            }
            return false;
        }

        /// <summary>
        /// Is the Server Reachable from the internet? if not, show error icon or give message
        /// </summary>
        /// <param name="SharedConnectionDataSource"></param>
        /// <returns></returns>
        public static bool IsServerReachableFromTheInternet(string SharedConnectionDataSource)
        {
            if (!String.IsNullOrEmpty(SharedConnectionDataSource))
            {
                bool bResult = _hiddenFrm.fMSLSpecific.IsServerReachableFromTheInternet(SharedConnectionDataSource);
                return bResult;
            }
            return false;            
        }

        #endregion

        #region Pluto AddOns

        /// <summary>
        /// Try to update the Service, if needed
        /// </summary>
        public static void UpdateServiceIfNeeded()
        {
            _hiddenFrm.fMSLSpecific.UpdateServiceIfNeeded();
        }

        /// <summary>
        /// Check if service isd out of date
        /// </summary>
        /// <returns></returns>
        public static bool IsAPIOutOfDate()
        {
            return _hiddenFrm.fAuthentication.IsAPIOutOfDate();
        }

        /// <summary>
        /// Retrieve the API version of the service
        /// </summary>
        /// <returns></returns>
        public static string GetAPIVersion()
        {
            return _hiddenFrm.fAuthentication.GetAPIVersion();
        }

        /// <summary>
        /// Retrieve the Pluto Service's HOST GUID
        /// </summary>
        /// <returns></returns>
        public static string GetHostGUID()
        {
            return _hiddenFrm.fMSLSpecific.GetHostSpecGUID();
        }

        /// <summary>
        /// Retrieve Pluto Service's External Port
        /// </summary>
        /// <returns></returns>
        public static int GetExternalPort()
        {
            return _hiddenFrm.fMSLSpecific.GetExternalPort();
        }

        /// <summary>
        /// Retrieve Pluto Service's External IP
        /// </summary>
        /// <returns></returns>
        public static string GetExternalIP()
        {
            return _hiddenFrm.fMSLSpecific.GetExternalIP();
        }

        /// <summary>
        /// Retrieve Pluto Service's Local IP
        /// </summary>
        /// <returns></returns>
        public static string GetLocalIP()
        {
            return _hiddenFrm.fMSLSpecific.GetLocalIP();
        }

        /// <summary>
        /// Generate all user api keys for all connections
        /// </summary>
        public static void GenerateApiKeysForPracticesInLoadedSharedCredentials()
        {
            _hiddenFrm.fMSLSpecific.GenerateApiKeysForPracticesInLoadedSharedCredentials();
        }

        /// <summary>
        /// Add a Shared Credential to the Store
        /// </summary>
        /// <param name="credential"></param>
        /// <returns></returns>
        public static bool AddSharedCredential(ApiKeyNCredential credential)
        {
            return _hiddenFrm.fMSLSpecific.AddSharedCredential(credential);
        }

        /// <summary>
        /// Rerieve all loaded Credentials
        /// </summary>
        /// <returns></returns>
        public static ApiKeyNCredential[] GetLoadedCredentials()
        {
            return _hiddenFrm.fMSLSpecific.GetLoadedCredentials();
        }

        #endregion

        #region Pluto 

        /// <summary>
        /// Post Billing
        /// </summary>
        public static bool PostBilling(string SystemApiKey, BillingPost1 billingPost)
        {
            return _hiddenFrm.fBilling.PostBilling(SystemApiKey, String.Empty, billingPost);            
        }

        #endregion
    }
}
