// Finish making the getmessageID function
        public String getMessageId(String message, int fieldNum)
        {
            Message t = new Message(message);
            String tempString = t.getElement("MSH", fieldNum);

            return tempString;
        }
        // This method is used to send a message to the server
        public  bool Send(string cmdstring, Queue queue)
        {
            cmdstring = HL7.CreateMLLPMessage(cmdstring);
            exceptionthrown = false;
            //var parameters = os_util.ParseParams(cmdstring);

            Message m = new Message(cmdstring);
            if (m.getElement("MSH", 8).ToUpper().ToString() == "ACK")
                return true;

            if (cmdstring.Length > 0)
            {
                try
                {
                    // We need a connection to the server to send a message
                    if (connectionsocket.Connected)
                    {

                        byte[] byData = System.Text.Encoding.ASCII.GetBytes(cmdstring);

                        try
                        {
                            connectionsocket.Send(byData);
                            queue.Sent = true;
                            _repository.SaveChangesQueue(queue);
                        }
                        catch (Exception ex)
                        {
                            ErrorHandler._ErrorHandler.LogError(ex, "Error sending", this);
                            connected = connectionsocket.Connected ? true : false ;
                            Connect(Settings._instance.RemoteIPAddress, Convert.ToInt32(Settings._instance.RemotePort));

                        }
                       
                        try
                        {

                           //ProcessSyncRecieve();
                           var item1 = socketpool.Pop();
                            item1.UserToken = new OSUserToken(this.connectionsocket,
                        Convert.ToInt32(Settings._instance.BufferSize), this._repository);

                           bool IOPending = connectionsocket.ReceiveAsync(item1);
                           // comment this for faster reads
                           if (!IOPending)
                           {
                               ProcessReceive(item);
                           }


                        }
                        catch (Exception ex)
                        {
                                
                              ErrorHandler._ErrorHandler.LogError(ex, "Did not recieve a message after 3 seconds");  
                        }
                        return true;
                    }
                    else
                    {
                        connected = false;
                        Connect(Settings._instance.RemoteIPAddress, Convert.ToInt32(Settings._instance.RemotePort));
                        return false;

                    }
                }
                catch (Exception ex)
                {
                    ErrorHandler._ErrorHandler.LogError(ex, "Error sending", this);
                    lasterror = ex.ToString();
                    return false;
                }
            }
            else
            {
                lasterror = "No message provided for Send.";
               ErrorHandler._ErrorHandler.LogInfo(lasterror);
                
                return false;
            }
        }
        public void SendMessages()
        {

            foreach (var message in Directory.GetFiles(Settings._instance.OutFolderPath,"*.txt"))
            {

                Queue queue = new Queue();
                try
                {
                    using (FileStream f = new FileStream(message, FileMode.Open, FileAccess.ReadWrite))
                    {
                        using (StreamReader newMsg = new StreamReader(f))
                        {
                            String msg = "";

                             msg = newMsg.ReadToEnd();
                            Message msgMessage = new Message(msg);

                            if (msgMessage.getElement("MSH", 8) == "ACK")
                            {
                                queue.Sent = true;
                                queue.Garbage = true;
                               // _repository.SaveChangesQueue(queue);
                               

                            }
                            else
                            {

                              //  _repository.CreateMhistory(msg);

                               // queue = _repository.CreateQueueRecord(msg);

                                if (Send(msg, queue))
                                {
                                    //queue = _repository.GetQueue(queue.ID);

                                    //queue.Sent = true;
                                    //_repository.SaveChangesQueue(queue);

                                }
                            }
                        }

                      
                    }
                    if (File.Exists(message))
                    {
                        if (queue.Sent == true)
                            File.Delete(message);
                    }
                }
                catch (Exception ex)
                {
                    ErrorHandler._ErrorHandler.LogError( ex, "- Problem sending message - "+ message);
                    
                }
                
            }

        }
        public void ProcessClientData(String ackMessage)
        {


            // build the end of message string below to check recieved against it
            string content2 = new String((char) HL7.MLLP_FIRST_END_CHARACTER, 1);
            content2 = content2 + new String((char) HL7.MLLP_LAST_END_CHARACTER, 1);

            // get the message up to the eof characters
            // and remove the message from the string builder
            if (ackMessage.IndexOf(content2) > -1)
            {
                if (ackMessage.IndexOf(content2) == 0)
                {

                    ErrorHandler._ErrorHandler.LogInfo(
                        "Should not be here means message recieved did not have start and end MLLP characters ");
                }
                else
                {
                    int temp2 = ackMessage.IndexOf(content2);
                    ackMessage = ackMessage.Substring(1, temp2);
                    _repository.CreateMhistory(ackMessage);
                    Message m = new Message(ackMessage);
                    String messageID = m.getElement("MSH", 9);
                    _repository.CreateAckRecord(ackMessage);
                    _repository.ProcessQueue(messageID);

                }

            }
        }
        // Do something with the received data, then reset the token for use by another connection.
        // This is called when all of the data has been received for a read socket.
        public void ProcessData(SocketAsyncEventArgs args)
        {
            // Get the last message received from the client, which has been stored in the stringbuilder.
            String received = stringbuilder.ToString();

            //TODO Use message received to perform a specific operation.

            string content2 = new String((char)HL7.MLLP_FIRST_END_CHARACTER, 1);
            content2 = content2 + new String((char)HL7.MLLP_LAST_END_CHARACTER, 1);

           // Settings settings = new Settings();
            
            // get the message up to the eof characters
            // and remove the message from the string builder
            if (received.IndexOf(content2) > -1)
            {
                if (received.IndexOf(content2) == 0)
                {

                    totalbytecount = 0;
                    stringbuilder.Length = 0;
                   // Console.WriteLine("HERE CLEARING THINGS OUT");
                }
                else
                {

                    //int temp = received.IndexOf(content2);
                    int temp2 = received.IndexOf(content2);
                    totalbytecount = totalbytecount - received.Length;
                    received = received.Substring(1, temp2); 

                    stringbuilder.Remove(0, temp2);
                    totalbytecount = 0;
                    stringbuilder.Length = 0;
                   // Console.WriteLine("Received: \"{0}\". The server has read {1} bytes. {2} buffer {3}", received,received.Length, temp2, stringbuilder.Capacity);
                    _repository.CreateMhistory(received);

                    Message m = new Message(received);
                    //TODO: Load up a send buffer to send an ack back to the calling client
                    //TODO: Change the ack type based on errors or not.
                    AckMessages ack = new AckMessages(received, _repository);
                    
                    

                    if (!string.IsNullOrWhiteSpace(Settings._instance.OutFolderPath))
                    {
                        if (!string.IsNullOrEmpty(ack.getMessageId()))
                        {
                            String path = Path.Combine(Settings._instance.OutFolderPath, ack.getMessageId());

                            if (File.Exists(path))
                            {
                                bool b = true;
                                int i = 0;
                                do
                                {
                                    i++;
                                    path = Path.Combine(Settings._instance.OutFolderPath,
                                        string.Format(ack.getMessageId() + "-{0}{1}", i, ".txt"));
                                    if (!File.Exists(path))
                                    {
                                        b = false;
                                    }

                                } while (b);

                            }

                            using (
                                var fs = new FileStream(path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None,
                                    4096,
                                    FileOptions.None))
                            {
                                fs.Write(Encoding.ASCII.GetBytes(received), 0, Encoding.ASCII.GetByteCount(received));
                            }
                           
                            Byte[] sendBuffer = Encoding.ASCII.GetBytes(ack.ack);
                            args.SetBuffer(sendBuffer, 0, sendBuffer.Length);
                            OwnerSocket.Send(args.Buffer);
                            _repository.CreateMhistory(ack.ack);
                            
                        }
                    }
                    else
                    {
                        _repository.CreateQueueRecord(received);
                        ErrorHandler._ErrorHandler.LogInfo("There is an error creating the file: "+ received);                       

                    }
                }
              }
        }
        public void  ProcessClientData(SocketAsyncEventArgs args)
        {
            // Get the last message received from the client, which has been stored in the stringbuilder.
            String received = stringbuilder.ToString();

            //TODO Use message received to perform a specific operation.

            // build the end of message string below to check recieved against it
            string content2 = new String((char)HL7.MLLP_FIRST_END_CHARACTER, 1);
            content2 = content2 + new String((char)HL7.MLLP_LAST_END_CHARACTER, 1);

            // get the message up to the eof characters
            // and remove the message from the string builder
            if (received.IndexOf(content2) > -1)
            {
                if (received.IndexOf(content2) == 0)
                {

                    totalbytecount = 0;
                    stringbuilder.Length = 0;
                    //Console.WriteLine("HERE CLEARING THINGS OUT");
                 // ErrorHandler._ErrorHandler.LogInfo("Cleaning out buffer client data ");
                }
                else
                {
                    //int temp = received.IndexOf(content2);
                    int temp2 = received.IndexOf(content2);
                    totalbytecount = totalbytecount - received.Length;
                    received = received.Substring(1, temp2);
                   //  _repository.CreateMhistory(received);
                    
                    stringbuilder.Remove(0, temp2);
                    totalbytecount = 0;
                    stringbuilder.Length = 0;
                    
                   // Console.WriteLine("Received: \"{0}\". The server has read {1} bytes. {2}", received, received.Length, temp2);

                    Message m = new Message(received);
                    String messageID = m.getElement("MSH", 9);
                    
                     //   _repository.CreateAckRecord(received);
                   // _repository.ProcessQueue(messageID);

                   // AckMessages ack = new AckMessages(received, _repository);
                    //Console.WriteLine(ack.ack);
                    //Byte[] sendBuffer = Encoding.ASCII.GetBytes(ack.ack);
                    //args.SetBuffer(sendBuffer, 0, sendBuffer.Length);
                    //OwnerSocket.Send(args.Buffer);

                }
                
            }

            // All the data has been read from the 
            // client. Display it on the console.
            //Console.WriteLine("Read {0} bytes from socket. \n Data : {1}",
            //    content.Length, content);
            // Echo the ACk message here async or in the caller
            //Send(handler, content);

            //TODO: Load up a send buffer to send an ack back to the calling client

            //

            // Clear StringBuffer, so it can receive more data from the client.


        }
        public void CreateAckRecord(String m)
        {
            //  _magDb.Registries.      //Add(registry);
            try
            {
                var message = new Message(m);

                AckMessRecieved ackMess = new AckMessRecieved();
                ackMess.Message = m;
                ackMess.MessageID = message.getElement("MSH", 9);
                ackMess.SentDateTime = System.DateTime.Now;
                var _magDb = new MagLink_engineEntities();
                _magDb.Entry(ackMess).State = ackMess.ID == 0 ? EntityState.Added : EntityState.Modified;
                _magDb.SaveChanges();
            }
            catch (Exception ex)
            {
                ErrorHandler._ErrorHandler.LogError(ex, "Error saving changes to ackMessages Received");
            }

        }
        public Queue CreateQueueRecord(String message)
        {
            Queue queue = new Queue();

            try
            {
                queue.SentDateTime = System.DateTime.Now;
                queue.Message = message;
                Message m = new Message(message);
                queue.MessageID = m.getElement("MSH", 9);
                queue.Garbage = false;
                queue.Sent = false;
                queue.PatientMRN = m.getElement("PID", 3);

                //using (_magDb)
                //{
                   var _magDb = new MagLink_engineEntities();
                    _magDb.Queues.Add(queue);
                    _magDb.SaveChanges();
   
                //}
            }
            catch (Exception ex)
            {
                ErrorHandler._ErrorHandler.LogError(ex, "Error making queue record in table");                    
            }

            return queue;

        }
        public void CreateMhistory(String message)
        {
            try
            {
                Message_History history = new Message_History();
                history.DateTime = System.DateTime.Now;
                history.Message = message;
                Message m = new Message(message);
                history.PatID = m.getElement("PID", 3);
                history.PatName = m.getElement("PID", 5);
                history.messageid = m.getElement("MSH", 9);

                //using (_magDb)
                //{
              var      _magDb = new MagLink_engineEntities();
                    _magDb.Message_History.Add(history);
                    _magDb.SaveChanges();
                  //  _magDb.Dispose();
                //}
            }
            catch (Exception ex)
            {
                    ErrorHandler._ErrorHandler.LogError(ex, "Error entering data in the message history table");

            }
            
        }