// 
// 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.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using minigestor.datos;
using System.IO;
using ateneo.utiles;
using gestor.utiles;

namespace minigestor
{
    public partial class FormCandidatos : Form
    {
        TablaCandidatos tabla;
        DataView vista;
        MiniGestor main;
        Configuracion conf;
        public FormNuevoCandidato formNuevoCandidato = null;
        //bool solicitadaAperturaNuevo = false;
        private const int ESTADO_LIBRE = 2;
        string titulo;
        bool UICongelada = false;
        private bool peticionCierreInterna = false;

        public FormCandidatos(MiniGestor minigestor) {
            main = minigestor;
            conf = Configuracion.instanciaUnica;
            tabla = TablaCandidatos.getTablaCandidatos();
            InitializeComponent();
            titulo = "RELACION DE CANDIDATOS   Mesa " + conf.mesa;
            this.Text = titulo;
            this.BackColor = Global.colorApp;
            preparaGridCandidatos();
            insertarMenusScript();
        }

        public void congelarUI(bool congelado) {
            UICongelada = congelado;
            Text = congelado ? "Recibiendo relación de candidatos..." : titulo;
            this.btNuevaCita.Enabled = !congelado;
            this.btPresente.Enabled = !congelado;
        }

        void insertarMenusScript() {
            if (conf.scriptsCandidato.Count > 0) {
                menuGridCandidatos.Items.Add("-");
                foreach (ScriptCandidato sc in conf.scriptsCandidato) {
                    ToolStripMenuItem item = new ToolStripMenuItem();
                    item.Text = sc.menuTxt;
                    item.Tag = sc;
                    item.Click += new EventHandler(menuScript_Click);
                    menuGridCandidatos.Items.Add(item);
                }
            }
        }

        void menuScript_Click(object sender, EventArgs e) {
            ScriptCandidato sc = (ScriptCandidato)(sender as ToolStripDropDownItem).Tag;
            if (!File.Exists(sc.path)) {
                MessageBox.Show("'" + sc.path + "'\nArchivo no encontrado");
                return;
            }
            RegistroCandidatos reg = registroSeleccionadoEnGrid();
            ProgramaExterno.run(sc.path, reg.numeroTicket, reg.nif, reg.nombre);
        }

        void preparaGridCandidatos() {
            vista = new DataView(tabla.tabla);
            gridCandidatos.AutoGenerateColumns = false;
            gridCandidatos.DataSource = vista;
            poblarGrid(gridCandidatos);
        }

        private void poblarGrid(DataGridView grid) {
            DataGridViewTextBoxColumn column;
            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "Nombre";
            column.HeaderText = "NOMBRE";
            column.FillWeight = 250;
            grid.Columns.Add(column);
            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "Nif";
            column.HeaderText = "Iden.Fis";
            grid.Columns.Add(column);
            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "HoraCita";
            column.HeaderText = "Hora Cita";
            column.DefaultCellStyle.Format = "HH:mm:ss";
            grid.Columns.Add(column);
            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "CitaVinculada";
            column.HeaderText = "VINCUL.";
            grid.Columns.Add(column);
            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "NumeroTicket";
            column.HeaderText = "TIQUE";
            column.SortMode = DataGridViewColumnSortMode.Programmatic;
            grid.Columns.Add(column);
            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "cola";
            column.HeaderText = "COLA";
            grid.Columns.Add(column);
            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "Estado";
            column.HeaderText = "ESTADO";
            grid.Columns.Add(column);
            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "HoraCalculada2";
            column.HeaderText = "Hora ASIG";
            column.DefaultCellStyle.Format = "HH:mm:ss";
            grid.Columns.Add(column);
            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "HoraPresente";
            column.HeaderText = "Hora.PRES";
            column.DefaultCellStyle.Format = "HH:mm:ss";
            grid.Columns.Add(column);
            column = new DataGridViewTextBoxColumn();
            column.DataPropertyName = "FalsoTicket";
            column.Name = "FalsoTicket";
            column.Visible = false;
            grid.Columns.Add(column);
        }

        private void grid_KeyPress(object sender, KeyPressEventArgs e) {
            busquedaProgresiva(e.KeyChar);
        }

        long tickCount = 0;
        string acumulado = "";
        bool desc = false;
        int numColBusqueda;
        int numFilaBusqueda;
        private void busquedaProgresiva(char c) {
            long tick = Environment.TickCount;
            if (tick - tickCount > 1000) {
                acumulado = "";
                numFilaBusqueda = desc ? gridCandidatos.Rows.Count - 1 : 0;
            }
            tickCount = tick;
            acumulado += c;
            string s;
            if (!desc) {
                int limit = gridCandidatos.Rows.Count;
                for (int i = numFilaBusqueda; i < limit; i++) {
                    s = gridCandidatos[numColBusqueda, i].FormattedValue.ToString();
                    if (s.StartsWith(acumulado, StringComparison.CurrentCultureIgnoreCase)) {
                        gridCandidatos.CurrentCell = gridCandidatos[1, i];
                        numFilaBusqueda = i;
                        return;
                    }
                }
            } else {
                for (int i = numFilaBusqueda; i >= 0; i--) {
                    s = gridCandidatos[numColBusqueda, i].FormattedValue.ToString();
                    if (s.StartsWith(acumulado, StringComparison.CurrentCultureIgnoreCase)) {
                        gridCandidatos.CurrentCell = gridCandidatos[numColBusqueda, i];
                        numFilaBusqueda = i;
                        return;
                    }
                }
            }
        }

        private void grid_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
            if (gridCandidatos.Columns[e.ColumnIndex].DataPropertyName == "NumeroTicket") {
                DataGridViewColumn columna = gridCandidatos.Columns["FalsoTicket"];
                if (gridCandidatos.SortedColumn != null && gridCandidatos.SortedColumn.Index == columna.Index) {
                    desc = gridCandidatos.SortOrder == SortOrder.Ascending ? true : false;
                }
                gridCandidatos.Sort(columna, desc ? ListSortDirection.Descending : ListSortDirection.Ascending);
                gridCandidatos.Columns[e.ColumnIndex].HeaderCell.SortGlyphDirection = desc ? SortOrder.Descending : SortOrder.Ascending;
            } else {
                desc = vista.Sort.IndexOf("DESC") > 0;
            }
            numColBusqueda = e.ColumnIndex;
        }

        private void btNuevaCita_Click(object sender, EventArgs e) {
            if (comprobarEstado()) {
                nuevaCita();
            }
        }

        private void nuevaCita() {
            nuevaCita(null);
        }

        private void nuevaCita(RegistroCandidatos rc) {
            if (formNuevoCandidato == null) {
                formNuevoCandidato = new FormNuevoCandidato(main);
            }
            if (rc != null) {
                formNuevoCandidato.clonarTiquet(rc.nif, rc.nombre);
            } else {
                formNuevoCandidato.borraCampos();
            }
            formNuevoCandidato.Show();
            if (formNuevoCandidato.WindowState == FormWindowState.Minimized) {
                formNuevoCandidato.WindowState = FormWindowState.Normal;
            }
            try {
                Win32Apis.bringToFront(formNuevoCandidato);
            } catch (Exception) { }
        }

        internal List<RegistroCandidatos> obtenerLista() {
            List<RegistroCandidatos> lista = new List<RegistroCandidatos>(vista.Count);
            for (int i = 0; i < vista.Count; i++) {
                lista.Add((RegistroCandidatos)vista[i].Row);
            }
            return lista;
        }

        private void btPresente_Click(object sender, EventArgs e) {
            ponerMarcaEstado("P");
            gridCandidatos.Focus();
        }

        private bool generarNuevaCita() {
            if (!comprobarEstado()) {  // comprobar que estamos libres
                return false;
            }
            RegistroCandidatos reg = registroSeleccionadoEnGrid();
            if (reg == null) {
                return false;
            }
            // creo que estado "D" es imposible en este modelo pero por si...
            if (reg.estado != "S" && reg.estado != "F" && reg.estado != "D") {
                MessageBox.Show("El registro debe figurar como atendido para generar nueva cita");
                return false;
            }

            nuevaCita(reg);

            return true;
        }


        private bool ponerMarcaEstado(string marca) {
            if (!comprobarEstado()) {  // comprobar que estamos libres
                return false;
            }
            RegistroCandidatos reg = registroSeleccionadoEnGrid();
            if (reg == null) {
                return false;
            }
            if (reg.estado == marca) {
                return false;
            }
            if (reg.estado.Trim() != "" ) {
                if (marca == " ") {
                    if (MessageBox.Show("Este registro figura como atendido. ¿Desea borrar su estado?",
                    "ATENCIÓN", MessageBoxButtons.YesNo) == DialogResult.No) {
                        return false;
                    }
                } else {
                    return false;
                }
            }
            int r = Global.compruebaHoraCalculada(Environment.TickCount, reg.horaCita.Ticks);
            DateTime ahora = DateTime.Now;
            if (marca == "P") {
                if (r == 3) {
                    MessageBox.Show("Este contribuyente no puede ser atendido.\nEstá fuera del margen horario establecido\nDebe solicitar nueva cita.");
                    return false;
                }
            } 
            reg.cambiaEstado(marca, ahora, ahora);
            return true;
        }

        bool comprobarEstado() {
            if (main.miEstado != ESTADO_LIBRE) {
                MessageBox.Show("Debe estar en estado LIBRE para efectuar la operación");
                return false;
            }
            return true;
        }

        RegistroCandidatos registroSeleccionadoEnGrid() {
            if (!UICongelada && gridCandidatos.SelectedRows.Count > 0) {
                DataRowView dvr = (DataRowView)gridCandidatos.SelectedRows[0].DataBoundItem;
                return (RegistroCandidatos)dvr.Row;
            }
            return null;
        }

        private void gridCandidatos_MouseDown(object sender, MouseEventArgs e) {
            if (e.Button == MouseButtons.Right) {
                DataGridView.HitTestInfo hti = gridCandidatos.HitTest(e.X, e.Y);
                if (hti.Type == DataGridViewHitTestType.Cell) {
                    gridCandidatos.ClearSelection();
                    gridCandidatos.Rows[hti.RowIndex].Selected = true;
                }
            }
        }

        private void gridCandidatos_MouseUp(object sender, MouseEventArgs e) {
            if (e.Button == MouseButtons.Right) {
                DataGridView.HitTestInfo hti = gridCandidatos.HitTest(e.X, e.Y);
                if (hti.Type == DataGridViewHitTestType.Cell) {
                    menuGridCandidatos.Show(gridCandidatos.PointToScreen(e.Location));
                }
            }
        }

        private void marcarComoPresenteToolStripMenuItem_Click(object sender, EventArgs e) {
            ponerMarcaEstado("P");
        }

        private void cambiarANOPRESENTEToolStripMenuItem_Click(object sender, EventArgs e) {
            ponerMarcaEstado(" ");
        }


        internal void terminadaCargaCandidatos() {
            congelarUI(false);
            //if (solicitadaAperturaRelacion) {
            //abrirVentanaCandidatos();
            //}
            //imprimirListadoDeCitaPreviaToolStripMenuItem.Enabled = true;
        }

        public void cerrar() {
            peticionCierreInterna = true;
            this.Close();
        }

        private void FormCandidatos_FormClosing(object sender, FormClosingEventArgs e) {
            if (!peticionCierreInterna && e.CloseReason == CloseReason.UserClosing) {
                MessageBox.Show("Cierre la ventana Operador para cerrar esta aplicación");
                e.Cancel = true;
            }
        }

        private void generarNuevaToolStripMenuItem_Click(object sender, EventArgs e) {
            generarNuevaCita();
        }

    }
}
