using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using ChamChat.Models;

namespace ChamChat
{
    public  abstract class Client
    {
        public Client(Int32 MIDS, ClientType Type)
        {
            _MIDS = MIDS;
            _Type = Type;
            _DataTransferLogs = new List<DataTransferLog>();
        }

        
        protected Int32 _MIDS = 0; public Int32 MIDS { get { return _MIDS; } set { _MIDS = value; } }
        protected Int32 _Address = 1; public Int32 Address { get { return _Address; } set { _Address = value; } }
        protected Interface _Interface; public Interface Interface { get { return _Interface; } set { _Interface = value; } }
        
        protected InterfaceType _InterfaceType; 
        public InterfaceType InterfaceType { get { return _InterfaceType; } } // Interface type is set as constant
        
        
        
        protected List<ProfileOption> _ClientOptions; public List<ProfileOption> Options { get { return _ClientOptions; } }
        protected List<Parameter> _Parameters; public List<Parameter> Parameters { get { return _Parameters; } }
        protected String _InterfaceID; public String InterfaceID { get { return _Interface.ID; } }
        protected Profile _Profile;
        protected List<Alarm> _Alarms; public List<Alarm> Alarms { get { return _Alarms; } }
        protected List<Int32> _AvailableRAMs = new List<int>(); public List<Int32> AvailableRAMs { get { return _AvailableRAMs; } }
        protected ClientType _Type; public ClientType Type { get { return _Type; } }


        protected string _DataTransferLogFile = null;  // Set in Task.InitDataTransferLog()
        public String DataTransferLogFile { get { return _DataTransferLogFile; } set { _DataTransferLogFile = value; } }
        
        
        
        protected List<ClientMessage> _ClientMessages = new List<ClientMessage>(); public List<ClientMessage> ClientMessages { get { return _ClientMessages; } set { _ClientMessages = value; } }
        


        public String TypeDescription { get { return _Type.ToStr(); } }


        protected void AppendDataTransferLog(DataTransferLog log)
        {
            try
            {
                //  Save all logs to file, but only keep the logs to show in the GUI in memory.
                if (log.ShowInGUI)
                    this._DataTransferLogs.Add(log);

                if (_DataTransferLogFile != null)
                {
                    using (StreamWriter sw = File.AppendText(_DataTransferLogFile))
                    {
                        sw.WriteLine(log.ToCSV());
                    }
                }
            }
            catch { }
        }
        protected List<DataTransferLog> _DataTransferLogs;
        public List<DataTransferLog> DataTransferLogs
        {
            get
            {
                List<DataTransferLog> result = new List<DataTransferLog>();
                int n = _DataTransferLogs.Count;
                for (int i = 0; i < n; i++)
                {
                    result.Add(_DataTransferLogs[i]);
                }
                return result;
            }
            set { _DataTransferLogs = value; } // Is set to new list in Task constructor
        }


 


        public abstract Profile ReadProfile(int RAM, ref System.ComponentModel.BackgroundWorker bgw);

        public abstract Boolean WriteProfile(Profile Profile);

        public abstract Boolean WriteProfile(Profile Profile, int RAM);

        public abstract Boolean WriteProfile(Profile Profile, int RAM, ref System.ComponentModel.BackgroundWorker bgw);

        public abstract Boolean Start();

        public abstract Boolean Stop();

        public abstract Boolean IsFinished();

        public abstract Boolean HasAlarm(out List<Alarm> _Alarms);


        
        /// <summary>
        /// Checks if the given profile can run stand alone or if connection is required during running
        /// </summary>
        public abstract Boolean IsProgrammable(Profile profile);


        /// <summary>
        /// Checks if the client is executing a profile
        /// </summary>
        public abstract Boolean IsIdle();


        /// <summary>
        /// Checks the connection by sending and receiving a simple command
        /// </summary>
        public abstract Boolean IsOnline();



        /// <summary>
        /// Checks if given option is available for programming in this client
        /// </summary>
        public Boolean IsAvailable(ProfileOption Option)
        {
            return _ClientOptions.Contains(Option);
        }


        public override string ToString() { return string.Format("{0:00000} {1}", _MIDS, _Type.ToStr()); }

        
        /// <summary>
        /// Gives a string containing info on progress
        /// </summary>
        public abstract String Progress();
    }


   



}
