using System;
using System.Configuration;
using System.ServiceModel.Configuration;
using System.ServiceModel.Description;

namespace WSPOSInitiative.Common
{
    #region Endpoint毎のデバイス情報取り扱いクラス

    /// <summary>
    /// .configでのEndpoint毎のデバイス指定内容を実行時に取り扱うためのクラス定義
    /// The class definition for dealing with the contents of device specification for every Endpoint in .config at instruction execution time  
    /// </summary>
    public class ConfigDeviceBehavior : IEndpointBehavior
    {
        /// <summary>
        /// .configでの指定内容を保持する変数
        /// The variable holding the contents of specification in .config
        /// </summary>
        private string _deviceName;
        private int _providerSessionTimeout;
        private int _sessionCheckPeriod;
        private int _eventPollingTimeout;
        private int _eventResponseTimeout;
        private bool _codePageConversion;

        /// <summary>
        /// ConfigDeviceBehaviorのコンストラクタ
        /// Constructor
        /// </summary>
        public ConfigDeviceBehavior()
        {
            this._deviceName = string.Empty;
            this._providerSessionTimeout = 180;
            this._sessionCheckPeriod = 1;
            this._eventPollingTimeout = -1;
            this._eventResponseTimeout = -1;
            this._codePageConversion = true;
        }

        /// <summary>
        /// .configでの指定内容を格納・通知するプロパティ・動作定義
        /// The property and the definition of operation which stores and notifies the contents of specification in .config 
        /// </summary>
        public string deviceName { get { return _deviceName; } set { _deviceName = value; } }
        public int providerSessionTimeout { get { return _providerSessionTimeout; } set { _providerSessionTimeout = value; } }
        public int sessionCheckPeriod { get { return _sessionCheckPeriod; } set { _sessionCheckPeriod = value; } }
        public int eventPollingTimeout { get { return _eventPollingTimeout; } set { _eventPollingTimeout = value; } }
        public int eventResponseTimeout { get { return _eventResponseTimeout; } set { _eventResponseTimeout = value; } }
        public bool codePageConversion { get { return _codePageConversion; } set { _codePageConversion = value; } }

        /// <summary>
        /// IEndpointBehaviorで動作をカスタマイズする際に実装する各関数
        /// Each function mounted when customizing operation by IEndpointBehavior 
        /// </summary>
        /// <param name="endpoint"></param>
        /// <param name="bindingParameters"></param>
        /// <param name="clientRuntime"></param>
        /// <param name="endpointDispatcher"></param>
        void IEndpointBehavior.AddBindingParameters(ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters) { }
        void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime){}
        void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.EndpointDispatcher endpointDispatcher){}
        void IEndpointBehavior.Validate(ServiceEndpoint endpoint){}
    }
    #endregion

    #region .config endpointBehavior device information class

    /// <summary>
    /// .configファイルでEndpoint毎の動作(OpenDeviceでのデバイス名および各種タイマ値)の設定を取り扱うクラスの定義
    /// The definition of the class which deals with a setup of the operation (the device name and the various timer values in OpenDevice) for every Endpoint by a .config file 
    /// </summary>
    public class ConfigDeviceBehaviorExtensionElement : BehaviorExtensionElement
    {
        /// <summary>
        /// ConfigDeviceBehaviorExtensionElementのコンストラクタ
        /// Constructor
        /// </summary>
        public ConfigDeviceBehaviorExtensionElement() { }

        /// <summary>
        /// このクラスで扱っているBehaviorのType情報通知関数
        /// The Type information notification function of Behavior currently treated in this class 
        /// </summary>
        public override Type BehaviorType
        {
            get { return typeof(ConfigDeviceBehavior); }
        }

        /// <summary>
        /// ConfigDeviceBehaviorオブジェクトを作成・設定する
        /// A ConfigDeviceBehavior object is created and set up. 
        /// </summary>
        /// <returns>作成したConfigDeviceBehaviorオブジェクト | Created ConfigDeviceBehavior object</returns>
        protected override object CreateBehavior()
        {
            ConfigDeviceBehavior ConfigDevice = new ConfigDeviceBehavior();

            ConfigDevice.deviceName = deviceName;
            ConfigDevice.providerSessionTimeout = providerSessionTimeout;
            ConfigDevice.sessionCheckPeriod = sessionCheckPeriod;
            ConfigDevice.eventPollingTimeout = eventPollingTimeout;
            ConfigDevice.eventResponseTimeout = eventResponseTimeout;

            return ConfigDevice;
        }

        /// <summary>
        /// OpenDeviceで使用するPOS for.NET,OpenPOSのデバイス名：必須
        /// POS for.NET, the device name of OpenPOS which are used by OpenDevice: Indispensable 
        /// </summary>
        [ConfigurationProperty("deviceName", IsRequired = true)]
        public string deviceName
        {
            get { return (string)base["deviceName"]; }
            set { base["deviceName"] = value; }
        }

        /// <summary>
        /// プロバイダのセッションタイムアウト値(秒)：デフォルト180秒
        /// A provider's session timeout value (second): Default 180 seconds 
        /// </summary>
        [ConfigurationProperty("providerSessionTimeout", DefaultValue = 180, IsRequired = false)]
        public int providerSessionTimeout
        {
            get { return (int)base["providerSessionTimeout"]; }
            set { base["providerSessionTimeout"] = value; }
        }

        /// <summary>
        /// プロバイダのセッションタイムアウトチェック周期(秒)：デフォルト1秒
        /// A provider's session time-out-check interval (second): Default 1 second 
        /// </summary>
        [ConfigurationProperty("sessionCheckPeriod", DefaultValue = 1, IsRequired = false)]
        public int sessionCheckPeriod
        {
            get { return (int)base["sessionCheckPeriod"]; }
            set { base["sessionCheckPeriod"] = value; }
        }

        /// <summary>
        /// ロングポーリング用のイベント待ちタイムアウト値(秒)：デフォルト -1(無限待ち=HTTPセッションのタイムアウト値)
        /// The waiting timeout value for an event for long polling (second): Default-1 (waiting for infinity = timeout value of a HTTP session) 
        /// </summary>
        [ConfigurationProperty("eventPollingTimeout", DefaultValue = -1, IsRequired = false)]
        public int eventPollingTimeout
        {
            get { return (int)base["eventPollingTimeout"]; }
            set { base["eventPollingTimeout"] = value; }
        }

        /// <summary>
        /// ロングポーリング/自己ホスト両用のイベント処理終了待ちタイムアウト値(秒)：デフォルト -1(無限待ち=HTTPセッションのタイムアウト値)
        /// The waiting timeout value for the end of event processing long polling / both for a self-host (second): Default 1 (waiting for infinity = timeout value of a HTTP session) 
        /// </summary>
        [ConfigurationProperty("eventResponseTimeout", DefaultValue = -1, IsRequired = false)]
        public int eventResponseTimeout
        {
            get { return (int)base["eventResponseTimeout"]; }
            set { base["eventResponseTimeout"] = value; }
        }

        /// <summary>
        /// OPOS SO とのやりとりで 文字列をNIBBLE化する際に コードページの変換をするか否か
        /// Whether or not the code page conversion to string a NIBBLE in interacting with OPOS SO
        /// </summary>
        [ConfigurationProperty("codePageConversion", DefaultValue = true, IsRequired = false)]
        public bool codePageConversion
        {
            get { return (bool)base["codePageConversion"]; }
            set { base["codePageConversion"] = value; }
        }

    }

    #endregion
}
