// 
// Copyright 2016 Agencia Estatal de Administración Tibutaria
//
// Licencia con arreglo a la EUPL, Versión 1.1 o -en cuanto
// sean aprobadas por la Comisión Europea- versiones
// posteriores de la EUPL (la «Licencia»);
// Solo podrá usarse esta obra si se respeta la Licencia.
// Puede obtenerse una copia de la Licencia en:
//  
// https://joinup.ec.europa.eu/software/page/eupl
//  
// Salvo cuando lo exija la legislación aplicable o se acuerde
// por escrito, el programa distribuido con arreglo a la
// Licencia se distribuye «TAL CUAL», SIN GARANTÍAS NI CONDICIONES
// DE NINGÚN TIPO, ni expresasni implícitas.
//
// Véase la Licencia en el idioma concreto que rige los permisos y 
// limitaciones que establece la Licencia.
// 

using System;
using System.Collections.Generic;
using System.Text;
using minigestor.datos;
using System.Windows.Forms;
using gestor.utiles;
using System.IO;
using ateneo.utiles;

namespace minigestor
{
    public class MiniGestor
    {
        public string numeroGestor;
        public int margenRetraso;
        public int margenPenalizacion;
        public string turno;
        public TablaCandidatos candidatos;
        public TablaColas colas;
        Configuracion conf = null;
        public Comunicaciones comunicaciones;
        public FormCandidatos principal;
        public int miEstado;
        int candidatosRecibidos;
        int candidatosEsperados;

        public MiniGestor() {
            Global.gestor = this;
            conf = Configuracion.instanciaUnica;
            comunicaciones = new Comunicaciones(this);
            conf.cargar();
        }

        void inicia() {
            try {
                preparaDatos();
                arrancaVentanaPrincipal();
                preparaComunicaciones();
            } catch (Exception exc) {
                MessageBox.Show((IWin32Window)null, "ERROR DESDE DENTRO:" + exc.Message);
            }
        }

        private void preparaDatos() {
            colas = TablaColas.getTablaColas();
            candidatos = TablaCandidatos.getTablaCandidatos();
        }

        void preparaComunicaciones() {
            if (!comunicaciones.conectar()) {
                Application.Exit();
                return;
            }
            comunicaciones.enviar(COD_ENVIADO.CONEXION, "minGestor", "2");
        }

        internal void conexionAceptada(string msj) {
            try {
                string[] pars = msj.Split('|');
                numeroGestor = pars[0];
                margenRetraso = Int32.Parse(pars[2]) * 60000;
                margenPenalizacion = Int32.Parse(pars[3]) * 60000;
                turno = pars[4];
                try
                {
                    ejecutarCmd("time", pars[6]);
                }
                catch { }
                try
                {
                    ejecutarCmd("date", pars[7]);
                }
                catch { }
                principal.congelarUI(true);
                comunicaciones.enviar(COD_ENVIADO.ENVIAR_TABLA_CANDIDATOS, "xx");
            } catch { }
        }

        private void arrancaVentanaPrincipal() {
            principal = new FormCandidatos(this);
            principal.Show();
        }

        internal void iniciaCargaCandidatos(string msj) {
            try {
                int numregistros = Int32.Parse(msj);
                candidatos.vaciar();
                candidatosRecibidos = 0;
                candidatosEsperados = numregistros;
                if (candidatosEsperados == 0) {
                    ajustesFinRegistrosCandidatos();
                }
            } catch (Exception exc) {
                LogExcepcion.guardar("Error en iniciaCargaCandidatos", exc);
            }
        }

        public void nuevoRegistroCandidatos(string reg) {
            candidatosRecibidos++;
            candidatos.nuevoRegistro(reg);
            if (candidatosRecibidos >= candidatosEsperados) {
                ajustesFinRegistrosCandidatos();
            }
        }

        void ajustesFinRegistrosCandidatos() {
            candidatos.cargada = true;
            if (principal != null) {
                principal.terminadaCargaCandidatos();
            }
        }

        internal void nuevoRegistroColas(string sreg) {
            try {
                if (sreg != "FIN_REGISTROS") {
                    colas.nuevoRegistro(sreg);
                } else {
                    colas.completa = true;
                }
            } catch (Exception exc) {
                LogExcepcion.guardar("Error en NuevoRegistroColas!", exc);
            }
        }

        internal void nuevoCandidato(string msj) {
            string[] partes = msj.Split(new char[] { '|' }, 2);
            RegistroCandidatos r = candidatos.nuevoRegistro(partes[1]);
            if (r == null) {
                MessageBox.Show("Error al recibir mensaje con tique: \n" + msj);
                return;
            }
            if (partes[0] == numeroGestor) {
                autoEnvio(r);
            }
        }

        private void autoEnvio(RegistroCandidatos r) {
            if (conf.mesa == "0") {
                MessageBox.Show("Numero de mesa erroneo");
                return;
            }
            string id = r.Id.ToString();
            comunicaciones.enviar(COD_ENVIADO.ENVIO_MANUAL_A_MESA, id + "", conf.mesa);        
        }

        internal void cambiaEstadoCandidato(string msj) {
            candidatos.nuevoRegistro(msj);
        }

        internal void cambioEstadoMesa(string msj) {
            string[] pars = msj.Split(new char[] { '|' }, 3);
            int valorEstado;
            try {
                valorEstado = Int32.Parse(pars[1]);
                if (pars[0] == conf.mesa) {
                    miEstado = valorEstado;
                }
                if (valorEstado == 3 && pars.Length > 2) {
                    cambiaEstadoCandidato(pars[2]);
                }
            } catch  {}
        }

        void ejecutarCmd(string comando, string valor) {
            System.Diagnostics.Process process = new System.Diagnostics.Process();
            process.StartInfo.CreateNoWindow = true;
            process.StartInfo.UseShellExecute = false;
            process.StartInfo.FileName = "CMD";
            process.StartInfo.Arguments = "/C " + comando + " " + valor;
            process.Start();
        }

        public void comunicaCambioEstado(RegistroCandidatos reg) {
            comunicaciones.enviar(COD_ENVIADO.ENVIO_MODIFICACION_CANDIDATO, numeroGestor, reg.ToString());
        }

        public void lanzarCliente() {
            inicia();
        }

        public void cerrarCliente() {
            comunicaciones.desconectar();
            principal.cerrar();
        }

        public void cambiarVisibilidad(bool v) {
            principal.Visible = v;
        }
    }
}
