protected void gvDatos_SelectedIndexChanged(object sender, EventArgs e)
    {
        InicializarControles();

        GridViewRow row = gvDatos.SelectedRow;
        HfAccion.Value = "EDIT";
        HfnCod_Entidad.Value = Server.HtmlDecode(row.Cells[1].Text.Trim());
        this.txtNombre.Text = Server.HtmlDecode(row.Cells[2].Text.Trim());
        this.txtDescripcion.Text = Server.HtmlDecode(row.Cells[3].Text.Trim());
        this.chkHab.Checked = ((CheckBox)row.FindControl("chkHabGrilla")).Checked;

        //Paso los atributos a la lista
        DataTable oTabla = TuCuento.Negocio.Entidad_NEG.TraerAtributos(Convert.ToInt32(HfnCod_Entidad.Value), -1, -1);

        foreach (DataRow fila in oTabla.Rows)
        {
            TuCuento.Entidades.EntidadAtributo oAtributo = new TuCuento.Entidades.EntidadAtributo();
            oAtributo.TipoEntidad = new TuCuento.Entidades.Entidad();
            oAtributo.nCod_Entidad = Convert.ToInt32(fila["nCod_Entidad"]);
            oAtributo.nCod_Atributo = Convert.ToInt32(fila["nCod_Atributo"]);
            oAtributo.sNombre = fila["sNombre"].ToString();
            oAtributo.sDescripcion = fila["sDescripcion"].ToString();
            oAtributo.nHab = Convert.ToInt32(fila["nHab"]);
            oAtributo.nCod_TipoAtributo = Convert.ToInt32(fila["nCod_TipoAtributo"]);
            oAtributo.TipoEntidad.nCod_Entidad = Convert.ToInt32(fila["nCod_EntidadTipo"]);
            oAtributo.TipoEntidad.sNombre = fila["sNombreEntidad"].ToString();
            lstAtributos.Add(oAtributo);
        }

        gvAtributos.DataSource = lstAtributos;
        gvAtributos.DataBind();
        
        HabDesCtrl(true);
        txtNombre.Focus();
    }
    protected void btnAgregar_Click(object sender, EventArgs e)
    {
        //Valido los datos ingresados
        if (ValidarDatosAtributo())
        {
            if (HfAccionAttr.Value == "EDIT")
            {
                //Lo busco en la lista y lo modifico
                foreach (TuCuento.Entidades.EntidadAtributo oAtributo in lstAtributos)
                {
                    if (oAtributo.nCod_Atributo == Convert.ToInt32(HfnCod_Atributo.Value))
                    {
                        oAtributo.sNombre = txtAttrNombre.Text.Trim();
                        oAtributo.sDescripcion = txtAttrDescripcion.Text.Trim();
                        oAtributo.nCod_TipoAtributo = Convert.ToInt32(ddlTipoAtributo.SelectedValue);

                        if ((Funciones.TipoDato)Convert.ToInt32(this.ddlTipoAtributo.SelectedValue) == Funciones.TipoDato.Entidad)
                        {
                            oAtributo.TipoEntidad.nCod_Entidad = Convert.ToInt32(ddlEntidad.SelectedValue);
                            oAtributo.TipoEntidad.sNombre = ddlEntidad.SelectedItem.Text;
                        }
                        else
                        {
                            oAtributo.TipoEntidad.nCod_Entidad = 0;
                            oAtributo.TipoEntidad.sNombre = null;
                        }

                        oAtributo.nHab = (chkAttrHab.Checked ? 1 : 0);

                        break;
                    }
                }
            }
            else
            {
                TuCuento.Entidades.EntidadAtributo oAtributo = new TuCuento.Entidades.EntidadAtributo();
                TuCuento.Entidades.Entidad oEntidad = new TuCuento.Entidades.Entidad();

                int nCod_Atributo = lstAtributos.Count;

                nCod_Atributo++;

                oAtributo.nCod_Atributo = nCod_Atributo;
                oAtributo.sNombre = txtAttrNombre.Text.Trim();
                oAtributo.sDescripcion = txtAttrDescripcion.Text.Trim();
                oAtributo.nCod_TipoAtributo = Convert.ToInt32(ddlTipoAtributo.SelectedValue);

                if (ddlTipoAtributo.SelectedValue == "1")
                {
                    oEntidad.nCod_Entidad = Convert.ToInt32(ddlEntidad.SelectedValue);
                    oEntidad.sNombre = ddlEntidad.SelectedItem.Text;
                }

                oAtributo.TipoEntidad = oEntidad;

                oAtributo.nHab = (chkAttrHab.Checked ? 1 : 0);

                //Lo agrego a la grilla
                lstAtributos.Add(oAtributo);

            }
            
            gvAtributos.DataSource = lstAtributos;
            gvAtributos.DataBind();

            BlanquearControlesAtributos();
            txtAttrNombre.Focus();
        }
    }
    private void CargarListaDetalle(int nCod_Historia)
    {
        DataTable oTabla = TuCuento.Negocio.HistoriaDetalle_NEG.ListarDetalleHistoria(nCod_Historia);
        List<TuCuento.Entidades.EntidadAtributo> lstEntidadNoMostrar = new List<TuCuento.Entidades.EntidadAtributo>();
        
        foreach (DataRow oFila in oTabla.Rows)
        {
            TuCuento.Entidades.HistoriaDetalle oDetalle = new TuCuento.Entidades.HistoriaDetalle();

            oDetalle.nCod_Historia = Convert.ToInt32(oFila["nCod_Historia"].ToString());
            oDetalle.nCod_TipoHistoriaDetalle = Convert.ToInt32(oFila["nCod_TipoHistoriaDetalle"].ToString());
            oDetalle.nOrden = Convert.ToInt32(oFila["nOrden"].ToString());

            Funciones.TipoHistoriaDetalle oTipo = (Funciones.TipoHistoriaDetalle)oDetalle.nCod_TipoHistoriaDetalle;

            if (Funciones.TipoHistoriaDetalle.Texto == oTipo)
            {
                DataTable oTexto = TuCuento.Negocio.HistoriaDetalle_NEG.TraerTexto(oDetalle.nCod_Historia, oDetalle.nOrden);

                oDetalle.Texto.sTexto = oTexto.Rows[0]["sTexto"].ToString();

            }
            else
            {
                TuCuento.Entidades.HistoriaDetInf oInferencia = new TuCuento.Entidades.HistoriaDetInf();
                //Traigo las condiciones
                DataTable oTablaInferencia = TuCuento.Negocio.HistoriaDetalle_NEG.TraerCondiciones(nCod_Historia, oDetalle.nOrden);

                foreach (DataRow oFilaInf in oTablaInferencia.Rows)
                {
                    TuCuento.Entidades.Condicion oCondicion = new TuCuento.Entidades.Condicion();
                    TuCuento.Entidades.CondicionValPosible oValPosible = new TuCuento.Entidades.CondicionValPosible();

                    oCondicion.nCod_Condicion = Convert.ToInt32(oFilaInf["nCod_Condicion"].ToString());
                    oCondicion.nCod_Entidad = Convert.ToInt32(oFilaInf["nCod_Entidad"].ToString());
                    oCondicion.nCod_Atributo = Convert.ToInt32(oFilaInf["nCod_Atributo"].ToString());

                    bool bEstaValPosible = false;
                    bool bEstaEntidadAtributo = false;

                    foreach (Inferencia oDato in lstInferencia)
                    {
                        if (oDato.nCod_Entidad == oCondicion.nCod_Entidad && oDato.nCod_Atributo == oCondicion.nCod_Atributo)
                        {
                            bEstaEntidadAtributo = true;
                            foreach (ValPosible oDatoVal in oDato.lstValPosible)
                            {
                                if (oDatoVal.nCod_ValPosible == Convert.ToInt32(oFilaInf["nCod_ValPosible"].ToString()))
                                {
                                    bEstaValPosible = true;
                                    break;
                                }
                            }
                            if (!bEstaValPosible)
                            {
                                ValPosible oCValPos = new ValPosible();
                                oCValPos.nCod_ValPosible = Convert.ToInt32(oFilaInf["nCod_ValPosible"].ToString());
                                oCValPos.sOperadorLogico = oFilaInf["sOperadorLogico"].ToString();
                                oCValPos.sValor = oFilaInf["sValor"].ToString();

                                if (oDato.lstValPosible == null)
                                {
                                    List<ValPosible> oValPos = new List<ValPosible>();
                                    oValPos.Add(oCValPos);
                                    oDato.lstValPosible = oValPos;
                                }
                                else
                                {
                                    oDato.lstValPosible.Add(oCValPos);
                                }
                                
                            }
                        }
                        if (bEstaEntidadAtributo)
                            break;
                    }

                    
                    if (!bEstaEntidadAtributo)
                    {
                        Inferencia oInf = new Inferencia(oCondicion.nCod_Entidad, oCondicion.nCod_Atributo, oFilaInf["sAtributo"].ToString());
                        List<ValPosible> oValPos = new List<ValPosible>();

                        ValPosible oCValPos = new ValPosible();
                        oCValPos.nCod_ValPosible = Convert.ToInt32(oFilaInf["nCod_ValPosible"].ToString());
                        oCValPos.sOperadorLogico = oFilaInf["sOperadorLogico"].ToString();
                        oCValPos.sValor = oFilaInf["sValor"].ToString();
                        oValPos.Add(oCValPos);
                        oInf.lstValPosible = oValPos;

                        lstInferencia.Add(oInf);
                    }
                                    
                    oValPosible.nCod_ValPosible = Convert.ToInt32(oFilaInf["nCod_ValPosible"].ToString());
                    oValPosible.sOperadorLogico = oFilaInf["sOperadorLogico"].ToString();
                    oValPosible.sValor = oFilaInf["sValor"].ToString();

                    oCondicion.lstValPosible = new List<TuCuento.Entidades.CondicionValPosible>();
                    oCondicion.lstValPosible.Add(oValPosible);

                    oInferencia.Condiciones.Add(oCondicion);
                }

                //Traigo las acciones
                oTablaInferencia = TuCuento.Negocio.HistoriaDetalle_NEG.TraerAccion(nCod_Historia, oDetalle.nOrden);

                foreach (DataRow oFilaInf in oTablaInferencia.Rows)
                {
                    TuCuento.Entidades.Accion oAccion = new TuCuento.Entidades.Accion();
                    oAccion.nCod_Accion = Convert.ToInt32(oFilaInf["nCod_Accion"].ToString());
                    oAccion.nCod_TipoAccion = Convert.ToInt32(oFilaInf["nCod_TipoAccion"].ToString());

                    //Si modifica un hecho busco cual es el hecho y lo agrego a la lista de hechos que no tengo que mostrar
                    if ((Funciones.TipoAccion)oAccion.nCod_TipoAccion == Funciones.TipoAccion.ModHecho)
                    {
                        DataTable oAccionModHecho = TuCuento.Negocio.Accion_NEG.ListarAcciones(oAccion.nCod_Accion, -1, -1);

                        TuCuento.Entidades.EntidadAtributo oEntAtrr = new TuCuento.Entidades.EntidadAtributo();
                        oEntAtrr.nCod_Entidad = Convert.ToInt32(oAccionModHecho.Rows[0]["nCod_Entidad"].ToString());
                        oEntAtrr.nCod_Atributo = Convert.ToInt32(oAccionModHecho.Rows[0]["nCod_Atributo"].ToString());

                        lstEntidadNoMostrar.Add(oEntAtrr);
                    }
                    else
                    {
                        oAccion.Historia = new TuCuento.Entidades.AccionHistoria();
                        oAccion.Historia.nCod_Historia = Convert.ToInt32(oFilaInf["nCod_HistoriaAccion"].ToString());
                    }

                    oInferencia.Accion.Add(oAccion);
                }

                oDetalle.Inferencia = oInferencia;

            }

            lstDetalleHistoria.Add(oDetalle);
        }

        //Quito las entidades y atributos que van a ser inferidos
        foreach (TuCuento.Entidades.EntidadAtributo oEnt in lstEntidadNoMostrar) 
        {
            foreach (Inferencia oInf in lstInferencia)
            {
                if (oEnt.nCod_Entidad == oInf.nCod_Entidad && oEnt.nCod_Atributo == oInf.nCod_Atributo)
                {
                    lstInferencia.Remove(oInf);
                    break;
                }
            }
        }

    }