// 
// 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 System.Data;
using System.Data.SqlClient;
using gestor.utiles;

namespace minigestor.datos
{
    public enum ORDEN_CANDIDATOS
    {
        NIF, NOMBRE, HORACITA, HORACALCULADA, TICKET, CITAVINCULADA
    }

    public class TablaCandidatos
    {
        public CandidatosDataTable tabla;
        DataView vistaId = null;
        DataView presentes = null;

        protected static TablaCandidatos yo = null;
        public bool cargada;

        public static TablaCandidatos getTablaCandidatos() {
            if (yo == null) yo = new TablaCandidatos();
            return yo;
        }

        public TablaCandidatos() {
            tabla = new CandidatosDataTable();
            vistaId = new DataView(tabla);
            vistaId.Sort = "Id";
        }

        public DataView vistaPresentes() {
            if (presentes == null) {
                presentes = new DataView(tabla);
                presentes.RowFilter = "ESTADO='P'";
            }
            return presentes;
        }

        public RegistroCandidatos buscarId(int id) {
            int idx = vistaId.Find(id);
            if (idx > -1) return (RegistroCandidatos)vistaId[idx].Row;
            else return null;
        }

        internal void borrarId(int id) {
            int idx = vistaId.Find(id);
            if (idx > -1) vistaId.Delete(idx);
        }

        internal void vaciar() {
            tabla.Clear();
        }

        internal RegistroCandidatos nuevoRegistro(string msj) {
            RegistroCandidatos reg = tabla.NewCandidatosRow();
            reg.leerRegistroCompleto(msj);
            int idx;
            if ((idx = vistaId.Find(reg.Id)) > -1) {
                RegistroCandidatos reg2 = (RegistroCandidatos)vistaId[idx].Row;
                reg2.leerRegistroCompleto(reg);
                return reg2;
            } else {
                tabla.Rows.Add(reg);
                return reg;
            }
        }

        internal void cambiaTurno() {

        }

        public void cargaEstimacion(string msj) {
            string[] dat = msj.Split('|');
            if (dat.Length > 2) {
                nuevoRegistro(msj);
            } else {
                try {
                    RegistroCandidatos r = buscarId(Int32.Parse(dat[0]));
                    if (r != null) {
                        r.horaEstimada = Global.nzt(dat[1]);
                    }
                } catch { }
            }
        }

        public IComparer<RegistroCandidatos> obtenerComparador(int orden, bool asc) {
            IComparer<RegistroCandidatos> comparador = null;
            switch ((ORDEN_CANDIDATOS)orden) {
                case ORDEN_CANDIDATOS.NOMBRE: comparador = new ComparadorNombre(asc); break;
                case ORDEN_CANDIDATOS.NIF: comparador = new ComparadorNif(asc); break;
                case ORDEN_CANDIDATOS.CITAVINCULADA: comparador = new ComparadorVinculada(asc); break;
                case ORDEN_CANDIDATOS.TICKET: comparador = new ComparadorTicket(asc); break;
                default: comparador = new ComparadorHoraCita(asc); break;
            }
            return comparador;
        }


        internal RegistroCandidatos buscarPorNifPresente(string nif) {
            for (int i = 0; i < tabla.Rows.Count; i++) {
                RegistroCandidatos rc = tabla[i];
                if (rc.nif == nif && rc.estado == "P") {
                    return rc;
                }
            }
            return null;
        }

        public RegistroCandidatos buscarPorNif(string nif) {
            for (int i = 0; i < tabla.Rows.Count; i++) {
                RegistroCandidatos rc = tabla[i];
                if (rc.nif.StartsWith(nif)) {
                    return rc;
                }
            }
            return null;
        }

        internal string buscarNombrePorNif(string nifABuscar) {
            RegistroCandidatos rc = buscarPorNif(nifABuscar);
            if (rc != null) return rc.nombre;
            return "";
        }


        internal RegistroCandidatos buscarPorNifyCola(string nif, string cola) {
            for (int i = 0; i < tabla.Rows.Count; i++) {
                RegistroCandidatos rc = tabla[i];
                if (rc.nif == nif && rc.cola == cola && (rc.estadoVacio() || rc.estado == "D")) {
                    return rc;
                }
            }
            return null;
        }

        public class ComparadorNif : IComparer<RegistroCandidatos>
        {
            bool asc;
            public ComparadorNif(bool asc) {
                this.asc = asc;
            }
            public int Compare(RegistroCandidatos r1, RegistroCandidatos r2) {
                if (asc) return r1.nif.CompareTo(r2.nif);
                else return r2.nif.CompareTo(r1.nif);
            }
        }

        public class ComparadorNombre : IComparer<RegistroCandidatos>
        {
            bool asc;
            public ComparadorNombre(bool asc) {
                this.asc = asc;
            }
            public int Compare(RegistroCandidatos r1, RegistroCandidatos r2) {
                if (asc) return r1.nombre.CompareTo(r2.nombre);
                else return r2.nombre.CompareTo(r1.nombre);
            }
        }

        public class ComparadorVinculada : IComparer<RegistroCandidatos>
        {
            bool asc;
            public ComparadorVinculada(bool asc) {
                this.asc = asc;
            }
            public int Compare(RegistroCandidatos r1, RegistroCandidatos r2) {
                if (asc) return r1.citaVinculada.CompareTo(r2.citaVinculada);
                else return r2.citaVinculada.CompareTo(r1.citaVinculada);
            }
        }

        public class ComparadorTicket : IComparer<RegistroCandidatos>
        {
            bool asc;
            public ComparadorTicket(bool asc) {
                this.asc = asc;
            }
            public int Compare(RegistroCandidatos r1, RegistroCandidatos r2) {
                if (asc) return r1.numeroTicket.CompareTo(r2.numeroTicket);
                else return r2.numeroTicket.CompareTo(r1.numeroTicket);
            }
        }

        public class ComparadorHoraCita : IComparer<RegistroCandidatos>
        {

            bool asc;
            public ComparadorHoraCita(bool asc) {
                this.asc = asc;
            }
            public int Compare(RegistroCandidatos r1, RegistroCandidatos r2) {
                DateTime t1;
                DateTime t2;
                if (asc) {
                    t1 = r1.horaCita;
                    t2 = r2.horaCita;
                } else {
                    t1 = r2.horaCita;
                    t2 = r1.horaCita;
                }
                int v = t1.CompareTo(t2);
                if (v == 0) {
                    t1 = r1.horaPresente;
                    t2 = r2.horaPresente;
                    return t1.CompareTo(t2);
                }
                return v;
            }
        }

        public void cambiaEstadoVinculados(string codigoCita, string nuevoEstado, DateTime horaPresente, DateTime horaCalculada) {
            for (int i = 0; i < tabla.Rows.Count; i++) {
                RegistroCandidatos r = tabla[i];
                if (r.citaVinculada == codigoCita && r.estado != "P" && r.citaMultiple > 1) {
                    r.cambiaEstado(nuevoEstado, horaPresente, horaCalculada);
                }
            }
        }

        internal void igualarMesaYCola(RegistroCandidatos reg) {
            if (reg.citaMultiple > 1) {
                for (int i = 0; i < tabla.Rows.Count; i++) {
                    RegistroCandidatos r = tabla[i];
                    if (r.citaVinculada == reg.citaVinculada && r.citaMultiple > 1) {
                        r.cola = reg.cola;
                        r.operador = reg.operador;
                    }
                }
            }
        }

        internal List<RegistroCandidatos> obtenerLista() {
            List<RegistroCandidatos> lista = new List<RegistroCandidatos>(100);
            foreach (RegistroCandidatos r in tabla.enumRegistros()) {
                lista.Add(r);
            }
            lista.Sort(new ComparadorHoraCita(true));
            return lista;
        }

        internal string obtenerListaVinculados(string codigoCita, TablaCandidatosVinculados copia) {
            string cad = "";
            for (int i = 0; i < tabla.Rows.Count; i++) {
                RegistroCandidatos rc = tabla[i];
                if (rc.citaVinculada == codigoCita && rc.citaMultiple > 1) {
                    cad += rc.nif + "  " + rc.nombre + "\n";
                    if (copia != null) {
                        copia.add(rc);
                    }
                }
            }
            if (copia != null) {
                copia.ordena();
            }
            return cad;
        }
    }
}

