using GMW_data;
using Newtonsoft.Json;
using SteamWare;
using System;
using System.Collections.Generic;
using System.Web.UI;

namespace GMW.WebUserControls
{
  public partial class mod_consumoAnime : System.Web.UI.UserControl
  {

    #region parametri status con scadenza

    /// <summary>
    /// Struttura dictionary dei valori CURRENT di stato oggetti pagina (Page Object Status) 
    /// </summary>
    protected Dictionary<string, string> cPOS = new Dictionary<string, string>();

    /// <summary>
    /// Struttura dictionary dei valori PREVIOUS di stato oggetti pagina (Page Object Status)
    /// ATTENZIONE: dopo N sec viene invalidata
    /// </summary>
    protected Dictionary<string, string> pPOS
    {
      get
      {
        Dictionary<string, string> answ = new Dictionary<string, string>();
        //// se non fossero scaduti li leggo da session...)
        //if (DateTime.Now < lastCheck.AddSeconds(BCReadDurSec))
        //{
        if (memLayer.ML.isInSessionObject(string.Format("pPOS.{0}", this.ID)))
        {
          answ = JsonConvert.DeserializeObject<Dictionary<string, string>>(memLayer.ML.StringSessionObj(string.Format("pPOS.{0}", this.ID)));
        }
        //}
        return answ;
      }
      set
      {
        string serVal = JsonConvert.SerializeObject(value);
        memLayer.ML.setSessionVal(string.Format("pPOS.{0}", this.ID), serVal, false);
      }
    }
    /// <summary>
    ///  Indica la durata dei valori letti da barcode prima di farli scadere
    /// </summary>
    protected int BCReadDurSec
    {
      get
      {
        return memLayer.ML.cdvi("BCReadDurSec");
      }
    }
    /// <summary>
    /// DataOra ultimo controllo
    /// </summary>
    protected DateTime lastCheck
    {
      get
      {
        DateTime answ = DateTime.Now.AddHours(-1);
        DateTime.TryParse(memLayer.ML.StringSessionObj(string.Format("lastCheck.{0}", this.ID)), out answ);
        return answ;
      }
      set
      {
        memLayer.ML.setSessionVal(string.Format("lastCheck.{0}", this.ID), value, false);
      }
    }

    #endregion

    #region parametri in sessione

    /// <summary>
    /// Ultimo messaggio salvato
    /// </summary>
    protected string lastMess
    {
      get
      {
        //return memLayer.ML.StringSessionObj(string.Format("lastMess.{0}", this.ID));
        string answ = "";
        try
        {
          answ = pPOS["mess"];
        }
        catch
        { }
        return answ;
      }
      set
      {
        //memLayer.ML.setSessionVal(string.Format("lastMess.{0}", this.ID), value, false);
        var mPOS = pPOS;
        mPOS["mess"] = value;
        pPOS = mPOS;
      }
    }
    /// <summary>
    /// Ultimo CSS salvato
    /// </summary>
    protected string lastCss
    {
      get
      {
        //return memLayer.ML.StringSessionObj(string.Format("lastCss.{0}", this.ID));
        string answ = "";
        try
        {
          answ = pPOS["css"];
        }
        catch
        { }
        return answ;
      }
      set
      {
        //memLayer.ML.setSessionVal(string.Format("lastCss.{0}", this.ID), value, false);
        var mPOS = pPOS;
        mPOS["css"] = value;
        pPOS = mPOS;
      }
    }
    /// <summary>
    /// Ultimo BCode letto salvato
    /// </summary>
    protected string lastBCodeIn
    {
      get
      {
        return memLayer.ML.StringSessionObj(string.Format("lastBCodeIn.{0}", this.ID));
      }
      set
      {
        memLayer.ML.setSessionVal(string.Format("lastBCodeIn.{0}", this.ID), value, false);
      }
    }
    /// <summary>
    /// indica UDC selezionato
    /// </summary>
    protected string currUdcFrom
    {
      get
      {
        return memLayer.ML.StringSessionObj(string.Format("currUdcFrom.{0}", this.ID));
      }
      set
      {
        memLayer.ML.setSessionVal(string.Format("currUdcFrom.{0}", this.ID), value, false);
      }
    }
    /// <summary>
    /// CSS corrente
    /// </summary>
    protected string currCss
    {
      get
      {
        //return memLayer.ML.StringSessionObj(string.Format("lastCss.{0}", this.ID));
        string answ = "";
        try
        {
          answ = cPOS["css"];
        }
        catch
        { }
        if (string.IsNullOrEmpty(answ))
        {
          answ = "stileComandoND";
        }
        return answ;
      }
      set
      {
        //memLayer.ML.setSessionVal(string.Format("lastCss.{0}", this.ID), value, false);
        cPOS["css"] = value;
      }
    }
    /// <summary>
    /// Mess corrente
    /// </summary>
    protected string currMess
    {
      get
      {
        //return memLayer.ML.StringSessionObj(string.Format("lastCss.{0}", this.ID));
        string answ = "";
        try
        {
          answ = cPOS["mess"];
        }
        catch
        { }
        return answ;
      }
      set
      {
        //memLayer.ML.setSessionVal(string.Format("lastCss.{0}", this.ID), value, false);
        cPOS["mess"] = value;
      }
    }
    /// <summary>
    /// Classe assegnata al pannello comandi
    /// </summary>
    protected string panelClass
    {
      get
      {
        return pnlAll.CssClass;
      }
      set
      {
        pnlAll.CssClass = value;
        lastCss = value;
      }
    }
    /// <summary>
    /// indica se i caratteri vadano forzati a maiuscoli
    /// </summary>
    public bool forceUppercase
    {
      get
      {
        return memLayer.ML.confReadBool("forceUppercase");
      }
    }
    /// <summary>
    /// indica se siano disabilitate le conferme x avere operazioni veloci
    /// </summary>
    public bool disableConfirm
    {
      get
      {
        return memLayer.ML.BoolSessionObj(string.Format("disableConfirm.{0}", this.ID));
      }
      set
      {
        memLayer.ML.setSessionVal(string.Format("disableConfirm.{0}", this.ID), value);
        fixBtnDisableConf();
      }
    }
    /// <summary>
    /// veto x update ulteriori
    /// </summary>
    public bool vetoUpdate
    {
      get
      {
        return memLayer.ML.BoolSessionObj(string.Format("veto.{0}", this.ID));
      }
      set
      {
        memLayer.ML.setSessionVal(string.Format("veto.{0}", this.ID), value);
        fixBtnDisableConf();
      }
    }
    /// <summary>
    /// indica se siano disabilitate le conferme x avere operazioni veloci
    /// </summary>
    public bool needForza_NoPosVLP
    {
      get
      {
        return memLayer.ML.BoolSessionObj("Forza_NoPosVLP");
      }
      set
      {
        memLayer.ML.setSessionVal("Forza_NoPosVLP", value);
        fixBtnDisableConf();
      }
    }
    /// <summary>
    /// indica se siano disabilitate le conferme x avere operazioni veloci
    /// </summary>
    public bool needForzaCons_inLDP
    {
      get
      {
        return memLayer.ML.BoolSessionObj("ForzaCons_inLDP");
      }
      set
      {
        memLayer.ML.setSessionVal("ForzaCons_inLDP", value);
        fixBtnDisableConf();
      }
    }

    #endregion

    /// <summary>
    /// sistemo labels oggetti
    /// </summary>
    private void traduciObj()
    {
      // buttons
      btnConsuma.Text = traduci("btnConsumaUdc");
      btnForzaCons_NoPosVLP.Text = traduci("btnForzaCons_NoPosVLP");
      btnForzaCons_inLDP.Text = traduci("btnForzaCons_inLDP");
      // fix button gestione disabilitazione conferme
      fixBtnDisableConf();
    }
    /// <summary>
    /// sistema btn abilitazione/disabilitazione conferma comandi
    /// </summary>
    private void fixBtnDisableConf()
    {
      btnForzaCons_NoPosVLP.Visible = false;
      btnForzaCons_inLDP.Visible = false;
      btnConsuma.Visible = true;
      if (disableConfirm)
      {
        btnDisableConf.Text = traduci("confirmDisabled");
        btnDisableConf.CssClass = "btn btn-danger";
      }
      else
      {
        btnDisableConf.Text = traduci("confirmEnabled");
        btnDisableConf.CssClass = "btn btn-success";
      }
      if (needForza_NoPosVLP)
      {
        btnForzaCons_NoPosVLP.Visible = true;
        btnConsuma.Visible = false;
      }
      else
      {
        btnForzaCons_NoPosVLP.Visible = false;
      }
      if (needForzaCons_inLDP)
      {
        btnForzaCons_inLDP.Visible = true;
        btnConsuma.Visible = false;
      }
      else
      {
        btnForzaCons_inLDP.Visible = false;
      }
    }
    /// <summary>
    /// wrapper traduzione
    /// </summary>
    /// <param name="lemma"></param>
    /// <returns></returns>
    public string traduci(object lemma)
    {
      return user_std.UtSn.Traduci(lemma.ToString());
    }

    /// <summary>
    /// caricamento pagina
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
      if (!Page.IsPostBack)
      {
        currCss = "stileAttesa";
        disableConfirm = false;
        traduciObj();
        currUdcFrom = "";
        lastBCodeIn = "";
        vetoUpdate = false;
        lastCheck = DateTime.Now;
      }
      doChecks();
      updateVisual();
    }
    /// <summary>
    /// Aggiornamento visualizzazione dati e stili
    /// </summary>
    private void updateVisual()
    {
      lblUdcSel.Text = "";
      if (currUdcFrom != "")
      {
        lblUdcSel.Text += string.Format("UDC: <b>{0}</b>", currUdcFrom);
      }

      // controllo se ho fatto un check meno di 2 sec prima...  
      if (DateTime.Now < lastCheck.AddSeconds(BCReadDurSec))
      {
        // imposto "Vecchi" valori
        lblMessaggi.Text = lastMess;
        panelClass = lastCss;
      }
      else
      {
        // imposto NUOVI valori  
        lblMessaggi.Text = currMess;
        panelClass = currCss;
        // salvo NUOVI valori --> PREV
        pPOS = cPOS;
        lastCheck = DateTime.Now;
      }
    }

    /// <summary>
    /// effettua controlli visibilità
    /// </summary>
    private void doChecks()
    {
      checkVeto();
      checkBarcode();
      checkConsuma();
      checkUDC();
    }

    #region metodi verifica
    private void checkVeto()
    {
      // controllo se ho fatto un check meno di 2 sec prima...  
      if (DateTime.Now > lastCheck.AddSeconds(BCReadDurSec))
      {
        vetoUpdate = false;
      }
    }
    /// <summary>
    /// controlla se ci sia un barcode
    /// </summary>
    private void checkBarcode()
    {
      if (barcodeIn != "")
      {
        DS_Applicazione.ElencoCartelliniRow rigaCart;
        string tipoImballo = "";
        if (barcodeIn != lastBCodeIn || !vetoUpdate)
        {
          currMess = string.Format("Barcode digitato: {0}", barcodeIn);
          switch (tipoBCode)
          {
            case tipoCodiceBarcode.UDC:
              // procedo solo se UDC esistente
              if (MagClass.magazzino.checkUDC(barcodeIn))
              {
                // cerco di recuperare riga UDC
                try
                {
                  rigaCart = DataProxy.obj.taCartellini.stp_getByUdc(barcodeIn)[0];
                  tipoImballo = rigaCart.CodImballo;
                }
                catch
                { }
                // salvo UDC from
                currUdcFrom = barcodeIn;
                currCss = "stileAttesa";
                // resetto warnings 
                needForza_NoPosVLP = false;
                needForzaCons_inLDP = false;
                // controllo: se sono in fast mode SCARICO!
                if (disableConfirm)
                {
                  scaricaUdcFrom(true);
                }
              }
              break;
            case tipoCodiceBarcode.Comando:
              // se richiesto scarico rapido lo gestisco
              if (barcodeIn.ToUpper() == memLayer.ML.cdv("cmdFast").ToUpper())
              {
                disableConfirm = !disableConfirm;
                currMess = traduci("enDisFastMode");
              }
              break;
            default:
              currMess += " - codice <b>non riconosciuto</b>!";
              currCss = "stileComandoND";
              break;
          }
          lastBCodeIn = barcodeIn;
        }
        barcodeIn = "";
        // sovrascrivo il PREV...
        pPOS = cPOS;
      }
      else
      {
        currMess = traduci("AttesaBCode");
        if (string.IsNullOrEmpty(currUdcFrom))
        {
          currCss = "stileAttesa";
        }
      }
      txtBarcode.Focus();
    }
    /// <summary>
    /// controllo abilitazione consumo
    /// </summary>
    private void checkConsuma()
    {
      bool consumaOk = false;
      if (!disableConfirm)
      {
        if (currUdcFrom != "")
        {
          consumaOk = true;
          // controllo se sia GIA' consumato
          if (MagClass.magazzino.checkUDC(currUdcFrom) && consumaOk)
          {
            consumaOk = MagClass.magazzino.udcMpIsConsumabile(currUdcFrom);
          }
        }
      }
      btnConsuma.Enabled = consumaOk;
      btnConsuma.CssClass = "btn btn-default";
      if (!consumaOk)
      {
        btnConsuma.CssClass += " disabled";
      }
    }

    /// <summary>
    /// Controlla UDC x fix visualizzazione
    /// </summary>
    private void checkUDC()
    {
      if (!vetoUpdate)
      {
        if (currUdcFrom != "")
        {
          // se già consumato LO INDICO...
          if (MagClass.magazzino.checkUDC(currUdcFrom))
          {
            bool isConsumabile = MagClass.magazzino.udcMpIsConsumabile(currUdcFrom);
            if (!isConsumabile)
            {
              currMess = "<br/>" + traduci("erroreUdcConsumato");
              currCss = "stileComandoKo";
              // sovrascrivo il PREV...
              pPOS = cPOS;
            }
          }
        }
      }
    }

    #endregion

    #region azioni

    /// <summary>
    /// consuma UDC
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnConsuma_Click(object sender, EventArgs e)
    {
      scaricaUdcFrom(false);
    }
    /// <summary>
    /// consuma UDC anche se non è in posizione LPA010101
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnForzaCons_NoPosVLP_Click(object sender, EventArgs e)
    {
      scaricaUdcFrom(true);
    }
    /// <summary>
    /// consuma UDC anche se in LDP
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnForzaCons_inLDP_Click(object sender, EventArgs e)
    {
      scaricaUdcFrom(true);
    }
    /// <summary>
    /// effettua scaricamento UDC FROM
    /// </summary>
    /// <param name="forzaOperazione">true/false se forzare operazione anche se 
    /// - NON in posizione LPA010101
    /// - non già presente in LDP (nel qual caso lo toglie)
    /// perché vogliamo che sia prima in posizione nota (quindi prima spostamento in LP a mano e poi scaricamento)</param>
    private void scaricaUdcFrom(bool forzaOperazione)
    {
      if (currUdcFrom != "" && !vetoUpdate)
      {
        // controllo se UDC non sia già consumato...
        if (MagClass.magazzino.udcMpIsConsumabile(currUdcFrom))
        {
          // controllo UDC sia corretto (in giusta posizione...)
          if (MagClass.magazzino.IdxPosizioneUdc(currUdcFrom) == memLayer.ML.cdvi("IdxPosizioneAnime"))
          {
            // 2015.01.08: modifica x gestione con stored esterna di controllo...
            //if (MagClass.magazzino.codCellaUdc(currUdcFrom) == memLayer.ML.confReadString("cellaLPA") || MagClass.magazzino.codCellaUdc(currUdcFrom) == memLayer.ML.confReadString("cellaLPX") || forzaOperazione)

            // controllo UDC sia in posizione LDP anime LPA010101...
            if (MagClass.magazzino.checkUdc_OkLPAX(currUdcFrom) || forzaOperazione)
            {
              // controllo che non sia già in una LDP
              if (!MagClass.magazzino.udcInLdp(currUdcFrom) || forzaOperazione)
              {
                // indico UDC consumato!
                lastMess = string.Format("{0} {1}", traduci("effettuatoConsumoUDC"), currUdcFrom);
                needForzaCons_inLDP = false;
                needForza_NoPosVLP = false;
              }
              else
              {
                // è già in una LDP: mostro button x forzare...
                lastMess = "------------ ESITO OPERAZIONE ------------</br>";
                lastMess += string.Format("{0} {1}</br>", traduci("UDC_impegnatoLDP"), currUdcFrom);
                lastMess += "-----------------------------------------</br>";
              }
            }
            else
            {
              // non è in posizione LPA: mostro button x forzare...                 
              lastMess = "------------ ESITO OPERAZIONE ------------</br>";
              lastMess += string.Format("{0} {1}</br>", traduci("UDC_nonPrel"), currUdcFrom);
              lastMess += "-----------------------------------------</br>";
            }
            // ora consumo DAVVERO UDC
            MagClass.magazzino.scaricaUdcMpWip(currUdcFrom, Request.UserHostName);
            currCss = "stileComandoOk";
            currMess = lastMess;
            vetoUpdate = true;
            lastCheck = DateTime.Now;
            // se richiesto (era in LDP)
            if (needForzaCons_inLDP)
            {
              // elimino part da altre LDP
              MagClass.magazzino.taRigheListePrelievo.eliminaByUdc(currUdcFrom);
            }
          }
          else
          {
            // indico UDC sbagliato!
            lastMess = string.Format("{0} {1}", traduci("UDC_posizErrataAnime"), currUdcFrom);
            currCss = "stileComandoKo";
          }
        }
        else
        {
          // indico UDC consumato!
          lastMess = string.Format("{0} {1}", traduci("UDC_giaConsumato"), currUdcFrom);
          currCss = "stileComandoKo";
        }
        // recupero lastmMess
        currMess = lastMess;
        // salvo valore presente e corrente...
        pPOS = cPOS;
      }
      updateVisual();
    }

    #endregion

    /// <summary>
    /// decodifica il tipo barcode acquisito
    /// </summary>
    public tipoCodiceBarcode tipoBCode
    {
      get
      {
        tipoCodiceBarcode answ = tipoCodiceBarcode.ND;
        int trovati = 0;
        // controllo non si tratti di un comando...
        string preCmd = memLayer.ML.AppConf["prefComandi"];
        if (barcodeIn.StartsWith(preCmd))
        {
          answ = tipoCodiceBarcode.Comando;
        }
        // controllo se sia un particolare
        else if (TermClass.Ter.riconosciBarcode(barcodeIn) == tipoCodiceBarcode.Particolare && TermClass.Ter.isAnima(barcodeIn)) // è un particolare...
        {
          answ = tipoCodiceBarcode.Particolare;
        }
        else
        {
          try
          {
            // cerco tra gitterbox (UDC)...
            trovati = MagClass.magazzino.taCartellini.getByUdc(barcodeIn).Rows.Count;
            if (trovati > 0)
            {
              answ = tipoCodiceBarcode.UDC;
            }
          }
          catch
          {
          }
        }
        return answ;
      }
    }
    /// <summary>
    /// valore barcode
    /// </summary>
    public string barcodeIn
    {
      get
      {
        return txtBarcode.Text.Trim();
      }
      set
      {
        txtBarcode.Text = value;
      }
    }

    /// <summary>
    /// cambia la modalità di scarico UDC dis/abilitando conferme
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnDisableConf_Click(object sender, EventArgs e)
    {
      disableConfirm = !disableConfirm;
    }

  }
}