using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using GMW_data;
using SteamWare;

namespace GMW_Term.WebUserControls
{
    public partial class mod_barcode : System.Web.UI.UserControl
    {
        // variabile per verificare se è operatore
        bool _validUserInSession = false;
        string _homeBtnText = "Home";
        string _homeBtnLink = "~/Home.aspx";


        /// <summary>
        /// wrapper traduzione termini
        /// </summary>
        /// <param name="lemma"></param>
        /// <returns></returns>
        public string traduci(string lemma)
        {
            string answ = $"[{lemma}]";
            try
            {
                answ = user_std.UtSn.Traduci(lemma);
            }
            catch
            { }
            return answ;
        }

        #region area eventi

        public event EventHandler eh_scannedUser;
        public event EventHandler eh_resetUser;
        public event EventHandler eh_scannedUdc;
        public event EventHandler eh_scannedAL;
        public event EventHandler eh_scannedListaPrelievo;
        public event EventHandler eh_scannedParticolare;
        public event EventHandler eh_scannedCella;

        #endregion

        /// <summary>
        /// testo del pulsante HOME
        /// </summary>
        public string homeBtnText
        {
            set
            {
                _homeBtnText = value;
                traduciObj();
            }
            get
            {
                return _homeBtnText;
            }
        }
        /// <summary>
        /// link del pulsante HOME
        /// </summary>
        public string homeBtnLink
        {
            set
            {
                _homeBtnLink = value;
                traduciObj();
            }
            get
            {
                return _homeBtnLink;
            }
        }
        /// <summary>
        /// traduce stringhe oggetti
        /// </summary>
        protected void traduciObj()
        {
            // scrive label e text bottoni
            btnLoginPage.Text = string.Format("{0}\n[Alt+{1}]", traduci("Login"), 7);
            btnLoginPage.AccessKey = "7";
            btnButtonsHome.Text = string.Format("{0}\n[Alt+{1}]", traduci(_homeBtnText), 9);
            btnButtonsHome.AccessKey = "9";
        }
        /// <summary>
        /// setta focus su barcode
        /// </summary>
        public void setFocusBarcode()
        {
            txtInput.Focus();
        }

        /// <summary>
        /// metodi al caricamento della pagina
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            traduciObj();

            // se username è valorizzato...
            verificaOperatoreInSessione();
            if (_validUserInSession)
            {
                btnLoginPage.Text = string.Format("{0}\n[Alt+{1}]", traduci("Logout"), 7);
                btnLoginPage.Visible = memLayer.ML.confReadBool("showLogout");
                btnButtonsHome.Visible = true;
                // se ho un precedente valore barcode lo mostro...
                if (memLayer.ML.isInSessionObject("Barcode_sel"))
                {
                    lblData.Text = memLayer.ML.StringSessionObj("Barcode_sel");
                }
                else
                {
                    lblData.Text = traduci("Insert Data") + "...";
                }
                lblRev.Visible = false;
            }
            // se non è valorizzato chiede di effettuare login...
            else
            {
                if (memLayer.ML.confReadBool("SimpleLogin"))
                {
                    // in questo caso fa login di default con l'operatore indicato...
                    string codOperatore = memLayer.ML.confReadString("CodOperDefault");
                    effettuaLoginOperatore(codOperatore);
                }
                else
                {
                    // sistema visualizzazione
                    btnLoginPage.Visible = false;
                    btnButtonsHome.Visible = false;
                    lblData.Text = traduci("Please Login");
                    lblRev.Text = string.Format("<b>{0}</b> v.{1}", memLayer.ML.confReadString("appName"), System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);
                    //lblRev.Text = string.Format("<b>{0}</b> v.{1}.{2}", memLayer.ML.confReadString("appName"), memLayer.ML.confReadString("mainRev"), memLayer.ML.confReadString("minRev"));
                }
            }
            txtInput.Focus();
        }
        /// <summary>
        /// inserito testo nella TextBox
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void txtInput_TextChanged(object sender, EventArgs e)
        {
            // generico try/catch
            try
            {
                // salvo in sessione la scansione attuale...
                valoreScan = txtScansione;
                // verifica l'input immesso
                tipoCodiceBarcode answ = TermClass.Ter.riconosciBarcode(txtScansione);
                verificaOperatoreInSessione();
                if (!_validUserInSession) //controllo: se non c'è operatore in sessione
                {
                    if (answ == tipoCodiceBarcode.Operatore)
                    {
                        effettuaLoginOperatore(txtScansione);
                    }
                    else
                    {
                        if (memLayer.ML.confReadBool("enableCookie"))
                        {
                            // provo a rifare login da operatore in cookie...
                            try
                            {
                                effettuaLoginOperatore(memLayer.ML.getCookieVal("CodSoggetto"));
                                logger.lg.scriviLog(string.Format("Rifatto login da cookie  x operatore: {0}", memLayer.ML.getCookieVal("CodSoggetto")), tipoLog.STARTUP);
                            }
                            catch
                            {
                                logger.lg.scriviLog("Non sono riuscito a rifare login da cookie 'CodSoggetto' x operatore", tipoLog.EXCEPTION);
                            }
                            lblData.Text = traduci("Invalid Code");
                            txtScansione = "";
                        }
                    }
                }
                else
                {
                    switch (answ)
                    {
                        case tipoCodiceBarcode.ND:
                            lblData.Text = traduci("Code Mismatch") + ": " + txtScansione;
                            txtInput.Text = "";
                            break;
                        case tipoCodiceBarcode.Operatore:
                            effettuaLoginOperatore(txtScansione);
                            break;
                        case tipoCodiceBarcode.ListaPrelievo:
                            chekListaPrelievo();
                            break;
                        case tipoCodiceBarcode.UDC:
                            verificaUdc();
                            break;
                        case tipoCodiceBarcode.AL:
                            verificaAL();
                            break;
                        case tipoCodiceBarcode.Particolare:
                            verificaParticolare();
                            break;
                        case tipoCodiceBarcode.Cella:
                            verificaCella();
                            break;
                        default:
                            lblData.Text = traduci("CodeNotRecognized") + ": " + txtScansione;
                            txtInput.Text = "";
                            break;
                    }
                }
                lblData.Font.Italic = false;
            }
            catch (Exception exc)
            {
                logger.lg.scriviLog(string.Format("Errore in decodifica testo da input barcode: {0}", exc), tipoLog.EXCEPTION);
                if (memLayer.ML.confReadBool("forceResetToHome"))
                {
                    Response.Redirect("Home.aspx");
                }
            }
        }
        /// <summary>
        /// verifica la lista di prelievo (se attivabile la attiva)
        /// </summary>
        private void chekListaPrelievo()
        {
            // verifica preliminare: se sia una chiamata di tipo "chiudi lista" e la lista sia quella dell'utente...
            bool isCloseCmd = false;
            try
            {
                isCloseCmd = txtScansione.EndsWith(memLayer.ML.confReadString("closeCodeLdp"));
            }
            catch
            { }
            if (isCloseCmd)
            {
                string codLista = txtScansione.Replace(memLayer.ML.confReadString("closeCodeLdp"), "");
                // controllo se sia la lista di prelievo assegnata all'utente
                bool isUserList = (codLista == MagClass.magazzino.codListaAttivaUtente);
                if (isUserList)
                {
                    // chiudo!
                    esitoOperazione esitoCompleta = GMW_data.MagClass.magazzino.completaListaPrelievo(memLayer.ML.StringSessionObj("CodCS"), codLista, MagClass.magazzino.CodSoggCurrUser, Request.UserHostName);
                    if (esitoCompleta == esitoOperazione.ok)
                    {
                        // indico che la lista indicata è stata chiusa
                        lblData.Text = string.Format("{0}: {1}", traduci("ListClosed"), codLista);
                    }
                    else if (esitoCompleta == esitoOperazione.errore_noUdc)
                    {
                        GMW_data.MagClass.magazzino.attivaListaPrelievo(memLayer.ML.StringSessionObj("CodCS"), codLista, MagClass.magazzino.CodSoggCurrUser);
                        httpLog(string.Format("Lista di prelievo {0} rilasciata poiché senza UDC prelevati da parte dell'opertore {1}", codLista, MagClass.magazzino.CodSoggCurrUser), tipoLog.INFO);
                        // tolgo dalla session la lista prelievo attuale...
                        memLayer.ML.emptySessionVal("CodLista_sel");
                        memLayer.ML.emptySessionVal("CodListaAttiva");
                        memLayer.ML.emptySessionVal("activeTask");
                        // indico che la lista indicata è stata rimessa in stato "attiva"
                        lblData.Text = string.Format("{0}: {1}", traduci("ListReActivated"), codLista);
                    }
                    // svuoto cache!
                    //memLayer.ML.emptySessionVal("UDC_sel");
                    GMW_data.TermClass.Ter.resetScanBarcode(true, false, false);
                }
                else
                {
                    // indico che il codice di chiusura NON è valido xché non ha in carico la lista indicata
                    lblData.Text = string.Format("!!! {0}: {1}", traduci("ListNotCloseable"), codLista);
                }
            }
            else
            {
                // verifico se al lista di prelievo sia valida ed attivabile
                if (MagClass.magazzino.listaPrelevabile(txtScansione))
                {
                    // verifico se l'utente ha delle lsite di prelievo attive e quindi NON PUO prenderne in carico altre
                    if (!MagClass.magazzino.userHasActiveLP)
                    {
                        // indico la lista come attiva
                        GMW_data.MagClass.magazzino.iniziaListaPrelievo(memLayer.ML.StringSessionObj("CodCS"), txtScansione, MagClass.magazzino.CodSoggCurrUser);
                        // salvo in sessione che voglio mostrare il dettaglio della lista appena presa in carico
                        memLayer.ML.setSessionVal("showDetListaPre", true, false);

                        if (eh_scannedListaPrelievo != null)
                        {
                            eh_scannedListaPrelievo(this, new EventArgs());
                        }
                    }
                    else
                    {
                        // indico l'errore: operatore già con una lista attiva
                        lblData.Text = string.Format("!!! {0}: {1}", traduci("ListStillOpen"), MagClass.magazzino.codListaAttivaUtente);
                    }
                }
                else
                {
                    // se la lista è quella in carico rimando a quella
                    if (txtScansione == MagClass.magazzino.codListaAttivaUtente)
                    {
                        // salvo in sessione che voglio mostrare il dettaglio della lista appena presa in carico
                        memLayer.ML.setSessionVal("showDetListaPre", true, false);

                        if (eh_scannedListaPrelievo != null)
                        {
                            eh_scannedListaPrelievo(this, new EventArgs());
                        }
                    }
                    else
                    {
                        // indico l'errore: lista non valida o non attivabile
                        lblData.Text = string.Format("!!! {0}: {1}", traduci("NotDownloadable"), txtScansione);
                    }
                }
            }
            txtInput.Text = "";
        }
        /// <summary>
        /// verifica validità UDC
        /// </summary>
        private void verificaUdc()
        {
            // controllo l'UDC se sia valido (==esistente)
            bool barcodeOk = MagClass.magazzino.checkUDC(valoreScan);
            if (barcodeOk)
            {
                // salvo in session UDC selezionato
                memLayer.ML.setSessionVal("UDC_sel", valoreScan, false);
                // svuoto AL...
                memLayer.ML.emptySessionVal("AL_sel");
                if (eh_scannedUdc != null)
                {
                    eh_scannedUdc(this, new EventArgs());
                }
            }
            else
            {
                lblData.Text = string.Format(traduci("UDCCodeInvalid") + ": " + "{0}", valoreScan);
                txtScansione = "";
            }
        }
        /// <summary>
        /// verifica validità AL
        /// </summary>
        private void verificaAL()
        {
            // controllo AL se sia valido (==esistente)
            bool barcodeOk = MagClass.magazzino.checkAL(valoreScan);
            if (barcodeOk)
            {
                // salvo in session AL selezionato
                memLayer.ML.setSessionVal("AL_sel", valoreScan, false);
                // svuoto UDC...
                memLayer.ML.emptySessionVal("UDC_sel");
                if (eh_scannedAL != null)
                {
                    eh_scannedAL(this, new EventArgs());
                }
            }
            else
            {
                lblData.Text = string.Format(traduci("ALCodeInvalid") + ": " + "{0}", valoreScan);
                txtScansione = "";
            }
        }
        /// <summary>
        /// verifica validità cella
        /// </summary>
        private void verificaCella()
        {
            // controllo cod cella se sia valido (==esistente)
            bool barcodeOk = MagClass.magazzino.checkCella(valoreScan);
            if (barcodeOk)
            {
                // calcolo idxCella
                int idxCella = MagClass.magazzino.IdxCellaByCodCella(memLayer.ML.StringSessionObj("CodCS"), valoreScan);
                // salvo in session idxCella selezionata
                memLayer.ML.setSessionVal("IdxCella_sel", idxCella);
                memLayer.ML.setSessionVal("codCella_sel", valoreScan);
                memLayer.ML.setSessionVal("activeTask", string.Format("Cella: {0}", valoreScan));
                if (eh_scannedCella != null)
                {
                    eh_scannedCella(this, new EventArgs());
                }
            }
            else
            {
                lblData.Text = string.Format(traduci("CellaCodeInvalid") + ": " + "{0}", valoreScan);
                txtScansione = "";
            }
        }
        /// <summary>
        /// verifica validità particolare
        /// </summary>
        private void verificaParticolare()
        {
            // controllo se sia valido il particolare (==esistente)
            bool barcodeOk = MagClass.magazzino.checkParticolare(memLayer.ML.StringSessionObj("CodCS"), valoreScan);
            if (barcodeOk)
            {
                // salvo in session particolare selezionato
                memLayer.ML.setSessionVal("Particolare_sel", txtScansione);
                memLayer.ML.setSessionVal("activeTask", string.Format("Particolare: {0}", valoreScan));
                if (eh_scannedParticolare != null)
                {
                    eh_scannedParticolare(this, new EventArgs());
                }
            }
            else
            {
                lblData.Text = string.Format(traduci("PartCodeInvalid") + ": " + "{0}", valoreScan);
                txtScansione = "";
            }
        }

        /// <summary>
        /// effettua le chiamate per la login
        /// </summary>
        /// <param name="dataIn"></param>
        private void effettuaLoginOperatore(string dataIn)
        {
            // solo se ho un codice !=""
            if (dataIn != "")
            {
                // salvo in sessione valore barcode
                memLayer.ML.setSessionVal("CodSoggetto", dataIn);
                if (memLayer.ML.confReadBool("enableCookie"))
                {
                    // salvo anche in cookie...
                    memLayer.ML.setCookieVal("CodSoggetto", dataIn);
                }
                // verifico che il cod operatore passato sia valido per Rilpro.Anagoperatori e Soggetti2Utente
                httpLog(string.Format("Richiesta di login tramite barcode da {0}, IP {1}", Request.UserHostName, Request.UserHostAddress), tipoLog.STARTUP);
                esitoLoginTerm esito = TermClass.Ter.doUserLogin(dataIn);
                if (esito == esitoLoginTerm.ok)
                {
                    // svuoto dati lista attiva e smartlist...
                    memLayer.ML.emptySessionVal("CodListaAttiva");
                    memLayer.ML.emptySessionVal("activeTask");
                    // salvo i dati di CodCS
                    memLayer.ML.setSessionVal("CodCS", memLayer.ML.confReadString("CodCS"), true);
                    // in caso operatore abbia liste attive le carico...
                    if (MagClass.magazzino.userHasActiveLP)
                    {
                        string codiceListaAttivo = "";
                        try
                        {
                            codiceListaAttivo = MagClass.magazzino.codListaAttivaUtente;
                            // salvo la lista di prelievo come attiva
                            memLayer.ML.setSessionVal("activeTask", string.Format("Lista Prelievo {0}", codiceListaAttivo));
                            memLayer.ML.setSessionVal("CodListaAttiva", codiceListaAttivo);
                        }
                        catch
                        {
                            // c'era una lista attiva, non l'ho recuperata, segno errore!
                            httpLog(string.Format(traduci("ErrorListDataRetrieval"), user_std.UtSn.utente), tipoLog.ERROR);
                        }
                    }
                    else
                    {
                        memLayer.ML.setSessionVal("activeTask", "Selezionato Operatore");
                    }
                    txtInput.Text = "";
                    // alza evento login!
                    if (eh_scannedUser != null)
                    {
                        eh_scannedUser(this, new EventArgs());
                    }
                }
                else
                {
                    // avvisa che il codice è errato
                    lblData.Text = string.Format("{0} {1} {2}", traduci("Single User"), txtInput.Text, traduci("NotInDb"));
                    txtInput.Text = "";
                }
            }
        }
        /// <summary>
        /// wrapper per log con salvataggio dell'IP del chiamante
        /// </summary>
        /// <param name="_testoPre"></param>
        /// <returns></returns>
        public bool httpLog(string _testoPre)
        {
            bool answ = false;
            string postazione_IP = "";
            try
            {
                postazione_IP = string.Format(" | {0} | ", Request.UserHostName);
            }
            catch
            { }
            logger.lg.scriviLog(postazione_IP + _testoPre);
            return answ;
        }
        /// <summary>
        /// wrapper per log con salvataggio dell'IP del chiamante
        /// </summary>
        /// <param name="_testoPre"></param>
        /// <returns></returns>
        public bool httpLog(string testoLog, tipoLog tipo)
        {
            bool answ = false;
            string postazione_IP = "";
            try
            {
                postazione_IP = string.Format(" | {0} | ", Request.UserHostName);
            }
            catch
            { }
            logger.lg.scriviLog(postazione_IP + testoLog, tipo);
            return answ;
        }
        /// <summary>
        /// effettua logout...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnLoginPage_Click(object sender, EventArgs e)
        {
            TermUtils.TU.forceLogOut();
            verificaOperatoreInSessione();
            // evento reset
            if (eh_resetUser != null)
            {
                eh_resetUser(this, new EventArgs());
            }
        }
        /// <summary>
        /// va alla pagina dei buttons principale
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnButtonsHome_Click(object sender, EventArgs e)
        {
            Response.Redirect(homeBtnLink);
        }
        /// <summary>
        /// Verifica se c'è un valore in sessione di tipo operatore
        /// </summary>
        protected void verificaOperatoreInSessione()
        {
            if (string.IsNullOrEmpty(user_std.UtSn.utente))
            {
                _validUserInSession = false;
                httpLog(string.Format("Errore: perso user da sessione: IP {0}, user-barcode '{1}'", Request.UserHostAddress, memLayer.ML.StringSessionObj("CodSoggetto")), tipoLog.ERROR);
            }
            else
            {
                _validUserInSession = true;
            }
        }
        /// <summary>
        /// testo contenuto nella textbox
        /// </summary>
        public string txtScansione
        {
            get
            {
                return txtInput.Text.Trim().ToUpper();
            }
            set
            {
                txtInput.Text = value;
            }
        }
        /// <summary>
        /// valore della scansione barcode
        /// </summary>
        public string valoreScan
        {
            get
            {
                return memLayer.ML.StringSessionObj("scannedValue");
            }
            set
            {
                memLayer.ML.setSessionVal("scannedValue", value, false);
            }
        }
        /// <summary>
        /// definisce se mostrare l'header text (Barcode input)
        /// </summary>
        public bool showHeaderText
        {
            get
            {
                return lblInput.Visible;
            }
            set
            {
                lblInput.Visible = value;
            }
        }
        /// <summary>
        /// definisce se mostrare testo di commento sotto barcode
        /// </summary>
        public bool showNoteText
        {
            get
            {
                return lblData.Visible;
            }
            set
            {
                lblData.Visible = value;
            }
        }
        /// <summary>
        /// numero minimo di caratteri x char autocomplete
        /// </summary>
        public int minCharAutocomplete
        {
            get
            {
                return aceParticolare.MinimumPrefixLength;
            }
            set
            {
                aceParticolare.MinimumPrefixLength = value;
            }
        }
        /// <summary>
        /// metodo di autocomplete extender da impiegare
        /// </summary>
        public string aceMethod
        {
            get
            {
                return aceParticolare.ServiceMethod;
            }
            set
            {
                aceParticolare.ServiceMethod = value;
            }
        }
    }
}