using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


using Maser.Feanor.Model;
using System.Data.SqlClient;



namespace Maser.Feanor.Biz
{

    public class Sensors
    {

        public List<Sensor> GetActiveByChamber(Int32 chamberPK)
        {
            string query = string.Format("Select * from Sensors where Enabled = 1 and ChamberPK = {0:0} order by ID", chamberPK);
            try
            {
                return GetListByQuery(query);
            }
            catch (Exception e)
            {
                throw e;
            }
        }


        public bool Equal(Sensor A, Sensor B)
        {
            // Compare properties that can be changed by user
            if (A.Description != B.Description)
                return false;

            if (A.Enabled != B.Enabled)
                return false;


            if (A.ApplyCalibration != B.ApplyCalibration)
                return false;

            return true;

        }


        public List<Sensor> GetByChamber(int chamberPK)
        {
            string query = string.Format("Select * from Sensors where ChamberPK = {0:0} order by ID asc", chamberPK);
            try
            {
                return GetListByQuery(query);
            }
            catch (Exception e)
            {
                throw e;
            }
        }


        public Sensor GetByPK(Int32 PK)
        {
            string query = String.Format("Select * from Sensors where PK = {0}", PK);
            try
            {
                return GetByQuery(query);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public Sensor GetByID(Int32 ID, Int32 ChamberPK)
        {
            string query = String.Format("Select * from Sensors where ID = {0} AND ChamberPK = {1}", ID, ChamberPK);
            try
            {
                return GetByQuery(query);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public List<Sensor> GetAllActive()
        {
            string query = "Select * from Sensors where Enabled = 1";
            try
            {
                return GetListByQuery(query);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public List<Sensor> GetAll()
        {
            string query = "Select * from Sensors";
            try
            {
                return GetListByQuery(query);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public Boolean Delete(Sensor sensor)
        {
            try
            {
                sensor.Enabled = false;
                return Modify(sensor);
            }
            catch (Exception e)
            {
                throw e;
            }
        }

        public bool Exists(Sensor sensor)
        {
            try
            {
                return (GetByPK(sensor.PK) != null);
            }
            catch (Exception e)
            {
                throw e;
            }
        }
        
        public bool Modify(Sensor sensor)
        {
            try
            {
                if (!Exists(sensor))
                    return false;
            }
            catch (Exception e)
            {
                throw e;
            }

            string query = String.Format("UPDATE Sensors SET ID='{0}', ChamberPK='{1}', Description='{2}', Type='{3}', Enabled='{4}', ApplyCalibration='{5}' WHERE PK={6};", sensor.ID,sensor.ChamberPK,sensor.Description,(int)sensor.Type,sensor.Enabled,sensor.ApplyCalibration,sensor.PK);
            try
            {
                SqlConnection myConnection = new SqlConnection(Properties.Settings.Default.FeanorConnStr);
                myConnection.Open();
                SqlCommand myCommand = new SqlCommand(query, myConnection);
                myCommand.ExecuteNonQuery();
                return true;
            }
            catch (Exception e)
            {               
                throw e;
            }
            
        }

        public Int32 Add(Sensor sensor)
        {
            string query = String.Format("INSERT INTO Sensors (ID, ChamberPK, Description, Type, Enabled, ApplyCalibration) VALUES ('{0}', '{1}', '{2}', '{3}', '{4}', '{5}');", sensor.ID,  sensor.ChamberPK, sensor.Description, (int)sensor.Type, sensor.Enabled, sensor.ApplyCalibration);
            query += "SELECT SCOPE_IDENTITY();";

            SqlConnection myConnection = new SqlConnection(Properties.Settings.Default.FeanorConnStr);
            myConnection.Open();
            try
            {
                SqlCommand myCommand = new SqlCommand(query, myConnection);
                return Int32.Parse(myCommand.ExecuteScalar().ToString());
            }
            catch (Exception e)
            {
                
                throw e;
            }
            finally
            {
                myConnection.Close();
            }
        }

        private Sensor GetByQuery(string query)
        {
            Sensor result = null;
            SqlConnection myConnection = new SqlConnection(Properties.Settings.Default.FeanorConnStr);
            SqlDataReader myReader = null;
            try
            {
                myConnection.Open();

                SqlCommand myCommand = new SqlCommand(query, myConnection);
                myReader = myCommand.ExecuteReader();
                if (myReader.HasRows)
                {
                    myReader.Read();
                    result = new Sensor(myReader.GetInt32(0), myReader.GetInt32(1), myReader.GetInt32(2), myReader.GetString(3), (SensorType)myReader.GetInt32(4), myReader.GetBoolean(5), myReader.GetBoolean(6));
                }

                if (myReader != null)
                {
                    myReader.Close();
                }
            }
            catch (Exception e)
            {
                
                throw e;
               
            }
            finally
            {
                myConnection.Close(); // Martijn
                /* 
                https://msdn.microsoft.com/en-us/library/haa3afyz(v=vs.110).aspx
                Do not call Close or Dispose on a Connection, a DataReader, or any other managed object in the Finalize method of your class. 
                In a finalizer, only release unmanaged resources that your class owns directly. 
                If your class does not own any unmanaged resources, do not include a Finalize method in your class definition. 
                For more information, see Garbage Collection.
                */
            }
            return result;
        }

        private List<Sensor> GetListByQuery(string query)
        {
            List<Sensor> result = new List<Sensor>();
            SqlConnection myConnection = new SqlConnection(Properties.Settings.Default.FeanorConnStr);

            SqlDataReader myReader = null;
            try
            {
                myConnection.Open();

                SqlCommand myCommand = new SqlCommand(query, myConnection);
                myReader = myCommand.ExecuteReader();
                if (myReader.HasRows)
                {
                    while (myReader.Read())
                    {
                        result.Add(new Sensor(myReader.GetInt32(0), myReader.GetInt32(1), myReader.GetInt32(2), myReader.GetString(3), (SensorType)myReader.GetInt32(4), myReader.GetBoolean(5), myReader.GetBoolean(6)));
                    }
                }
            }
            catch (Exception e)
            {
               
                throw e;
            }
            finally
            {
                if (myReader != null)
                myReader.Close();
                myConnection.Close(); // Martijn

                /* 
                https://msdn.microsoft.com/en-us/library/haa3afyz(v=vs.110).aspx
                Do not call Close or Dispose on a Connection, a DataReader, or any other managed object in the Finalize method of your class. 
                In a finalizer, only release unmanaged resources that your class owns directly. 
                If your class does not own any unmanaged resources, do not include a Finalize method in your class definition. 
                For more information, see Garbage Collection.
                */
            }
            return result;
        }


        
    }


}
