using GMW_data;
using SteamWare;
using System;
using System.Web.UI.WebControls;

namespace GMW.WebUserControls
{
    public partial class mod_dettCelleBlocco : System.Web.UI.UserControl
    {
        protected int IdxBlocco = 0;
        protected int IdxCella = 0;
        protected int CodMagLogico = -1;
        protected int numX = 1;
        protected int numY = 1;
        protected GMW_data.Type.BlockMap[,] BloccoCelle;

        public event EventHandler eh_selValore;
        /// <summary>
        /// evento caricamento pagina...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            doUpdate();
        }
        /// <summary>
        /// esegue update controllo
        /// </summary>
        public void doUpdate()
        {
            caricaDatiBlocco();
            aggiornaCelleOccupate();
            creaLabelTooltipCelle();
            disegnaTabella();
        }
        /// <summary>
        /// effettua reset dati selezionati
        /// </summary>
        public void reset()
        {
            memLayer.ML.emptySessionVal("IdxCellaMag");
        }

        /// <summary>
        /// carica i dati del blocco in un oggetto BlockMap (compreso attive/inattive)
        /// </summary>
        private void caricaDatiBlocco()
        {
            // carico da session blocco e cella (eventualmente)
            IdxBlocco = memLayer.ML.IntSessionObj("IdxBlocco_sel");
            IdxCella = memLayer.ML.IntSessionObj("IdxCellaMag");
            // controllo: se mancano dati rimando a StatoMag.aspx
            if ((IdxBlocco == 0) || (IdxCella == 0))
            {
                Response.Redirect("~/StatoMag.aspx");
            }
            // calcolo di quante righe e colonne ho bisogno...
            DS_magazzino.BlocchiRow rigaBlocco = MagClass.magazzino.taBlocchi.getByIdx(IdxBlocco)[0];
            numX = rigaBlocco.NumX;
            numY = rigaBlocco.NumY;
            // carico TUTTE le celle del blocco...
            DS_magazzino.CelleDataTable tabCelleAll = MagClass.magazzino.taCelle.getByIdxBlocco(IdxBlocco);
            DS_magazzino.CelleRow rigaCelle;
            // carico i tipi cella...
            DS_magazzino.TipoCellaDataTable tabTipoCelle = MagClass.magazzino.taTipoCella.GetData();
            // inizializzo il mio array...
            BloccoCelle = new GMW_data.Type.BlockMap[numX, numY];
            // per calcolo capacità di OGNI cella
            int capa = 0;
            // carico i dati nell'array: di default tutto VUOTO, con posizione attiva...
            string currCss = "";
            for (int pos_y = 0; pos_y < numY; pos_y++)
            {
                for (int pos_x = 0; pos_x < numX; pos_x++)
                {
                    // calcolo la capacità della cella...
                    rigaCelle = (DS_magazzino.CelleRow)tabCelleAll.Select(string.Format("X={0} AND Y={1}", pos_x + 1, pos_y + 1))[0];
                    capa = tabTipoCelle.FindByIdxTipoCella(rigaCelle.IdxTipoCella).Capienza;
                    // 2015.01.29 controllo se sia piena o libera...                    
                    currCss = "cellaLibera";
                    try
                    {
                        if (rigaCelle.Piena)
                        {
                            currCss = "cellaPiena";
                        }
                    }
                    catch
                    { }
                    BloccoCelle[pos_x, pos_y] = new GMW_data.Type.BlockMap("-", "", currCss, rigaCelle.IdxCella, rigaCelle.CodCella, capa, 0, rigaCelle.Piena, rigaCelle.Attiva);
                }
            }
        }
        /// <summary>
        /// Aggiorna la mappa con le celle occupate
        /// </summary>
        private void aggiornaCelleOccupate()
        {
            // carico il magazzino logico da visualizzare (oppure tutti...)
            CodMagLogico = memLayer.ML.IntSessionObj("CodMagLogico_sel");
            // carico altri dati da sessione
            string ParticolareSel = memLayer.ML.StringSessionObj("Particolare_sel");
            string DescStatoSel = memLayer.ML.StringSessionObj("DescStato_sel");
            string EsponenteSel = memLayer.ML.StringSessionObj("Esponente_sel");
            // ottengo elenco dettaglio UDC che occupano il blocco...
            DS_magazzino.v_UdcDetailDataTable tabUdc = MagClass.magazzino.taDettUDC.getUdcDetailByIdxBlocco(IdxBlocco);
            // SE è filtrato x mag logico utilizza altro metodo...
            if (CodMagLogico != -1)
            {
                tabUdc = MagClass.magazzino.taDettUDC.getByIdxBloccoCodMagLog(IdxBlocco, CodMagLogico);
            }
            // controllo se sia un magazzino mono o multicella...
            bool multicella = MagClass.magazzino.taCelle.getByIdxBlocco(IdxBlocco).Rows.Count > 1;
            // contatore: inserisco solo primi 20 UDC...
            int maxUdc = 20;
            // SE ci sono righe aggiorno il blocco...
            if (tabUdc.Rows.Count > 0)
            {
                // ...sovrascrivo valori di default
                foreach (DS_magazzino.v_UdcDetailRow riga in tabUdc)
                {
                    // salvo che ho 1 UDC in + nella cella...
                    BloccoCelle[riga.X - 1, riga.Y - 1].NumUdc++;
                    // controllo se nella cella ci sia il particolare selezionato...
                    if (ParticolareSel == riga.Particolare && multicella)
                    {
                        // controllo se sia anche lo specifico esponente/stato
                        if (DescStatoSel == riga.DescStato && EsponenteSel == riga.Esponente)
                        {
                            BloccoCelle[riga.X - 1, riga.Y - 1].Css = "cellaSelezDett";
                        }
                        else
                        {
                            BloccoCelle[riga.X - 1, riga.Y - 1].Css = "cellaSelezAll";
                        }
                    }
                    else
                    {
                        // se NON C'E' alcun particolare selezionato ... controllo il blocco!
                        if (BloccoCelle[riga.X - 1, riga.Y - 1].Piena)
                        {
                            BloccoCelle[riga.X - 1, riga.Y - 1].Css = "cellaPiena";
                        }
                        else
                        {
                            BloccoCelle[riga.X - 1, riga.Y - 1].Css = "cellaOccupata";
                        }
                    }
                    if (maxUdc > 0)
                    {
                        BloccoCelle[riga.X - 1, riga.Y - 1].ToolTip += string.Format("{2} - {0} {1:#}pz{3}", riga.UDC, riga.Qta, riga.Particolare, Environment.NewLine);
                        maxUdc--;
                        if (maxUdc == 0)
                        {
                            BloccoCelle[riga.X - 1, riga.Y - 1].ToolTip += "...more...";
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Aggiorna la mappa celle x label e tooltip
        /// </summary>
        private void creaLabelTooltipCelle()
        {
            // ...in base al setup mostro anche il disponibile o meno...
            string formato = "";
            if (memLayer.ML.confReadBool("showSizeCellaInDettMag"))
            {
                formato = "<b>{0}</b><br/>{1}";
            }
            else
            {
                formato = "<b>{0}</b>";
            }
            // faccio ciclo x ogni oggetto blocco..
            for (int pos_y = 0; pos_y < numY; pos_y++)
            {
                for (int pos_x = 0; pos_x < numX; pos_x++)
                {
                    // calcolo la capacità della cella... e mostro secondo formato definito prima                    
                    BloccoCelle[pos_x, pos_y].Label = string.Format(formato, BloccoCelle[pos_x, pos_y].NumUdc, BloccoCelle[pos_x, pos_y].Capacita);
                    // se è attiva = 0 aggiorno label
                    if (!BloccoCelle[pos_x, pos_y].Attiva)
                    {
                        BloccoCelle[pos_x, pos_y].Css = "cellaInattiva";
                        //BloccoCelle[pos_x, pos_y].Label = string.Format("[{0}]", BloccoCelle[pos_x, pos_y].Label);
                        // ... e tooltip
                        BloccoCelle[pos_x, pos_y].ToolTip = string.Format("{0}{1}{2}", traduci("CellaInattiva"), Environment.NewLine, BloccoCelle[pos_x, pos_y].ToolTip);
                    }
                }
            }
        }
        /// <summary>
        /// wrapper traduzione
        /// </summary>
        /// <param name="lemma"></param>
        /// <returns></returns>
        public string traduci(object lemma)
        {
            return user_std.UtSn.Traduci(lemma.ToString());
        }

        /// <summary>
        /// esegue il vero plotting della tabella
        /// </summary>
        private void disegnaTabella()
        {
            bool tabPresente = tblBlocco.Rows.Count > 0;
            if (tabPresente)
            {
                //foreach (TableRow riga in tblBlocco.Rows)
                //{
                //    foreach (TableCell cella in riga.Cells)
                //    {
                //        foreach (LinkButton lnkb in cella.Controls)
                //        {
                //            lnkb.Click -= new EventHandler(lnkb_Click);
                //        }
                //    }
                //}
                tblBlocco.Rows.Clear();
            }
            // metto prima riga con indicazione valori NUMERICI delle colonne
            setupRigaConteggioX();
            // ciclo nel mio array e creo di conseguenza le celle di tabella
            for (int pos_y = numY - 1; pos_y >= 0; pos_y--)
            {
                TableRow riga = new TableRow();
                TableCell cell;
                // cella con numero livello
                cell = setupCellaConteggioY(pos_y, riga);
                for (int pos_x = 0; pos_x < numX; pos_x++)
                {
                    cell = new TableCell();
                    cell.CssClass = BloccoCelle[pos_x, pos_y].Css;
                    // aggiungo button x fare elemento cliccabile
                    LinkButton lnkb = new LinkButton();
                    lnkb.ToolTip = BloccoCelle[pos_x, pos_y].ToolTip;
                    lnkb.Text = BloccoCelle[pos_x, pos_y].Label;
                    lnkb.Click += new EventHandler(lnkb_Click);
                    lnkb.CommandArgument = string.Format("{0}#{1}", BloccoCelle[pos_x, pos_y].KeyVal, BloccoCelle[pos_x, pos_y].CellCode);
                    // controllo se la cella è selezionata, nel caso BOLD!
                    if (BloccoCelle[pos_x, pos_y].KeyVal == IdxCella)
                    {
                        cell.CssClass = "selectedCell";
                        btnReset.Visible = true;
                    }
                    cell.Controls.Add(lnkb);
                    // carico in cella di tabella il linkButton
                    riga.Cells.Add(cell);
                }
                cell = setupCellaConteggioY(pos_y, riga);
                tblBlocco.Rows.Add(riga);
            }
            // metto ultima riga con indicazione valori NUMERICI delle colonne
            setupRigaConteggioX();
        }
        /// <summary>
        /// intercetta richiesta di zoom e zoomma sull'Udc in esame...
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void lnkb_Click(object sender, EventArgs e)
        {
            LinkButton lnk = (LinkButton)sender;
            // calcolo i parametri passati
            string[] valori = SteamWare.StringSplitter.CSplitter.Split(lnk.CommandArgument.ToString(), "#", true, 2, SteamWare.StringSplitter.ComparisonMethod.Text);
            // setto i valori in sessione
            IdxCella = Convert.ToInt32(valori[0]);
            memLayer.ML.setSessionVal("IdxCellaMag", valori[0], false);
            memLayer.ML.setSessionVal("CodCellaMag", valori[1], false);

            // evento selezione che passa dati al modulo operazioniUdc
            if (eh_selValore != null)
            {
                eh_selValore(this, new EventArgs());
            }
            Response.Redirect("~/DettaglioBlocco.aspx");
        }
        /// <summary>
        /// crea una cella per il numero dei livelli
        /// </summary>
        /// <param name="pos_y"></param>
        /// <param name="riga"></param>
        /// <returns></returns>
        private static TableCell setupCellaConteggioY(int pos_y, TableRow riga)
        {
            TableCell cell;
            cell = new TableCell();
            cell.CssClass = "cellaBianca";
            cell.Text = string.Format("{0:0#}", pos_y + 1);
            cell.ToolTip = "";
            riga.Cells.Add(cell);
            return cell;
        }
        /// <summary>
        /// crea la riga del numero delle colonne
        /// </summary>
        private void setupRigaConteggioX()
        {
            TableRow riga = new TableRow();
            TableCell cell;
            // cella vuota iniziale
            cell = new TableCell();
            riga.Cells.Add(cell);
            // celle con numeri
            for (int pos_x = 0; pos_x < numX; pos_x++)
            {
                cell = new TableCell();
                cell.CssClass = "cellaBianca";
                cell.Text = string.Format("{0:0#}", pos_x + 1);
                cell.ToolTip = "";
                riga.Cells.Add(cell);
            }
            // cella vuota finale
            cell = new TableCell();
            riga.Cells.Add(cell);
            // aggiungo riga!
            tblBlocco.Rows.Add(riga);
        }
        /// <summary>
        /// resetta disegno
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnReset_Click(object sender, EventArgs e)
        {
            memLayer.ML.emptySessionVal("IdxCellaMag");
            memLayer.ML.emptySessionVal("CodCellaMag");
            Response.Redirect("~/DettaglioBlocco.aspx");
        }

    }
}