using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace IndianHealthService.BMXNet.WinForm.Configuration
{
    /// <summary>
    /// Container for all persistent and available connection spec
    /// </summary>
    public class RpmsConnectionSettings
    {
        private Settings _userSettings = new Settings();

        public Settings UserSettings
        {
            get { return _userSettings; }
            set { _userSettings = value; }
        }
     
        private RpmsConnectionSpec _commandLineConnectionSpec = null;

        public RpmsConnectionSpec CommandLineConnectionSpec
        {
            get { return _commandLineConnectionSpec; }
            set { _commandLineConnectionSpec = value; }
        }

        private List<RpmsConnectionSpec> _managedConnectionSpecs = new List<RpmsConnectionSpec>();

        /// <summary>
        /// Answer all connection specs in user defined order
        /// </summary>
        public List<RpmsConnectionSpec> ManagedConnectionSpecs
        {
            get { return _managedConnectionSpecs; }
            set { _managedConnectionSpecs = value; }
        }

        /// <summary>
        /// Answer all available connection specs, including command-line spec
        /// </summary>
        public List<RpmsConnectionSpec> ConnectionSpecs
        {
            get { 
                if (this.CommandLineConnectionSpec==null) {
                    return this.ManagedConnectionSpecs; }
                else {
                    List<RpmsConnectionSpec> allSpecs=new List<RpmsConnectionSpec>(this.ManagedConnectionSpecs);
                    allSpecs.Insert(0,this.CommandLineConnectionSpec);
                    return allSpecs;
                }
            }
        }

        private RpmsConnectionSpec _defaultConnectionSpec=null;
        /// <summary>
        /// Answer the default connection spec. If there is not
        /// user defined default, answer the first connection spec
        /// </summary>
        public RpmsConnectionSpec DefaultConnectionSpec
        {
            get
            {
                if (_defaultConnectionSpec== null)
                {
                    if (this.CommandLineConnectionSpec == null)
                    {
                        foreach (RpmsConnectionSpec each in this.ManagedConnectionSpecs)
                        {
                            if (each.IsDefault)
                            {
                                return each;
                            }
                        }
                    }
                    return this.ConnectionSpecs.Count == 0 ? null : this.ConnectionSpecs[0];

                }
                else
                {
                    return _defaultConnectionSpec;
                }
            }
            set { this._defaultConnectionSpec = value; }
        }

        /// <summary>
        /// Add aSpec to the receiver.  Not persisted
        /// </summary>
        /// <param name="aSpec"></param>
        public void AddConnectionSpec(RpmsConnectionSpec aSpec)
        {
            this.ManagedConnectionSpecs.Add(aSpec);
            if (aSpec.IsDefault)
            {
                this.SetConnectionSpecAsDefault(aSpec);
            }

        }

        /// <summary>
        /// Remove aSpec from the receiver.  Not persisted.
        /// </summary>
        /// <param name="aSpec"></param>
        public void RemoveConnectionSpec(RpmsConnectionSpec aSpec)
        {
            this.ManagedConnectionSpecs.Remove(aSpec);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aSpec"></param>
        /// <returns>True if there was any movement</returns>
        public bool MoveConnectionSpecUp(RpmsConnectionSpec aSpec)
        {
            int currentIndex = this.ManagedConnectionSpecs.IndexOf(aSpec);

            if (currentIndex == 0)
            {
                return false;
            }
            else
            {
                this.RemoveConnectionSpec(aSpec);
                this.ManagedConnectionSpecs.Insert(currentIndex - 1, aSpec);
                return true;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="aSpec"></param>
        /// <returns>True if there was any movement</returns>
        public bool MoveConnectionSpecDown(RpmsConnectionSpec aSpec)
        {
            int currentIndex = this.ManagedConnectionSpecs.IndexOf(aSpec);

            if (currentIndex == this.ManagedConnectionSpecs.Count - 1)
            {
                return false;
            } else {
                this.RemoveConnectionSpec(aSpec);
                this.ManagedConnectionSpecs.Insert(currentIndex + 1, aSpec);
                return true;
            }
        }

        public void SetConnectionSpecAsDefault(RpmsConnectionSpec aSpec)
        {
            foreach (RpmsConnectionSpec each in this.ManagedConnectionSpecs)
            {
                each.IsDefault = false;
            }
            aSpec.IsDefault = true;
        }




    
       

         /// <summary>
        /// Refresh the receiver from the current state of the persistent store
        /// </summary>
        public void Revert()
        {           
            this.Load();
        }

        public void Load()
        {
            this.ManagedConnectionSpecs = this.Store.Read<List<RpmsConnectionSpec>>(this.StorageKeys);
            if (this.ManagedConnectionSpecs == null)
                this.ManagedConnectionSpecs = new List<RpmsConnectionSpec>();
          
        }

        public void Save()
        {
            this.Store.Write<List<RpmsConnectionSpec>>(this.ManagedConnectionSpecs, this.StorageKeys);       
        }

        private string[] _storageKeys = null;

        public string[] StorageKeys
        {
            get { return _storageKeys; }
            set { _storageKeys = value; }
        }

        private PersistentStore _store = null;

        public PersistentStore Store
        {
            get { return _store; }
            set { _store = value; }
        }

    }
}
