private void enviarFinSyncJob(string HHID, StateObject e)
        {
            int chunkSize = FIXED_HEADER_LENGTH;

            string header = "TYPE:FINSYNC";
            // Nuevo: Encriptado de datos.
            string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
            headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;

            string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);
            byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

            byte[] dataToSend = new byte[finalHeader.Length];

            System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);

            JobToSendToClient j = new JobToSendToClient();

            jobCounter++;
            j.ID = jobCounter;
            j.header = headerEncriptado;
            j.byteData = dataToSend;

            e.pendingJobs.Enqueue(j);     // Nuevo: un pendingjobs por cada cliente.
            e.readyToSend.Set();            // Activar envio

            loguearString(HHID + "- TRABAJO FINSYNC", TiposLOG.LENEL);
        }
        private void EnviarJobBloqueImagenes(string HHID, string dataLength, byte[] dataBytes, byteArrayEventArgs e)
        {
            // Espero señal para enviar imagenes
            if (!e.stateObject.masImagenes) EsperaProximoPedidoImagenes(e.stateObject);

            if (!e.stateObject.abortFlag)
            {
                try
                {
                    dataLength = dataLength.Trim(',');  // Quito la última coma

                    // Armo el trabajo a enviar si el HH está conectado
                    if (mainApp.ComunicationSystem.communicationLAYER.isPannelConnected(HHID))
                    {
                        dataLength = Encriptar_Datos.Encriptar.encriptar(dataLength, communicationSystem.ClaveEncriptar);
                        byte[] dataLengthBytes = Encoding.ASCII.GetBytes(dataLength);

                        int chunkSize = FIXED_HEADER_LENGTH + dataLengthBytes.Length + dataBytes.Length;

                        string header = "TYPE:IMGLIST,SIZE:" + chunkSize.ToString() + ",IDLENGTH:" + dataLengthBytes.Length.ToString();

                        // Nuevo: Encriptado de datos.
                        string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
                        headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;

                        string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);
                        byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

                        byte[] dataToSend = new byte[finalHeader.Length + dataLengthBytes.Length + dataBytes.Length];
                        System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);
                        System.Buffer.BlockCopy(dataLengthBytes, 0, dataToSend, headerBytedata.Length, dataLengthBytes.Length);
                        System.Buffer.BlockCopy(dataBytes, 0, dataToSend, headerBytedata.Length + dataLengthBytes.Length, dataBytes.Length);

                        JobToSendToClient j = new JobToSendToClient();

                        jobCounter++;
                        j.ID = jobCounter;
                        j.header = headerEncriptado;
                        j.byteData = dataToSend;

                        e.stateObject.pendingJobs.Enqueue(j);     // Nuevo: un pendingjobs por cada cliente.
                        e.stateObject.readyToSend.Set();
                        loguearString(HHID + "- ENVIADO TRABAJO Bloque de imágenes, largo: " + chunkSize.ToString(), TiposLOG.HH);
                    }
                }

                catch (Exception ex) { loguearString("Problema en EnviarJobBloqueImagenes: " + ex.Message, TiposLOG.HH); }
            }
        }
        private void enviarBloqueEmpleados(string dataEmp, string HHID, StateObject clientState)
        {
            try
            {

                //dataEmp = dataEmp.Trim('|');    // Saco último '|'

                // Armo el trabajo a enviar si el HH está conectado
                if (mainApp.ComunicationSystem.communicationLAYER.isPannelConnected(HHID))
                {

                    string dataStringEncriptado = dataEmp;//Encriptar_Datos.Encriptar.encriptar(dataEmp, communicationSystem.ClaveEncriptar);
                    byte[] dataBytes = Encoding.ASCII.GetBytes(dataStringEncriptado);

                    int chunkSize = FIXED_HEADER_LENGTH + dataBytes.Length;
                    //TYPE:EMPLISTXVER,SIZE:(.*)
                    string header = "TYPE:EMPLISTXVER,SIZE:" + chunkSize.ToString();

                    // Nuevo: Encriptado de datos.
                    string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
                    headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;

                    string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);
                    byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

                    byte[] dataToSend = new byte[finalHeader.Length + dataBytes.Length];
                    System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);
                    System.Buffer.BlockCopy(dataBytes, 0, dataToSend, headerBytedata.Length, dataBytes.Length);

                    JobToSendToClient j = new JobToSendToClient();

                    jobCounter++;
                    j.ID = jobCounter;
                    j.header = headerEncriptado;
                    j.byteData = dataToSend;

                    clientState.pendingJobs.Enqueue(j);     // Nuevo: un pendingjobs por cada cliente.
                    clientState.readyToSend.Set();
                    loguearString(HHID + "- TRABAJO Bloque de empleados por versión", TiposLOG.HH);
                }
            }
            catch (Exception ex) { loguearString("Excepción en enviarBloqueEmpleados: " + ex.Message, TiposLOG.HH); }
        }
        void enviarDummy(object sender, stringEventArgs e)
        {
            int chunkSize = FIXED_HEADER_LENGTH;
            string header = "TYPE:DUMMY";

            // Nuevo: Encriptado de datos.
            string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
            headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;
            string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);

            byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

            byte[] dataToSend = new byte[finalHeader.Length];
            System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);

            JobToSendToClient j = new JobToSendToClient();

            jobCounter++;
            j.ID = jobCounter;
            j.header = headerEncriptado;                // Usa el encriptado.
            j.byteData = dataToSend;

            // Nuevo: un pendingJobs por cada stateobject de cada cliente.
            e.stateObject.pendingJobs.Enqueue(j);
            e.stateObject.readyToSend.Set();
        }
        /// <summary>
        /// Evento lanzado por el socket que agrega un JOB de enviar una Imagen a la cola de pendingJobs.
        /// En el parametro TARJETA viene el numero de tarjeta cuya imagen hay que enviar.
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="v_eventArgs"></param>
        void addSendImageJob(object sender, stringEventArgs v_eventArgs)
        {
            try
            {
                string tarjeta = v_eventArgs.textData["TARJETA"];         // La tarjeta cuya imagen hay que enviar

                int idEmp = mainApp.DataManager.buscarEmpleadoxTarjeta(tarjeta).Id;

                Dictionary<int, Employee> listaEmpleados = mainApp.DataManager.getListaEmpleados();

                if (listaEmpleados.ContainsKey(idEmp))
                {
                    if (listaEmpleados[idEmp].hasImage())
                    {
                        byte[] imageBytes = listaEmpleados[idEmp].getImage();
                        int chunkSize = FIXED_HEADER_LENGTH + imageBytes.Length;
                        int imageVersion = listaEmpleados[idEmp].imageVersion;

                        //string header = "TYPE:IMAGE,SIZE:" + chunkSize.ToString() + ",TARJETA:" + tarjeta + ",IMGVER:" + imageVersion.ToString().Trim();
                        string header = "TYPE:IMAGE,SIZE:" + chunkSize.ToString() + ",TARJETA:" + tarjeta + ",IMGVER:" + imageVersion.ToString().Trim() + ",PERSONID:" +listaEmpleados[idEmp].PersonID;

                        // Nuevo: Encriptado de datos.
                        string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
                        headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;

                        string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);
                        byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

                        byte[] dataToSend = new byte[finalHeader.Length + imageBytes.Length];
                        System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);
                        System.Buffer.BlockCopy(imageBytes, 0, dataToSend, headerBytedata.Length, imageBytes.Length);

                        JobToSendToClient j = new JobToSendToClient();

                        jobCounter++;
                        j.ID = jobCounter;
                        j.header = headerEncriptado;
                        j.byteData = dataToSend;

                        v_eventArgs.stateObject.pendingJobs.Enqueue(j);     // Nuevo: un pendingjobs por cada cliente.
                        v_eventArgs.stateObject.readyToSend.Set();
                        loguearString(v_eventArgs.stateObject.HHID + "- TRABAJO SEND IMAGE: " + header, TiposLOG.HH);

                    }
                    else loguearString("No hay imagen asociada a la tarjeta " + tarjeta, TiposLOG.HH);
                }
                else
                {
                    //lstStatus.Items.Add("ERROR: la tarjeta NO EXISTE");
                }
            }
            catch (Exception e) { loguearString("Excepcion enviando imagen: " + e.Message, TiposLOG.HH); }
        }
        void borrarEmp(object sender, stringEventArgs e)
        {
            try
            {
                string tarjeta = e.textData["TARJETA"];         // La tarjeta del empleado que se va a eliminar
                string id = e.textData["HHID"];

                // Solo encola el trabajo si se dispone efectivamente informacion sobre el HH
                if (mainApp.ComunicationSystem.communicationLAYER.isPannelConnected(id))
                {
                    int chunkSize = FIXED_HEADER_LENGTH;

                    string header = "TYPE:DELEMP,SIZE:" + chunkSize.ToString() + ",BADGE:" + tarjeta;

                    // Nuevo: Encriptado de datos.
                    string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
                    headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;

                    string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);
                    byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

                    byte[] dataToSend = new byte[finalHeader.Length];
                    System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);

                    JobToSendToClient j = new JobToSendToClient();

                    jobCounter++;
                    j.ID = jobCounter;
                    j.header = headerEncriptado;
                    j.byteData = dataToSend;

                    e.stateObject.pendingJobs.Enqueue(j);     // Nuevo: un pendingjobs por cada cliente.
                    e.stateObject.readyToSend.Set();
                    loguearString(e.stateObject.HHID + "- TRABAJO Borrar empleado: " + header, TiposLOG.HH);
                }
            }
            catch (Exception ex) { loguearString("Excepción borrando empleado: " + ex.Message, TiposLOG.HH); }
        }
        // Envia el trabajo ALLPERSONID al HH para indicarle los personID validos en funcion de los actuales AccessLevels
        public void enviarAllPersonIDJob(string HHID, StateObject e)
        {
            string allPersonID = mainApp.DataManager.loadAllPersonID(HHID); // Carga los PersonID con los IDs de las personas que pertenecen al HHID

            string allPersonIDEnc = Encriptar_Datos.Encriptar.encriptar(allPersonID, communicationSystem.ClaveEncriptar);
            byte[] dataBytes = Encoding.ASCII.GetBytes(allPersonIDEnc);

            int chunkSize = FIXED_HEADER_LENGTH + dataBytes.Length;

            string header = "TYPE:ALLPERSONID,SIZE:" + chunkSize.ToString();

            // Nuevo: Encriptado de datos.
            string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
            headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;

            string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);
            byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

            byte[] dataToSend = new byte[finalHeader.Length + dataBytes.Length];
            System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);
            System.Buffer.BlockCopy(dataBytes, 0, dataToSend, headerBytedata.Length, dataBytes.Length);

            JobToSendToClient j = new JobToSendToClient();

            jobCounter++;
            j.ID = jobCounter;
            j.header = headerEncriptado;
            j.byteData = dataToSend;

            e.pendingJobs.Enqueue(j);     // Nuevo: un pendingjobs por cada cliente.
            e.readyToSend.Set();

            int cantEnviados = 0;
            if (allPersonID.Trim().Length > 0)
            {
                cantEnviados=allPersonID.Split(',').Length;
            }
            loguearString(HHID + "- TRABAJO ALLPERSONID. Cant de PersonIDs enviados:" + cantEnviados.ToString(), TiposLOG.LENEL);
        }
        private void addConfirmVisitJob(byteArrayEventArgs e)
        {
            int chunkSize = FIXED_HEADER_LENGTH;
            string header = "TYPE:CONFIRMVISIT,SIZE:" + chunkSize.ToString() + ",ID:" + e.textData["ID"];

            // Nuevo: Encriptado de datos.
            string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
            headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;

            string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);
            byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

            byte[] dataToSend = new byte[finalHeader.Length];
            System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);

            JobToSendToClient j = new JobToSendToClient();

            jobCounter++;
            j.ID = jobCounter;
            j.header = headerEncriptado;
            j.byteData = dataToSend;

            e.stateObject.pendingJobs.Enqueue(j);     // Nuevo: un pendingjobs por cada cliente.
            e.stateObject.readyToSend.Set();
            loguearString(e.stateObject.HHID + "- Agregado trabajo de CONFIRMACION de VISITA con ID: " + e.textData["ID"], TiposLOG.HH);
        }
        //void addBeginEmpListJob(object sender, stringEventArgs v_eventArgs)
        //{
        //    string header = "TYPE:BEGINEMPLIST";
        //    // Nuevo: Encriptado de datos.
        //    string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
        //    headerEncriptado = "SIZE:"+FIXED_HEADER_LENGTH.ToString() + ",DATA:" + headerEncriptado;
        //    string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);
        //    byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);
        //    byte[] dataToSend = new byte[finalHeader.Length];
        //    System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);
        //    //System.Buffer.BlockCopy(dataBytes, 0, dataToSend, headerBytedata.Length, dataBytes.Length);
        //    JobToSendToClient j = new JobToSendToClient();
        //    jobCounter++;
        //    j.ID = jobCounter;
        //    j.header = headerEncriptado;                // Usa el encriptado.
        //    j.byteData = dataToSend;
        //    // Nuevo: un pendingJobs por cada stateobject de cada cliente.
        //    v_eventArgs.stateObject.pendingJobs.Enqueue(j);
        //    v_eventArgs.stateObject.readyToSend.Set();        // Le aviso al semaforo que hay cosas encoladas para mandar.
        //    loguearString(v_eventArgs.stateObject.HHID + "- TRABAJO BEGINEMPLIST", TiposLOG.ALUTRACK);
        //}
        // Envia el mensaje de fin del envio de los bloques de empleadosXVersion
        //void addEndEmpListJob(StateObject clientState)
        //{
        //    string header = "TYPE:ENDEMPLIST";
        //    // Nuevo: Encriptado de datos.
        //    string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
        //    headerEncriptado = "SIZE:"+FIXED_HEADER_LENGTH.ToString() + ",DATA:" + headerEncriptado;
        //    string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);
        //    byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);
        //    byte[] dataToSend = new byte[finalHeader.Length];
        //    System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);
        //    //System.Buffer.BlockCopy(dataBytes, 0, dataToSend, headerBytedata.Length, dataBytes.Length);
        //    JobToSendToClient j = new JobToSendToClient();
        //    jobCounter++;
        //    j.ID = jobCounter;
        //    j.header = headerEncriptado;                // Usa el encriptado.
        //    j.byteData = dataToSend;
        //    // Nuevo: un pendingJobs por cada stateobject de cada cliente.
        //    clientState.pendingJobs.Enqueue(j);
        //    clientState.readyToSend.Set();        // Le aviso al semaforo que hay cosas encoladas para mandar.
        //    loguearString(clientState.HHID + "- TRABAJO ENDEMPLIST", TiposLOG.ALUTRACK);
        //}
        public void agregarTrabajoListaEmpleadosEspecifica(StateObject ClienteHH, string v_personIDs)
        {
            string personIDs ="'"+ v_personIDs+",";         // Para poder encontrar con contains

            string dataString = "";
            Dictionary<int, Employee> listaEmpleados = mainApp.DataManager.getListaEmpleados();

            try
            {
                StaticTools.obtenerMutex_ListaEmpleados();

                foreach (KeyValuePair<int, Employee> emp in listaEmpleados)
                {
                    if (personIDs.Contains(","+emp.Value.PersonID.ToString()))
                    {
                         dataString += emp.Value.PersonID.ToString() + "," + emp.Value.VersionEmpleado.ToString() + "|";
                    }
                }
            }
            catch (Exception ex)
            {
                loguearString("Excepcion en agregarTrabajoListaEmpleadosEspecifica: " + ex.Message, TiposLOG.LENEL);
            }
            finally
            {
                StaticTools.liberarMutex_ListaEmpleados();
            }

            if (dataString.Length > 0)
                    dataString = dataString.Substring(0, dataString.Length - 1);    // Le saco el | de más al final

            // Solo encola el trabajo si se dispone efectivamente informacion sobre el HH y no esta en proceso de abort...
            if (mainApp.ComunicationSystem.communicationLAYER.isPannelConnected(ClienteHH.HHID) && !ClienteHH.abortFlag)
                {
                    string dataStringEncriptado = Encriptar_Datos.Encriptar.encriptar(dataString, communicationSystem.ClaveEncriptar);
                    byte[] dataBytes = Encoding.ASCII.GetBytes(dataStringEncriptado);

                    int chunkSize = FIXED_HEADER_LENGTH + dataBytes.Length;
                    string header = "TYPE:EMPLIST,SIZE:" + chunkSize.ToString();

                    // Nuevo: Encriptado de datos.
                    string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
                    headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;
                    string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);

                    byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

                    byte[] dataToSend = new byte[finalHeader.Length + dataBytes.Length];
                    System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);
                    System.Buffer.BlockCopy(dataBytes, 0, dataToSend, headerBytedata.Length, dataBytes.Length);

                    JobToSendToClient j = new JobToSendToClient();

                    jobCounter++;
                    j.ID = jobCounter;
                    j.header = headerEncriptado;                // Usa el encriptado.
                    j.byteData = dataToSend;

                    // Nuevo: un pendingJobs por cada stateobject de cada cliente.
                    ClienteHH.pendingJobs.Enqueue(j);
                    ClienteHH.readyToSend.Set();        // Le aviso al semaforo que hay cosas encoladas para mandar.

                    loguearString(ClienteHH.HHID + "- Encolado TRABAJO EMPLIST", TiposLOG.LENEL);
                    loguearString(ClienteHH.HHID + "- Cantidad de trabajos: " + ClienteHH.pendingJobs.Count.ToString(), TiposLOG.HH);

                   // int orgID = mainApp.DataManager.obtenerOrganizationIDFromHHID(ClienteHH.HHID);

                    //layerLENEL.enviarAccessLevelsDefinitions(v_eventArgs.stateObject.HHID, orgID);

                }
                else
                {
                    loguearString(ClienteHH.HHID + "- no conectado. NO SE AGREGA EL TRABAJO " + dataString, TiposLOG.HH);
                }
        }
        /// <summary>
        /// Agrega a la cola de trabajos el trabajo de enviar la lista completa de versiones de empleados
        /// BETA: Todos son ADMIN: true y todos tienen Password: alutel
        /// NUEVO: EMPLIST envia ahora SOLAMENTE la lista de versiones de empleados, para que el HH pida solamente los que le faltan
        /// </summary>
        /// <param name="v_eventArgs"></param>
        public void agregarTrabajoListaEmpleados(stringEventArgs v_eventArgs)
        {
            try
            {
                string dataString = "";
                Dictionary<int, Employee> listaEmpleados = mainApp.DataManager.getListaEmpleados();

                DateTime ultimaActualizacionHandHeld = mainApp.DataManager.obtenerUltimaFechaSync(v_eventArgs.stateObject.HHID);

                //MUTEX
                try
                {
                    StaticTools.obtenerMutex_ListaEmpleados();
                    loguearString("Entro a agregarTrabajoListaEmpleados(EMPLIST) con : " + listaEmpleados.Count.ToString(),TiposLOG.LENEL);

                    foreach (KeyValuePair<int, Employee> emp in listaEmpleados)
                    {
                        if (v_eventArgs.stateObject.abortFlag)
                        {
                            loguearString("Hizo ABORTFLAG=TRUE ",TiposLOG.LENEL);
                            break;
                        }
                        //if (i == 0) break;  // debug
                        //i--;    // debug
                        DateTime ultimaActualizacionEmpleado = emp.Value.ultimaActualizacion;

                        Tarjeta tarjeta = mainApp.DataManager.buscarTarjetadeEmpleado(emp.Value.Id);

                        // Solo se envia la info de un empleado si tiene tarjeta asociada y algun accesslevel asociado
                        if ((tarjeta != null))
                        {
                            string accessLevels =AccessLevelLogic.getAccessLevelsByBadgeInHH(tarjeta.NUMERODETARJETA, v_eventArgs.stateObject.HHID);
                            DateTime ultimaActualizacionTarjeta = tarjeta.ultimaActualizacion;
                            if (accessLevels.Trim().Length>0)
                            {
                                if ((ultimaActualizacionEmpleado > ultimaActualizacionHandHeld)||(ultimaActualizacionTarjeta > ultimaActualizacionHandHeld ))
                                {

                                    // Envío los empleados con sus versiones para que el hh pida los datos SOLO de aquellos que cambiaron
                                    dataString += emp.Value.PersonID.ToString() + "," + emp.Value.VersionEmpleado.ToString() + "|";

                                }
                            }
                        }
                    }

                   // loguearString("dataString: " + dataString,TiposLOG.LENEL);

                }
                catch (Exception ex)
                {
                    loguearString("Excepcion en agregarTrabajoListaEmpleados-MUTEX " + ex.Message, TiposLOG.HH);
                }
                finally
                {
                    //MUTEX
                    StaticTools.liberarMutex_ListaEmpleados();
                }

                if (dataString.Length > 0)
                    dataString = dataString.Substring(0, dataString.Length - 1);    // Le saco el | de más al final
                else
                {
                    EnviarJobFinSync(v_eventArgs.stateObject.HHID, v_eventArgs.stateObject);
                    return;
                }
                // Solo encola el trabajo si se dispone efectivamente informacion sobre el HH y no esta en proceso de abort...
                if (mainApp.ComunicationSystem.communicationLAYER.isPannelConnected(v_eventArgs.stateObject.HHID) && !v_eventArgs.stateObject.abortFlag)
                {
                    string dataStringEncriptado = Encriptar_Datos.Encriptar.encriptar(dataString, communicationSystem.ClaveEncriptar);
                    byte[] dataBytes = Encoding.ASCII.GetBytes(dataStringEncriptado);

                    int chunkSize = FIXED_HEADER_LENGTH + dataBytes.Length;
                    string header = "TYPE:EMPLIST,SIZE:" + chunkSize.ToString();

                    // Nuevo: Encriptado de datos.
                    string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
                    headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;
                    string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);

                    byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

                    byte[] dataToSend = new byte[finalHeader.Length + dataBytes.Length];
                    System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);
                    System.Buffer.BlockCopy(dataBytes, 0, dataToSend, headerBytedata.Length, dataBytes.Length);

                    JobToSendToClient j = new JobToSendToClient();

                    jobCounter++;
                    j.ID = jobCounter;
                    j.header = headerEncriptado;                // Usa el encriptado.
                    j.byteData = dataToSend;

                    // Nuevo: un pendingJobs por cada stateobject de cada cliente.
                    v_eventArgs.stateObject.pendingJobs.Enqueue(j);
                    v_eventArgs.stateObject.readyToSend.Set();        // Le aviso al semaforo que hay cosas encoladas para mandar.

                    loguearString(v_eventArgs.stateObject.HHID + "- Encolado TRABAJO EMPLIST", TiposLOG.LENEL);
                   // loguearString(v_eventArgs.stateObject.HHID + "- Cantidad de trabajos: " + v_eventArgs.stateObject.pendingJobs.Count.ToString(), TiposLOG.ALUTRACK);

                    int orgID = mainApp.DataManager.obtenerOrganizationIDFromHHID(v_eventArgs.stateObject.HHID);

                    //layerLENEL.enviarAccessLevelsDefinitions(v_eventArgs.stateObject.HHID, orgID);

                }
                else
                {
                    loguearString(v_eventArgs.stateObject.HHID + "- no conectado. NO SE AGREGA EL TRABAJO " + dataString, TiposLOG.HH);
                }
            }
            catch (Exception ex) { loguearString("Excepcion en agregarTrabajoListaEmpleados(): " + ex.Message, TiposLOG.HH); }
        }
        public void agregarTrabajoAccessLevel(StateObject v_stateobject, string v_accessLevel)
        {
            string dataStringEncriptado = Encriptar_Datos.Encriptar.encriptar(v_accessLevel, communicationSystem.ClaveEncriptar);
            byte[] dataBytes = Encoding.ASCII.GetBytes(dataStringEncriptado);

            int chunkSize = FIXED_HEADER_LENGTH + dataBytes.Length;

            string header = "ACCESSLVL:SIZE:" + chunkSize.ToString();
            // Nuevo: Encriptado de datos.
            string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
            headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;
            string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);

            byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

            byte[] dataToSend = new byte[finalHeader.Length + dataBytes.Length];
            System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);
            System.Buffer.BlockCopy(dataBytes, 0, dataToSend, headerBytedata.Length, dataBytes.Length);

            JobToSendToClient j = new JobToSendToClient();

            jobCounter++;
            j.ID = jobCounter;
            j.header = headerEncriptado;                // Usa el encriptado.
            j.byteData = dataToSend;

            v_stateobject.pendingJobs.Enqueue(j);
            v_stateobject.readyToSend.Set();        // Le aviso al semaforo que hay cosas encoladas para mandar.

            loguearString(v_stateobject.HHID + "-ACCESSLEVEL: " + v_accessLevel,TiposLOG.HH);
        }
        void ThreadEnviarVersionImagenes(stringEventArgs e)
        {
            StateObject clientState = e.stateObject;

            try
            {
                string dataString = "";
                Dictionary<int, Employee> listaEmpleados = mainApp.DataManager.getListaEmpleados();

                //int i = 50; // Para debug

                foreach (KeyValuePair<int, Employee> emp in listaEmpleados)
                {
                    if (clientState.abortFlag)
                    {
                        break;
                    }

                    //if (i == 0) break;  // debug
                    //i--;    // debug

                    // VERIFICO QUE EL EMPLEADO TENGA IMAGEN
                    string pathImagenDB = mainApp.DataManager.cargarPathImagen(emp.Value.PersonID.ToString());

                    if (HayImagen(pathImagenDB))
                    {
                        Tarjeta tarjeta = mainApp.DataManager.buscarTarjetadeEmpleado(emp.Value.Id);
                        // Solo se envia la info de un empleado si tiene tarjeta asociada y algun accesslevel asociado
                        if (tarjeta != null)
                        {
                            string accessLevels = AccessLevelLogic.getAccessLevelsByBadgeInHH(tarjeta.NUMERODETARJETA, e.stateObject.HHID);

                            if (accessLevels.Trim().Length > 0)
                            {
                                // Envío las versiones de las imagenes para que el hh pida los datos SOLO de aquellos que cambiaron
                                dataString += emp.Value.PersonID.ToString() + ":" + emp.Value.imageVersion.ToString() + ",";
                            }
                        }
                    }
                }

                if (dataString.Length > 0)   // Si ninguna de las tarjetas a enviar al HH tienen foto, terminar la secuencia enviando FinSYNC
                {
                    dataString = dataString.Substring(0, dataString.Length - 1);    // Le saco el | de más al final

                    // Solo encola el trabajo si se dispone efectivamente informacion sobre el HH
                    if (mainApp.ComunicationSystem.communicationLAYER.isPannelConnected(e.stateObject.HHID) && (!clientState.abortFlag))
                    {
                        string dataStringEncriptado = Encriptar_Datos.Encriptar.encriptar(dataString, communicationSystem.ClaveEncriptar);
                        byte[] dataBytes = Encoding.ASCII.GetBytes(dataStringEncriptado);

                        int chunkSize = FIXED_HEADER_LENGTH + dataBytes.Length;
                        string header = "TYPE:VERIMGLIST,SIZE:" + chunkSize.ToString();

                        // Nuevo: Encriptado de datos.
                        string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
                        headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;
                        string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);

                        byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

                        byte[] dataToSend = new byte[finalHeader.Length + dataBytes.Length];
                        System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);
                        System.Buffer.BlockCopy(dataBytes, 0, dataToSend, headerBytedata.Length, dataBytes.Length);

                        JobToSendToClient j = new JobToSendToClient();

                        jobCounter++;
                        j.ID = jobCounter;
                        j.header = headerEncriptado;                // Usa el encriptado.
                        j.byteData = dataToSend;

                        // Nuevo: un pendingJobs por cada stateobject de cada cliente.
                        e.stateObject.pendingJobs.Enqueue(j);
                        e.stateObject.readyToSend.Set();        // Le aviso al semaforo que hay cosas encoladas para mandar.

                        loguearString(e.stateObject.HHID + "- TRABAJO VERIMGLIST", TiposLOG.HH);
                        loguearString(e.stateObject.HHID + "- Cantidad de trabajos: " + e.stateObject.pendingJobs.Count.ToString(), TiposLOG.HH);

                    }
                    else
                    {
                        loguearString(e.stateObject.HHID + "- No conectado. NO SE AGREGA EL TRABAJO " + dataString, TiposLOG.HH);
                    }
                }
                else       // Si ninguna de las tarjetas a enviar al HH tienen foto, terminar la secuencia enviando FinSYNC
                {
                    EnviarJobFinSync(e.stateObject.HHID, e.stateObject);
                }
            }
            catch (Exception ex) { loguearString("Excepcion en ThreadEnviarVersionImagenes(): " + ex.Message, TiposLOG.HH); }
        }
        public void agregarEmp(object sender, stringEventArgs e)
        {
            try
            {
                string dataEmp = string.Empty;
                string isAdmin_BETA = "true";
                string passWord_BETA = "alutel";

                string tarjeta = e.textData["TARJETA"];         // La tarjeta del empleado que se va a agregar
                string id = e.textData["HHID"];

                Employee emp = mainApp.DataManager.buscarEmpleadoxTarjeta(tarjeta);

                Tarjeta t = mainApp.DataManager.buscarTarjetadeEmpleado(emp.Id);
                // Solo se envia la info de un empleado si tiene tarjeta asociada y algun accesslevel asociado
                if ((tarjeta == null) || (t == null))
                {
                    loguearString("NO SE PUDO ENVIAR LA INFORMACIÓN DEL EMPLEADO CON TARJETA " + tarjeta, TiposLOG.HH);
                    return;
                }

                string accessLevels = AccessLevelLogic.getAccessLevelsByBadgeInHH(t.NUMERODETARJETA, e.stateObject.HHID);

                if (accessLevels.Trim().Length > 0)
                {

                    dataEmp = "TARJETA:" + t.NUMERODETARJETA + ",NOMBRE:" + emp.Nombre + ",APELLIDO:" + emp.Apellido + ",DOCUMENTO:" + emp.NumeroDocumento + ",EMPRESA:" + emp.Empresa + ",ACCESO:" + t.ESTADO.ToString() + ",IMGVER:" + emp.imageVersion.ToString().Trim() + ",ADMIN:" + isAdmin_BETA + ",PASS:"******",ACCESSID:" + accessLevels + ",VERSION:" + emp.VersionEmpleado.ToString() +",PERSONID:" + emp.PersonID.ToString();

                    //dataEmp = "TARJETA:" + t.NUMERODETARJETA + ",NOMBRE:" + emp.Nombre + ",APELLIDO:" + emp.Apellido + ",DOCUMENTO:" + emp.NumeroDocumento + ",EMPRESA:" + emp.Empresa + ",ACCESO:" + t.ESTADO.ToString() + ",IMGVER:" + emp.imageVersion.ToString().Trim() + ",ADMIN:" + isAdmin_BETA + ",PASS:"******",ACCESSID:" + accessLevels;

                }

                // Solo encola el trabajo si se dispone efectivamente informacion sobre el HH
                if (mainApp.ComunicationSystem.communicationLAYER.isPannelConnected(id))
                {

                    string dataStringEncriptado = Encriptar_Datos.Encriptar.encriptar(dataEmp, communicationSystem.ClaveEncriptar);
                    byte[] dataBytes = Encoding.ASCII.GetBytes(dataStringEncriptado);

                    int chunkSize = FIXED_HEADER_LENGTH + dataBytes.Length;
                    //TYPE:ADDEMP,SIZE:(.*)
                    string header = "TYPE:ADDEMP,SIZE:" + chunkSize.ToString();

                    // Nuevo: Encriptado de datos.
                    string headerEncriptado = Encriptar_Datos.Encriptar.encriptar(header, communicationSystem.ClaveEncriptar);
                    headerEncriptado = "SIZE:" + chunkSize.ToString() + ",DATA:" + headerEncriptado;

                    string finalHeader = headerEncriptado.PadRight(FIXED_HEADER_LENGTH);
                    byte[] headerBytedata = Encoding.ASCII.GetBytes(finalHeader);

                    byte[] dataToSend = new byte[finalHeader.Length + dataBytes.Length];
                    System.Buffer.BlockCopy(headerBytedata, 0, dataToSend, 0, headerBytedata.Length);
                    System.Buffer.BlockCopy(dataBytes, 0, dataToSend, headerBytedata.Length, dataBytes.Length);

                    JobToSendToClient j = new JobToSendToClient();

                    jobCounter++;
                    j.ID = jobCounter;
                    j.header = headerEncriptado;
                    j.byteData = dataToSend;

                    e.stateObject.pendingJobs.Enqueue(j);     // Nuevo: un pendingjobs por cada cliente.
                    e.stateObject.readyToSend.Set();
                    loguearString(e.stateObject.HHID + "- TRABAJO Agregar empleado: " + header, TiposLOG.HH);
                }
            }
            catch (Exception ex) { loguearString("Excepción agregando empleado: "+ex.Message, TiposLOG.HH); }
        }