unit uEditarFuenteSintetizador;

  {$MODE Delphi}
{$DEFINE  MODELO_ENTRADA_SALIDA}

interface

uses
  {$IFDEF WINDOWS}
  Windows,
  {$ELSE}
  LCLType,
  {$ENDIF}
  SysUtils, Classes,
  Graphics,
  utrazosxy,
  Controls, Forms,
  Dialogs, StdCtrls, Grids,
  uBaseEditores,
  uBaseEditoresCosasConNombre,
  uCosaConNombre,
  usalasdejuego, ucosa,
  uFuenteSintetizador,
  umodelosintcegh,
  uEsclavizador,
  uBaseFormularios,
  uverdoc, uconstantesSimSEE, utilidades, xMatDefs, uAuxiliares,
  uDatosHistoricos, uFechas,
  ComCtrls, ExtCtrls,
  uvisordetabla,
  Clipbrd, Menus, Buttons, upronostico,
  ugeturlinfo,
  Math,
  ucalibrarconopronosticos, uUtilFormulario,
  uFuentesAleatorias,
  uBaseEditoresFuentesConFichas;

resourcestring
  rsBorne = 'Borne';
  rsValores = 'Valores';
  rsFechaDeInicio = 'Fecha de Inicio';
  rsInformacioNAdicional = 'Información adicional';
  rsPeriodicaQ = 'Periodica?';
  rsNoDisponible = 'No disponible';
  mesSeleccionarArchivoAntesAgregarFichasFuente =
    'Debe seleccionar un archivo de datos antes de agregar fichas a la fuente';
  mesConfirmaEliminarFicha = '¿Confirma que desea eliminar la ficha seleccionada?';
  mesConfirmarEliminacion = 'Confirmar eliminación';
  rsSubMuestreada = 'Sub-muestreada';
  rsSobreMuestreada = 'Sobre-muestreada';
  rsSinEsclavizar = 'Sin Esclavizar';
  exDeterminismoInvalido = 'El formato del determinismo ingresado no es valido';
  msFormatoInvalido = 'Formato invalido';
  mesNumeroValorEsperado = 'El valor esperado debe ser un número entre 1 y 100';
  mesCalibCamposNoNumericos =
    'Los campos del calibrador deben ser valores numericos positivos mayores a 0';
  mesSesgosCamposNoNumericos =
    'Los campos del generador de sesgos deben ser valores numericos positivos.';
  mesFaltaElegirFuente = 'Debe seleccionar todas las fuentes de entrada y sus bornes';
  rs_Error_StrToInt = 'Error de conversión a entero.';

  rs_P = 'Probabilidad asignada a la guia.';
  rs_NPCC = 'Número de Pasos de Control de Cono.';
  rs_NPLC = 'Número de Pasos de Liberación del Cono.';
  rs_NPSA = 'Número de Pasos Sin Apertura del cono.';
  rs_NPAC = 'Número de Pasos de Apertura del Cono.';
  rs_ve = 'La guía es en valor esperado.';
  rs_pe = 'Probabilidad de Excedencia de la guía si no es en valor esperado.';
  rs_aipu = 'Apertura inicial del cono en por unidad de la varianza histórica.';
  rs_FechaIniCono = 'Fecha inicial del cono.';
  rs_fIN = 'Fuente de entrada';
  rs_Borne = 'Borne';

type

  { TEditorTablaconEditores }

  TEditorTablaconEditores = class(TBaseEditores)
    //Esta clase es necesaria para poder acceder a
    //las funciones que se usan dsp en el editor de la clase
    //TTablaconEditores

    constructor Create(AOwner: TComponent; cosaEditable: TCosa; xsala: TSalaDeJuego);

  end;

  { TComboBoxEnTabla }

  TComboBoxEnTabla = class(TComboBox)
  public
    fila: integer;

    constructor Create(TheOwner: TComponent; filaCB: integer);

  end;


  { TTablaconEditores }

  TTablaconEditores = class(TTabla)
    editor: TEditorTablaconEditores;
    cellFuente, cellBorne: TCelda;
    //    CBFuente, CBBorne: TComboBoxEnTabla;

    procedure wrComboBoxFuente(idFuente, idBorne: string;
      kfilaFuente, kcolumnaFuente, kfilaBorne, kcolumnaBorne, ancho: integer);
    function readCB(id: string; kfila, kcolumna: integer): TComboBox;
    function darValorCBFuente(idFuente: string;
      kfilaFuente, kcolumnaFuente: integer): TFuenteAleatoria;
    function darValorCBBorne(idBorne: string;
      kfilaBorne, kcolumnaBorne: integer): string;

    procedure SetValorCBFuente(idFuente, idBorne: string;
      kfilaFuente, kcolumnaFuente, kfilaBorne, kcolumnaBorne: integer;
      fuenteAleatoria: TFuenteAleatoria; borne: string);
    procedure SetValorCBBorne(idBorne: string; kfilaBorne, kcolumnaBorne: integer;
      borne: string);
    procedure wrComboBoxFuente_OnChange(Sender: TObject);
    procedure wrComboBoxBorne_OnChange(Sender: TObject);

    constructor Create(AOwner: TComponent; Name: string;
      cellpadding, cellsparcing, anchoborde: integer; sala: TSalaDeJuego);

  end;



  { TEditarFuenteSintetizador }

  TEditarFuenteSintetizador = class(TBaseEditoresCosasConNombre)


    BAyuda: TButton;
    BAyudaDurPasoSorteo: TButton;
    BAyudaDurPasoTiempo: TButton;
    BCancelar: TButton;
    BGuardar: TButton;
    btGetPronosticos: TButton;
    btGraficarPronosticos: TButton;
    btExportar: TButton;
    btImportar: TButton;
    btAyudaExportarImportar: TButton;
    cbArchiRef: TComboBox;
    cbArchiRef_DatHisto: TComboBox;
    cbArchiRef_ModAux: TComboBox;
    cbEditarParametrosDelCono: TCheckBox;
    btAyudaEditarParametrosDelCono: TButton;
    cbEscenarioSelecctionado: TComboBox;
    cbResumirPromediando: TCheckBox;
    cbSimularUsandoDatosHistoricos: TCheckBox;
    cbUsarModeloAuxiliarParaOpt: TCheckBox;
    cbSincronizarConHistoricos: TCheckBox;
    cbSincronizarConSemillaAleatoria: TCheckBox;
    eNPasosPlot: TEdit;
    eProbabilidad: TEdit;
    eDurPasoSorteo: TEdit;
    eDurPasoTiempo: TEdit;
    ENombre: TEdit;
    eTipoDeEsclavizacion: TEdit;
    eurl_get: TEdit;
    GroupBox1: TGroupBox;
    GroupBox2: TGroupBox;
    GroupBox3: TGroupBox;
    GroupBox4: TGroupBox;
    gbFuentesDeEntrada: TGroupBox;
    GroupBox5: TGroupBox;
    GroupBox6: TGroupBox;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    Label6: TLabel;
    eFechaIniCono: TLabeledEdit;
    lDatosHistoricos: TLabel;
    LDurPasoSorteo: TLabel;
    LDurPasoTiempo: TLabel;
    LNArch: TLabel;
    LNombre: TLabel;
    lTipoEsclavizacion: TLabel;
    odEditarFuenteSintetizador: TOpenDialog;
    Panel3: TPanel;
    rbGraficarEscenarioActual: TRadioButton;
    rbGraficarComplexivo: TRadioButton;
    sgGuiasCono: TScrollBox;
    sbListadoFuentesEntradas: TScrollBox;
    Splitter3: TSplitter;

    procedure BCancelarClick(Sender: TObject);
    procedure BGuardarClick(Sender: TObject); override;
    procedure BAyudaClick(Sender: TObject);
    procedure btGraficarPronosticosClick(Sender: TObject);
    procedure btGetPronosticosClick(Sender: TObject);
    procedure cambiosForm(Sender: TObject);
    procedure cbArchiRefChange(Sender: TObject);
    procedure cbArchiRef_DatHistoChange(Sender: TObject);
    procedure cbArchiRef_ModAuxChange(Sender: TObject);
    procedure cbEscenarioSelecctionadoChange(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
    procedure cbSimularUsandoDatosHistoricosClick(Sender: TObject);
    procedure btExportarClick(Sender: TObject);
    procedure btImportarClick(Sender: TObject);
    procedure btAyudaExportarImportarClick(Sender: TObject);
    procedure cbEditarParametrosDelConoChange(Sender: TObject);
    procedure btAyudaEditarParametrosDelConoClick(Sender: TObject);
    procedure CopiadoYPegadoDeterminismos(Sender: TObject; var Key: word;
      Shift: TShiftState);
    procedure BAyudaTipoEsclavizadorClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);

  private

    escenariosDePronosticos: TEscenarioDePronosticos;
    ultimoEscenarioSeleccionado: integer;

    Escenario_activo: TPronosticos;

    cegh: TModeloCEGH;
    tblPronosticos: TTabla;
    {$IFDEF MODELO_ENTRADA_SALIDA}
    InfoEntradas: integer;
    tblEntradas: TTablaconEditores;
    {$ENDIF}
    listaFuentesEntrada: TListaDeCosas;
    flg_MODELO_ENTRADA_SALIDA: boolean;
    flg_modo_cono: integer;

    {$IFDEF CALIBRAR_PRONOSTICOS_TRAZOSXY}
    flg_GraficosActivos: boolean;
    {$ENDIF}

    // llena al tabla a partir de los datos
    procedure cambiar_guia(kSerie: integer; nueva_guia: TDAOfNReal);


    procedure populate_Pronosticos;

    procedure populate_Entradas;
    procedure mostrarListaEntradas;
    procedure RellenarListaEntradas;

    // copia los valores de la tabla en los datos
    // retorna si hayErrores o si hayCambios.
    procedure dump_Pronosticos(var hayCambios, hayErrores: boolean);


    // copia los valores de la tabla en los datos
    // retorna si hayErrores o si hayCambios.
    procedure dump_Entradas(var hayCambios, hayErrores: boolean);

    function onCambioENarchValido: boolean;
    procedure setComponentesTipoEsclavizador;

  protected
    function validarModeloEHistorico(flg_NoNil: boolean): boolean;
    function validarFormulario: boolean; override;
  public
    constructor Create(AOwner: TComponent; sala: TSalaDeJuego;
      tipoCosa: TClass; cosaConNombre: TCosaConNombre); override;

  end;


var
  trx: array of TfrmDLLForm;


implementation

  {$R *.lfm}
{ TComboBoxEnTabla }

constructor TComboBoxEnTabla.Create(TheOwner: TComponent; filaCB: integer);
begin
  inherited Create(TheOwner);
  self.fila := filaCB;
end;

{ TEditorTablaconEditores }

constructor TEditorTablaconEditores.Create(AOwner: TComponent;
  cosaEditable: TCosa; xsala: TSalaDeJuego);
begin
  inherited Create(AOwner, cosaEditable, xsala);

end;

{ TTablaconEditores }

procedure TTablaconEditores.wrComboBoxFuente(idFuente, idBorne: string;
  kfilaFuente, kcolumnaFuente, kfilaBorne, kcolumnaBorne, ancho: integer);
var
  CBFuente, CBBorne: TComboBoxEnTabla;
begin
  cellFuente := getCelda(kfilaFuente, kcolumnaFuente);
  CBFuente := TComboBoxEnTabla.Create(cellFuente, kfilaFuente);

  cellBorne := getCelda(kfilaBorne, kcolumnaBorne);
  CBBorne := TComboBoxEnTabla.Create(cellBorne, kfilaBorne);

  CBFuente.Text := strSeleccionarFuente;
  CBBorne.Text := strSeleccionarBorne;
  editor.inicializarCBFuente(CBFuente, CBBorne, False);

  CBFuente.Name := idFuente;
  CBFuente.Width := ancho;
  CBFuente.Height := 22;

  CBBorne.Name := idBorne;
  CBBorne.Width := ancho;
  CBBorne.Height := 22;

  CBFuente.OnChange := wrComboBoxFuente_OnChange;
  CBBorne.OnChange := wrComboBoxBorne_OnChange;

  cellFuente.agregar(CBFuente);
  cellBorne.agregar(CBBorne);
end;

function TTablaconEditores.readCB(id: string; kfila, kcolumna: integer): TComboBox;
var
  celda: TCelda;
  CB: TComboBox;
begin
  CB := Self.FindObj(kfila, kcolumna, id);
  Result := CB;
end;

function TTablaconEditores.darValorCBFuente(idFuente: string;
  kfilaFuente, kcolumnaFuente: integer): TFuenteAleatoria;
var
  fuenteAleatoria: TFuenteAleatoria;
  CBFuenteAleatoria: TComboBox;
begin
  CBFuenteAleatoria := self.readCB(idFuente, kfilaFuente, kcolumnaFuente);
  fuenteAleatoria := editor.valorCBFuente(CBFuenteAleatoria);
  Result := fuenteAleatoria;

end;

function TTablaconEditores.darValorCBBorne(idBorne: string;
  kfilaBorne, kcolumnaBorne: integer): string;
var
  CBBorne: TComboBox;
  Borne: string;
begin

  CBBorne := self.readCB(idBorne, kfilaBorne, kcolumnaBorne);
  Borne := editor.valorCBString(CBBorne);
  Result := Borne;

end;

procedure TTablaconEditores.SetValorCBFuente(idFuente, idBorne: string;
  kfilaFuente, kcolumnaFuente, kfilaBorne, kcolumnaBorne: integer;
  fuenteAleatoria: TFuenteAleatoria; borne: string);
var
  CBFuente, CBBorne: TComboBox;
begin
  CBFuente := readCB(idFuente, kfilaFuente, kcolumnaFuente);
  CBBorne := readCB(idBorne, kfilaBorne, kcolumnaBorne);
  editor.setCBFuente(CBFuente, CBBorne, fuenteAleatoria, borne);
end;

procedure TTablaconEditores.SetValorCBBorne(idBorne: string;
  kfilaBorne, kcolumnaBorne: integer; borne: string);
begin

end;

procedure TTablaconEditores.wrComboBoxFuente_OnChange(Sender: TObject);
var
  CBFuente: TComboBoxEnTabla;
  CBBorne: TComboBox;
  idBorne: string;
  fila: integer;
begin
  CBFuente := TComboBoxEnTabla(Sender);
  fila := CBFuente.fila;
  idBorne := 'bIN_' + IntToStr(fila);
  CBBorne := readCB(idBorne, fila, 2);
  editor.CBFuenteChange(Sender, CBBorne);
end;

procedure TTablaconEditores.wrComboBoxBorne_OnChange(Sender: TObject);
var
  CBFuente: TComboBox;
  CBBorne: TComboBoxEnTabla;
  idFuente: string;
  fila: integer;
begin
  CBBorne := TComboBoxEnTabla(Sender);
  fila := CBBorne.fila;
  idFuente := 'fIN_' + IntToStr(fila);
  CBFuente := readCB(idFuente, fila, 2);

  editor.CBBorneChange(CBFuente, TComboBox(Sender));
end;

constructor TTablaconEditores.Create(AOwner: TComponent; Name: string;
  cellpadding, cellsparcing, anchoborde: integer; sala: TSalaDeJuego);
begin
  inherited Create(AOwner, Name, cellpadding, cellsparcing, anchoborde);

  editor := TEditorTablaconEditores.Create(AOwner, nil, sala);
end;

{ TEditarFuenteSintetizador }

constructor TEditarFuenteSintetizador.Create(AOwner: TComponent;
  sala: TSalaDeJuego; tipoCosa: TClass; cosaConNombre: TCosaConNombre);
var
  fuente: TFuenteSintetizadorCEGH;
  kNombreBornes_Publicados, i: integer;
  Catalogo: TCatalogoReferencias;

begin
  inherited Create(AOwner, sala, tipoCosa, cosaConNombre);
  self.eDurPasoTiempo.Text := FloatToStr(sala.globs.HorasDelPaso);

  cbEscenarioSelecctionado.Items.Add('<Nuevo escenario>');

  tblPronosticos := TTabla.Create(sgGuiasCono, 'tblPronosticos', 4, 0, 0);
  {$IFDEF MODELO_ENTRADA_SALIDA}
  tblEntradas := TTablaconEditores.Create(sbListadoFuentesEntradas,
    'tblEntradas', 4, 0, 0, sala);
  {$ENDIF}
  inicializarCBArchiRef(cbArchiRef, True);
  inicializarCBArchiRef(cbArchiRef_DatHisto, True);
  inicializarCBArchiRef(cbArchiRef_ModAux, True);

  {$IFDEF  MODELO_ENTRADA_SALIDA}
  //valores posibles de la fuente
  //  inicializarCBFuente(CBFuenteIN, CBBorneIN, True);
  {$ENDIF}
  listaFuentesEntrada := TListaDeCosas.Create(capa, 'ListaFuentesDeEntrada');


  if cosaConNombre <> nil then
  begin
    fuente := cosaConNombre as TFuenteSintetizadorCEGH;

    ENombre.Text := fuente.nombre;
    setCBArchiRef(cbArchiRef, fuente.nombreArchivoModelo);

    flg_modo_cono := fuente.flg_modo_cono;

    case flg_modo_cono of
      0:
      begin
        cbEditarParametrosDelCono.Checked := True;
        GroupBox4.Enabled := True;
      end;
      1:
      begin
        cbEditarParametrosDelCono.Checked := False;
        GroupBox4.Enabled := False;
      end;
      //      else    // gflieller@2019-07-12
      //        begin
    end;

    if fuente.nombreArchivoModelo <> nil then
    begin
      odEditarFuenteSintetizador.InitialDir :=
        getCurrentDrive + ExtractFilePath(fuente.nombreArchivoModelo.ArchiRef.get_archi);
      cegh := TModeloCEGH.CreateFromArchi(fuente.nombreArchivoModelo.ArchiRef.get_archi);
      eDurPasoSorteo.Text := IntToStr(cegh.durPasoDeSorteoEnHoras);
      setComponentesTipoEsclavizador;
    end
    else
    begin
      cegh := nil;
      eDurPasoSorteo.Text := rsNoDisponible;
    end;

    cbSimularUsandoDatosHistoricos.Checked := fuente.simularConDatosHistoricos;
    cbSimularUsandoDatosHistoricosClick(self);
    cbSincronizarConHistoricos.Checked := fuente.SincronizarConHistoricos;
    cbSincronizarConSemillaAleatoria.Checked := fuente.SincronizarConSemillaAleatoria;

    setCBArchiRef(cbArchiRef_DatHisto, fuente.nombreArchivoDatosHistoricos);

    setCBArchiRef(cbArchiRef_ModAux, fuente.nombreArchivoModelo);

    cbUsarModeloAuxiliarParaOpt.Checked := fuente.usarModeloAuxiliar;
    cbResumirPromediando.Checked := fuente.ResumirPromediando;


    Catalogo := TCatalogoReferencias.Create;
    Self.escenariosDePronosticos :=
      fuente.escenariosDePronosticos.Create_Clone(catalogo, 0) as
      TEscenarioDePronosticos;
    Catalogo.Free;

    for i := 1 to escenariosDePronosticos.Count do
      cbEscenarioSelecctionado.Items.Add('Escenario ' + IntToStr(i));

    cbEscenarioSelecctionado.ItemIndex := 1;
    ultimoEscenarioSeleccionado := 0;

    eProbabilidad.Text := FloatToStr(Self.escenariosDePronosticos.items[0].Probabilidad);
    eFechaIniCono.Text := self.escenariosDePronosticos.items[0].fechaIniCono.AsStr;


    eurl_get.Text := fuente.url_get;

    if fuente.nombreArchivoModelo <> nil then
      populate_Pronosticos;

    {$IFNDEF  MODELO_ENTRADA_SALIDA}
    gbFuentesDeEntrada.Visible := False;
    sbListadoFuentesEntradas.Visible := False;
    {$ENDIF}

    {$IFDEF  MODELO_ENTRADA_SALIDA}
    //    setCBFuente(CBFuenteIN, CBBorneIN, fuente.fuenteIN, fuente.borneIN);

    if fuente.datosModelo_Opt <> nil then
      self.InfoEntradas := fuente.datosModelo_Opt.nBornesEntrada
    //fuente.datosModelo_Opt.NombresDeBornes_Publicados.Count - fuente.datosModelo_Opt.nBornesSalida;
    else
    if fuente.fuentesEntrada <> nil then
      self.InfoEntradas := fuente.fuentesEntrada.Count
    else
      self.InfoEntradas := 0;


    for i := 0 to self.InfoEntradas - 1 do
    begin
      if fuente.fuentesEntrada.Count > i then
      begin
        listaFuentesEntrada.Add(
          fuente.fuentesEntrada.items[i]);
      end
      else
      begin
        listaFuentesEntrada.Add(nil);
      end;
    end;


    //SetLength(listaFuentesEntradas, InfoEntradas);
    if fuente.nombreArchivoModelo <> nil then
    begin
      populate_Entradas;
      mostrarListaEntradas;
    end;

    if self.InfoEntradas > 0 then
    begin
      flg_MODELO_ENTRADA_SALIDA := True;
      sbListadoFuentesEntradas.Visible := True;
      gbFuentesDeEntrada.Visible := True;
    end
    else
    begin
      flg_MODELO_ENTRADA_SALIDA := False;
      sbListadoFuentesEntradas.Visible := False;
      gbFuentesDeEntrada.Visible := False;
    end;

    {$ENDIF}
    //  end
  end
  else
  begin
    odEditarFuenteSintetizador.InitialDir := getDir_DatosComunes;
    self.escenariosDePronosticos := TEscenarioDePronosticos.Create(capa, '');
    {$IFDEF MODELO_ENTRADA_SALIDA}
    self.InfoEntradas := 0;
    flg_MODELO_ENTRADA_SALIDA := False;
    {$ENDIF}
    cegh := nil;
    eDurPasoSorteo.Text := rsNoDisponible;
    setCBArchiRef(cbArchiRef_DatHisto, nil);
    cbArchiRef_DatHisto.Enabled := False;
    setCBArchiRef(cbArchiRef_ModAux, nil);
    cbUsarModeloAuxiliarParaOpt.Checked := False;
    cbResumirPromediando.Checked := True;
    eurl_get.Text := '';
    //CBFuenteIN.Enabled := false;
    //    CBBorneIN.Enabled := false;
  end;

end;


procedure TEditarFuenteSintetizador.dump_Pronosticos(
  var hayCambios, hayErrores: boolean);
var
  i: integer;
  aPronostico: TPronostico;
  nuevos_valores: TDAofNReal;
  ed: TEdit;
  maxNPCC: integer;

  Pronosticos: TPronosticos;

  prob: NReal;
  dtIniCono: TDateTime;

  sFecha: string;

begin

  if hayErrores then
    exit;

  Pronosticos := escenariosDePronosticos.items[ultimoEscenarioSeleccionado] as
    TPronosticos;

  prob := StrToFloat(eProbabilidad.Text);

  sFecha := trim(lowercase(eFechaIniCono.Text));
  if (sFecha = 'auto') or (sFecha = '0') then
    dtIniCono := 0
  else
    dtIniCono := StrToDateTime(eFechaIniCono.Text);

  if Pronosticos.Probabilidad <> prob then
  begin
    Pronosticos.Probabilidad := prob;
    hayCambios := True;
  end;

  if Pronosticos.fechaIniCono.dt <> dtIniCono then
  begin
    Pronosticos.fechaIniCono.dt := dtIniCono;
    hayCambios := True;
  end;

  for i := 1 to Pronosticos.Count do
  begin
    aPronostico := Pronosticos[i - 1] as TPronostico; //Arrancan en 0
    ed := tblPronosticos.FindObj(i, 1, 'ed_' + IntToStr(i));
    if Assigned(ed) then
    begin
      try
        nuevos_valores := StrToDAOfNReal_(ed.Text, ';');
        if not viguales(nuevos_valores, aPronostico.guia) then
        begin
          setlength(aPronostico.guia, 0);
          aPronostico.guia := nuevos_valores;
          hayCambios := True;
        end;
      except
        on E: Exception do
        begin
          ShowMessage(msFormatoInvalido);
          ed.SetFocus;
          hayErrores := True;
        end;
      end;

      dump_int(tblPronosticos, aPronostico.NPCC, 'npcc_' + IntToStr(i),
        i, 2, hayCambios, hayErrores);

      maxNPCC := length(aPronostico.guia) - cegh.CalcOrdenDelFiltro;

      ////////////////////////////////////////////////////////////////////////////////
      if flg_modo_cono <> 1 then
      begin

        if aPronostico.NPCC > MaxNPCC then
        begin
          ed := tblPronosticos.FindObj(i, 2, 'npcc_' + IntToStr(i));
          ed.Text := IntToStr(maxNPCC);
          aPronostico.NPCC := maxNPCC;
          hayCambios := True;
          hayErrores := True;
          ShowMessage('Atención, el valor NPCC+NRetardos para la serie: ' +
            IntToStr(i) +
            ' es superior al largo de la guía del cono. Dicho valor NPCC fue reducido al largo de la guía-NRetardos. Revise el cambio por favor.');
        end;

        if aPronostico.NPCC < 0 then
        begin
          ed := tblPronosticos.FindObj(i, 2, 'npcc_' + IntToStr(i));
          ed.Text := IntToStr(0);
          aPronostico.NPCC := 0;
          hayCambios := True;
          hayErrores := True;
          ShowMessage('Atención, el valor NPCC < 0 la serie: ' +
            IntToStr(i) + ' Se impuso a CERO. Revise el cambio por favor.');
        end;


        dump_int(tblPronosticos, aPronostico.NPSA, 'npsa_' + IntToStr(i),
          i, 4, hayCambios, hayErrores);

        if aPronostico.NPSA < 0 then
        begin
          ed := tblPronosticos.FindObj(i, 4, 'npsa_' + IntToStr(i));
          ed.Text := IntToStr(0);
          aPronostico.NPSA := 0;
          hayCambios := True;
          hayErrores := True;
          ShowMessage('Atención, el valor NPSA < 0 la serie: ' +
            IntToStr(i) + ' Se impuso a CERO. Revise el cambio por favor.');
        end;



      (*
      if aPronostico.NPSA > MaxNPCC then
      begin
        ed := tblPronosticos.FindObj(i, 4, 'npsa_' + IntToStr(i));
        ed.Text := IntToStr(maxNPCC);
        aPronostico.NPSA := maxNPCC;
        hayCambios := True;
        hayErrores := True;
        ShowMessage('Atención, el valor NPSA del canal ' + IntToStr(
          i) + ' debe ser inferior a la cantidad de valores de la guia descontando los necesarios para inicializar el filtro.'
          + ' Dicho valor NPSA fue reducido al largo de la guía-NRetardos. Revise el cambio por favor.'
          );
      end;
      *)

        dump_int(tblPronosticos, aPronostico.NPLC, 'nplc_' + IntToStr(i),
          i, 3, hayCambios, hayErrores);


        if aPronostico.NPLC < 0 then
        begin
          ed := tblPronosticos.FindObj(i, 3, 'nplc_' + IntToStr(i));
          ed.Text := IntToStr(0);
          aPronostico.NPLC := 0;
          hayCambios := True;
          hayErrores := True;
          ShowMessage('Atención, el valor NPLC < 0 la serie: ' +
            IntToStr(i) + ' Se impuso a CERO. Revise el cambio por favor.');
        end;




        dump_int(tblPronosticos, aPronostico.NPAC, 'npac_' + IntToStr(i),
          i, 5, hayCambios, hayErrores);

        if aPronostico.NPAC < 0 then
        begin
          ed := tblPronosticos.FindObj(i, 5, 'npac_' + IntToStr(i));
          ed.Text := IntToStr(0);
          aPronostico.NPAC := 0;
          hayCambios := True;
          hayErrores := True;
          ShowMessage('Atención, el valor NPAC < 0 la serie: ' +
            IntToStr(i) + ' Se impuso a CERO. Revise el cambio por favor.');
        end;

(*
      dump_float(tblPronosticos, aPronostico.guia_pe, 'npe_' + IntToStr(i),
        i, 6, hayCambios, hayErrores);
  *)
        dump_float(tblPronosticos, aPronostico.AperturaInicial_pu, 'ai_' + IntToStr(i),
          i, 7, hayCambios, hayErrores);
      end;
    end;

  end;
  ////////////////////////////////////////////////////////////////////////////////

  if hayCambios then
    guardado := False;
end;

procedure TEditarFuenteSintetizador.dump_Entradas(var hayCambios, hayErrores: boolean);
var
  i: integer;
  fuenteAleatoriaConBorne, nueva_fuenteAleatoriaConBorne: TFuenteAleatoria_Borne;
  fuenteAleatoria, nueva_fuenteAleatoria: TFuenteAleatoria;
  Borne, nuevo_Borne: string;
  CBFuenteAleatoria, CBBorne: TComboBox;
  filaFuente, columnaFuente, filaBorne, columnaBorne: integer;
  idFuente, idBorne: string;

begin

  if hayErrores then
    exit;
  {$IFDEF MODELO_ENTRADA_SALIDA}
  for i := 1 to InfoEntradas do
  begin
    idFuente := 'fIN_' + IntToStr(i);
    filaFuente := i;
    columnaFuente := 1;
    idBorne := 'bIN_' + IntToStr(i);
    filaBorne := i;
    columnaBorne := 2;

    nueva_fuenteAleatoria := tblEntradas.darValorCBFuente(idFuente,
      filaFuente, columnaFuente);
    nuevo_Borne := tblEntradas.darValorCBBorne(idBorne, filaBorne, columnaBorne);

    if (nueva_fuenteAleatoria <> nil) then
    begin
      if (nuevo_Borne <> '') then
      begin
        nueva_fuenteAleatoriaConBorne :=
          TFuenteAleatoria_Borne.Create(capa, nueva_fuenteAleatoria, nuevo_Borne);
      end;
    end
    else
    begin
      ShowMessage(mesFaltaElegirFuente);
      hayErrores := True;
    end;


    try
      fuenteAleatoriaConBorne :=
        TFuenteAleatoria_Borne(listaFuentesEntrada.items[i - 1]);
      if nueva_fuenteAleatoriaConBorne <> fuenteAleatoriaConBorne then
      begin
        listaFuentesEntrada.items[i - 1] := nueva_fuenteAleatoriaConBorne;
        hayCambios := True;
      end;
    except
      on E: Exception do
      begin
        ShowMessage(msFormatoInvalido);
        hayErrores := True;
      end;
    end;
  end;

  if hayCambios then
    guardado := False;
  {$ENDIF}

end;




procedure TEditarFuenteSintetizador.populate_Pronosticos;
var
  i: integer;
  aPronostico: TPronostico;

begin

  Escenario_activo := escenariosDePronosticos.items[cbEscenarioSelecctionado.ItemIndex -
    1] as TPronosticos;

  //  tblPronosticos.Parent:= sgGuiasCono;
  //  Borne, valores, ve, prb, NPCC, NPLC, NPSA, NPAC

  tblPronosticos.ClearRedim(1 + Escenario_activo.Count, 8); //filas, columnas

  //Creo la fila de titulos
  tblPronosticos.wrTexto('', 0, 0, 'Borne');
  tblPronosticos.wrTexto('', 0, 1, 'Valores iniciales y guía del pronóstico.');
  tblPronosticos.wrTexto('', 0, 2, 'NPCC');
  tblPronosticos.wrTexto('', 0, 3, 'NPLC');
  tblPronosticos.wrTexto('', 0, 4, 'NPSA');
  tblPronosticos.wrTexto('', 0, 5, 'NPAC');
  //  tblPronosticos.wrTexto('', 0, 6, 'pe[p.u.]');
  tblPronosticos.wrTexto('', 0, 6, 'NRet.');
  tblPronosticos.wrTexto('', 0, 7, 'ai[p.u.]');


  tblPronosticos.SetBgColorFila(0, clGray);
  tblPronosticos.SetFontColorFila(0, clWhite);
  //Completo la tabla con los pronosticos para la serie

  for i := 1 to Escenario_activo.Count do
  begin

    aPronostico := Escenario_activo.items[i - 1];

    tblPronosticos.wrTexto('', i, 0, cegh.NombresDeBornes_Publicados[i - 1]);

    tblPronosticos.wrEdit('ed_' + IntToStr(i), i, 1, DAOfNRealToStr_(
      aPronostico.guia, 8, 3, ';'), 28, '');

    tblPronosticos.wrEdit('npcc_' + IntToStr(i), i, 2,
      IntToStr(aPronostico.NPCC), 4, rs_NPCC);
    tblPronosticos.wrEdit('nplc_' + IntToStr(i), i, 3,
      IntToStr(aPronostico.NPLC), 4, rs_NPLC);
    tblPronosticos.wrEdit('npsa_' + IntToStr(i), i, 4,
      IntToStr(aPronostico.NPSA), 4, rs_NPSA);
    tblPronosticos.wrEdit('npac_' + IntToStr(i), i, 5,
      IntToStr(aPronostico.NPAC), 4, rs_NPAC);
   (* tblPronosticos.wrEdit('npe_' + IntToStr(i), i, 6,
      FloatToStr(aPronostico.guia_pe), 3, rs_pe); *)
    tblPronosticos.wrTexto('', i, 6, IntToStr(cegh.CalcOrdenDelFiltro));
    tblPronosticos.wrEdit('ai_' + IntToStr(i), i, 7,
      FloatToStr(aPronostico.AperturaInicial_pu), 5, rs_aipu);

  end;

  eProbabilidad.Text := FloatToStr(Escenario_activo.Probabilidad);
  eFechaIniCono.Text := Escenario_activo.fechaIniCono.AsStr;

  tblPronosticos.reposicionar;
  tblPronosticos.Visible := True;

end;

procedure TEditarFuenteSintetizador.populate_Entradas;
var
  i: integer;
  filaFuente, columnaFuente: integer;
  filaBorne, columnaBorne: integer;
  fuenteConBorne: TFuenteAleatoria_Borne;
begin
   {$IFDEF MODELO_ENTRADA_SALIDA}
  tblEntradas.ClearRedim(1 + InfoEntradas, 3); //filas, columnas

  //Creo la fila de titulos
  tblEntradas.wrTexto('', 0, 0, '');
  tblEntradas.wrTexto('', 0, 1, 'Fuente');
  tblEntradas.wrTexto('', 0, 2, 'Borne');

  tblEntradas.SetBgColorFila(0, clGray);
  tblEntradas.SetFontColorFila(0, clWhite);

  for i := 1 to InfoEntradas do
  begin
    filaFuente := i;
    columnaFuente := 1;
    filaBorne := i;
    columnaBorne := 2;
    tblEntradas.wrTexto('', i, 0, 'Fuente ' + IntToStr(i));
    tblEntradas.wrComboBoxFuente('fIN_' + IntToStr(i), 'bIN_' + IntToStr(i),
      filaFuente, columnaFuente, filaBorne, columnaBorne, 130);
  end;

  tblEntradas.reposicionar;
  tblEntradas.Visible := True;
  {$ENDIF}

end;

procedure TEditarFuenteSintetizador.mostrarListaEntradas;
var
  i: integer;
  filaFuente, columnaFuente: integer;
  filaBorne, columnaBorne: integer;
  fuenteConBorne: TFuenteAleatoria_Borne;
  idFuente, idBorne: string;

begin
  {$IFDEF MODELO_ENTRADA_SALIDA}
  for i := 1 to InfoEntradas do
  begin
    filaFuente := i;
    columnaFuente := 1;
    filaBorne := i;
    columnaBorne := 2;
    idFuente := 'fIN_' + IntToStr(i);
    idBorne := 'bIN_' + IntToStr(i);

    fuenteConBorne := TFuenteAleatoria_Borne(listaFuentesEntrada.items[i - 1]);

    tblEntradas.SetValorCBFuente(idFuente, idBorne, filaFuente, columnaFuente,
      filaBorne, columnaBorne, fuenteConBorne.fuente, fuenteConBorne.borne);
  end;
  {$ENDIF}
end;



procedure TEditarFuenteSintetizador.RellenarListaEntradas;
var
  i: integer;
  fuenteAleatoriaConBorne: TFuenteAleatoria_Borne;
  fuenteAleatoria: TFuenteAleatoria;
  borne: string;
  filaFuente, columnaFuente, filaBorne, columnaBorne: integer;
begin
  {$IFDEF MODELO_ENTRADA_SALIDA}
  for i := 1 to InfoEntradas do
  begin
    filaFuente := i;
    columnaFuente := 1;
    filaBorne := i;
    columnaBorne := 2;

    fuenteAleatoria := tblEntradas.darValorCBFuente('fIN_' + IntToStr(i),
      filaFuente, columnaFuente);

    borne := tblEntradas.darValorCBBorne('bIN_' + IntToStr(i),
      filaBorne, columnaBorne);

    fuenteAleatoriaConBorne :=
      TFuenteAleatoria_Borne.Create(capa, fuenteAleatoria, borne);
    listaFuentesEntrada.items[i - 1] := fuenteAleatoriaConBorne;
  end;
  {$ENDIF}
end;




procedure TEditarFuenteSintetizador.cambiar_guia(kSerie: integer;
  nueva_guia: TDAOfNReal);
var
  i: integer;
  Pronosticos: TPronosticos;
  aPronostico: TPronostico;

begin
  Pronosticos := escenariosDePronosticos.items[cbEscenarioSelecctionado.ItemIndex - 1] as
    TPronosticos;
  aPronostico := Pronosticos.items[kSerie];
  setlength(aPronostico.guia, 0);
  aPronostico.guia := copy(nueva_guia);
end;


function TEditarFuenteSintetizador.onCambioENarchValido: boolean;
var
  i, j, pos: integer;
  newDatos: TModeloCEGH;
  newEscenario: TEscenarioDePronosticos;
  nEscenatios: integer;
  salaAux: TSalaDeJuego;
  fr: TFichaReferencia;
  referentes: string;
  Catalogo: TCatalogoReferencias;
  nFuentesEntrada: integer;
begin

  if valorCBArchiRef(cbArchiRef) <> nil then
    newDatos := TModeloCEGH.CreateFromArchi(valorCBArchiRef(
      cbArchiRef).ArchiRef.get_archi);

  Result := True;

  if cegh <> nil then
  begin

    Catalogo := TCatalogoReferencias.Create;
    // Para cargar la variable referencias en uCosaConNombre.
    salaAux := TSalaDeJuego(sala.Create_Clone(Catalogo, 0));
    referentes := '';
    for i := 0 to Catalogo.referencias.Count - 1 do
    begin
      fr := TFichaReferencia(Catalogo.referencias[i]);
      if (fr.referido_nombre = cosaConNombre.nombre) then
      begin
        if fr.referente is TCosaConNombre then
          referentes := referentes + TCosaConNombre(fr.referente).DescClase +
            ' - ' + TCosaConNombre(fr.referente).nombre + #13#10
        else
          referentes := referentes + TCosaConNombre(fr.referente).DescClase +
            ' - ' + 'SIN NOMBRE' + #13#10;
      end;
    end;

    // Libero y limpio las lista de referencias.
    salaAux.Free;
    Catalogo.LimpiarReferencias;

    if (referentes <> '') and (MessageDlg('Atención',
      'Se deberá verificar la asignación de bornes para:' +
      #13#10#13#10 + referentes + #13#10#13#10 + '¿Desea continuar?',
      mtWarning, [mbYes, mbNo], 0) = mrNo) then
    begin
      Result := False;
      Exit;
    end;

    newEscenario := TEscenarioDePronosticos.Create(capa);
    nEscenatios := escenariosDePronosticos.Count;

    cbEscenarioSelecctionado.Items.Clear;
    cbEscenarioSelecctionado.Items.Add('<Nuevo escenario>');

    if nEscenatios = 0 then
      escenariosDePronosticos.Add(TPronosticos.Create_Default(newDatos), 100)
    else
    begin
      // Si hay pronosticos en común los conservamos.
      for i := 0 to nEscenatios - 1 do
      begin
        newEscenario.Add(TPronosticos.Create_Default(newDatos),
          escenariosDePronosticos[i].Probabilidad);

        cbEscenarioSelecctionado.Items.Add('Escenario ' + IntToStr(i + 1));

        for j := 0 to cegh.NombresDeBornes_Publicados.Count - 1 do
        begin
          pos := newDatos.NombresDeBornes_Publicados.IndexOf(
            cegh.NombresDeBornes_Publicados[j]);

          if pos <> -1 then
          begin
            newEscenario[i][pos].Free;
            newEscenario[i][pos] :=
              escenariosDePronosticos[i][j].Create_Clone(Catalogo, 0) as TPronostico;
          end;
        end;
      end;
    end;
    //limpio las fuentes de entrada

    nFuentesEntrada := cegh.nBornesEntrada;
    // cegh.NombresDeBornes_Publicados.Count - cegh.nBornesSalida;
{    listaFuentesEntrada := TListaDeCosas.Create(capa, 'ListaFuentesDeEntrada');// nil;
    for i := 0 to nFuentesEntrada - 1 do
    begin
        listaFuentesEntrada.Add(nil);
    end;
    populate_Entradas;
}
    mostrarListaEntradas;
    cegh.Free;
    cbEscenarioSelecctionado.ItemIndex := 1;
    ultimoEscenarioSeleccionado := 0;

    Catalogo.Free;

  end
  else
  begin

    newEscenario := TEscenarioDePronosticos.Create(capa);
    newEscenario.Add(TPronosticos.Create_Default(newDatos), 100);

    cbEscenarioSelecctionado.Items.Clear;
    cbEscenarioSelecctionado.Items.Add('<Nuevo escenario>');

    {cbEscenarioSelecctionado.ItemIndex := 1;
    ultimoEscenarioSeleccionado := 0;   }

    cbEscenarioSelecctionado.Items.Add('Escenario ' + IntToStr(
      cbEscenarioSelecctionado.Items.Count));
    cbEscenarioSelecctionado.ItemIndex := cbEscenarioSelecctionado.Items.Count - 1;
  end;

  cegh := newDatos;
  if escenariosDePronosticos <> nil then
    escenariosDePronosticos.Free;

  self.escenariosDePronosticos := newEscenario;

  setComponentesTipoEsclavizador;

  {$IFDEF MODELO_ENTRADA_SALIDA}
  self.InfoEntradas := cegh.nBornesEntrada;
  //cegh.NombresDeBornes_Publicados.Count - cegh.nBornesSalida;

  for i := 0 to self.InfoEntradas - 1 do
  begin
    listaFuentesEntrada.Add(nil);
  end;
  {$ENDIF}

  populate_Pronosticos;
  {$IFDEF MODELO_ENTRADA_SALIDA}
  populate_Entradas;
  {$ENDIF}

  eDurPasoSorteo.Text := IntToStr(cegh.durPasoDeSorteoEnHoras);
  setCBArchiRef(cbArchiRef_ModAux, nil);
  setCBArchiRef(cbArchiRef_DatHisto, nil);
  cbUsarModeloAuxiliarParaOpt.Checked := False;
  cbResumirPromediando.Checked := True;
  cbSimularUsandoDatosHistoricos.Checked := False;
  eurl_get.Text := '';

end;

function TEditarFuenteSintetizador.validarModeloEHistorico(flg_NoNil: boolean): boolean;
var
  i: integer;
  mismosBornes: boolean;
  datosHistoricos: TDatosHistoricos;


  procedure printBornes(cegh_lst, hist_lst: TStringList);
  var
    kMax, k: integer;
    scegh, shist: string;

  begin
    kMax := max(cegh_lst.Count - 1, hist_lst.Count - 1);
    writeln('--': 4, #9'|', 'cegh': 12, #9'|', 'hist': 12, #9'|');
    for k := 0 to kMax do
    begin
      scegh := '----';
      shist := '----';
      Write(k + 1: 4);
      if k < cegh_lst.Count then
        scegh := cegh_lst[k];
      if k < hist_lst.Count then
        shist := hist_lst[k];
      if scegh = shist then
        writeln(k: 4, #9'|', scegh: 12, #9'|', shist: 12, #9'|', ' Ok.')
      else
        writeln(k: 4, #9'|', scegh: 12, #9'|', shist: 12, #9'|', ' <- REVISAR !!');
    end;

  end;

begin
  try
    if valorCBArchiRef(cbArchiRef_DatHisto) <> nil then
      datosHistoricos := TDatosHistoricos.CreateFromArchi(
        valorCBArchiRef(cbArchiRef_DatHisto).ArchiRef.get_archi)
    else
    begin
      if flg_NoNil then
      begin
        raise Exception.Create('Debe especificar un archivo de datos históricos');
        Result := False;
      end
      else
        Result := True;
      exit;
    end;


    if cegh.durPasoDeSorteoEnHoras <> Trunc(datosHistoricos.dt_EntrePuntos *
      dtToHora + 0.02) then
      raise Exception.Create(
        'Especificó un archivo de datos historicos con distinta duración de paso de sorteo que la del archivo del modelo.');


    mismosBornes := datosHistoricos.NombresDeBornes_Publicados.Count =
      cegh.NombresDeBornes_Publicados.Count;

    i := 0;
    while (i < datosHistoricos.NombresDeBornes_Publicados.Count) and mismosBornes do
    begin
      mismosBornes := cegh.NombresDeBornes_Publicados[i] =
        datosHistoricos.NombresDeBornes_Publicados[i];
      i := i + 1;
    end;

    if not mismosBornes then
    begin
      printBornes(cegh.NombresDeBornes_Publicados,
        datosHistoricos.NombresDeBornes_Publicados);
      raise Exception.Create(
        'Los bornes en el archivo del modelo difieren de los bornes en el archivo de datos historicos.');
    end;


    Result := True;
    datosHistoricos.Free;
  except
    on e: Exception do
    begin
      ShowMessage(e.Message);
      Result := False;
    end;
  end;
end;

function TEditarFuenteSintetizador.validarFormulario: boolean;
var
  hayCambios, hayErrores: boolean;
begin
  try
    hayCambios := False;
    hayErrores := False;
    dump_pronosticos(hayCambios, hayErrores);
    {$IFDEF MODELO_ENTRADA_SALIDA}
    dump_Entradas(hayCambios, hayErrores);
    {$ENDIF}
    Result := not hayErrores and inherited validarNombre(ENombre) and
      inherited validarCBArchiRef(cbArchiRef, True) and
      inherited validarCBArchiRef(cbArchiRef_DatHisto,
      cbSimularUsandoDatosHistoricos.Checked) and validarModeloEHistorico(
      cbSimularUsandoDatosHistoricos.Checked);

  except
    Result := False;
  end;
end;


{
procedure TEditarFuenteSintetizador.ENArchExit(Sender: TObject);
begin

    if ((valorCBArchiRef(cbArchiRef)<> nil) and validarCBArchiRef(cbArchiRef)) or
            ((valorCBArchiRef(cbArchiRef)= nil) and validarEditNarch(ENArch)) then
      onCambioENarchValido;
end;
      }


procedure TEditarFuenteSintetizador.cambiosForm(Sender: TObject);
begin
  inherited CambiosForm(Sender);
end;

procedure TEditarFuenteSintetizador.cbArchiRefChange(Sender: TObject);

begin
  inherited cbArchiRefChange(Sender, True);
  validarCBArchiRef(cbArchiRef, False);

  onCambioENarchValido;

end;

procedure TEditarFuenteSintetizador.cbArchiRef_DatHistoChange(Sender: TObject);

begin
  inherited cbArchiRefChange(Sender, True);
  validarCBArchiRef(cbArchiRef_DatHisto, cbSincronizarConHistoricos.Checked);

end;

procedure TEditarFuenteSintetizador.cbArchiRef_ModAuxChange(Sender: TObject);

begin
  inherited cbArchiRefChange(Sender, True);
  validarCBArchiRef(cbArchiRef_ModAux, cbUsarModeloAuxiliarParaOpt.Checked);
end;


procedure TEditarFuenteSintetizador.cbEscenarioSelecctionadoChange(Sender: TObject);
var
  hayCambios, hayErrores: boolean;
  index: integer;
begin

  if ultimoEscenarioSeleccionado = cbEscenarioSelecctionado.ItemIndex - 1 then
    Exit;

  hayErrores := False;
  hayCambios := False;
  dump_Pronosticos(hayCambios, hayErrores);

  // Agregar nuevo escanarios.
  if cbEscenarioSelecctionado.ItemIndex = 0 then
  begin
    ////******  A BORRAR   ***********

    //MessageDlg('Información', 'FUNCIÓN AÚN NO DISPONIBLE.', mtInformation, [mbOK], 0);
    //cbEscenarioSelecctionado.ItemIndex:=1;
    //Exit;

    ////******************************

    index := escenariosDePronosticos.Add(TPronosticos.Create_Default(cegh), 0);
    cbEscenarioSelecctionado.Items.Add('Escenario ' + IntToStr(
      cbEscenarioSelecctionado.Items.Count));
    cbEscenarioSelecctionado.ItemIndex := cbEscenarioSelecctionado.Items.Count - 1;
  end;

  if hayErrores then
    tblPronosticos.SetFocus
  else
    populate_Pronosticos;

  ultimoEscenarioSeleccionado := cbEscenarioSelecctionado.ItemIndex - 1;
end;


procedure TEditarFuenteSintetizador.cbSimularUsandoDatosHistoricosClick(Sender: TObject);
begin
  cbArchiRef_DatHisto.Enabled := cbSimularUsandoDatosHistoricos.Checked;
end;

procedure TEditarFuenteSintetizador.cbEditarParametrosDelConoChange(Sender: TObject);
var
  kSerie: integer;
begin
  GroupBox4.Enabled := cbEditarParametrosDelCono.Checked;
  if cbEditarParametrosDelCono.Checked then
    flg_modo_cono := 0
  else
    flg_modo_cono := 1;

  if escenariosDePronosticos <> nil then
  begin
    for kSerie := 0 to escenariosDePronosticos[0].NSeries - 1 do
      escenariosDePronosticos[0].items[kSerie].flg_modo_cono := flg_modo_cono;
  end;
end;

procedure TEditarFuenteSintetizador.btAyudaEditarParametrosDelConoClick(
  Sender: TObject);
begin
  // Ayuda parametros simplificados
  verdoc(3827, 'EditarParametrosDelCono');
end;

procedure TEditarFuenteSintetizador.btExportarClick(Sender: TObject);
var
  fuente: TFuenteSintetizadorCEGH;
  ArchiCono: string;
  archiTextoCono: TArchiTexto;
begin
  fuente := TFuenteSintetizadorCEGH(cosaConNombre);
  fuente.nombre := ENombre.Text;
  fuente.nombreArchivoModelo := valorCBArchiRef(cbArchiRef);
  fuente.nombreArchivoDatosHistoricos := valorCBArchiRef(cbArchiRef_DatHisto);
  fuente.simularConDatosHistoricos := cbSimularUsandoDatosHistoricos.Checked;
  fuente.sincronizarConHistoricos := cbSincronizarConHistoricos.Checked;
  fuente.SincronizarConSemillaAleatoria := cbSincronizarConSemillaAleatoria.Checked;
  fuente.nombreArchivoModeloAuxiliar := valorCBArchiRef(cbArchiRef_ModAux);
  fuente.usarModeloAuxiliar := cbUsarModeloAuxiliarParaOpt.Checked;
  fuente.ResumirPromediando := cbResumirPromediando.Checked;
  fuente.escenariosDePronosticos.Free;
  fuente.escenariosDePronosticos := self.escenariosDePronosticos;
  fuente.url_get := eurl_get.Text;
  fuente.InitModeloFromFile;
  fuente.capa := capa;
  fuente.flg_modo_cono := flg_modo_cono;
  {$IFDEF  MODELO_ENTRADA_SALIDA}
  //      fuente.fuenteIN := valorCBFuente(CBFuenteIN);
  //      fuente.borneIN := valorCBString(CBBorneIN);
  fuente.fuentesEntrada := listaFuentesEntrada;
  fuente.flg_MODELO_ENTRADA_SALIDA := flg_MODELO_ENTRADA_SALIDA;
  //      mostrarListaEntradas;
  //     RellenarListaEntradas;

  {$ENDIF}

  ArchiCono := getDir_Tmp + 'fuente_tmp.xlt';
  fuente.WriteToArchi(ArchiCono);

  ShowMessage('Pronóstico exportado a: ' + ArchiCono);

  btImportar.Enabled := True;

end;

procedure TEditarFuenteSintetizador.btImportarClick(Sender: TObject);
var
  ArchiCono: string;
  TextoCono: TArchiTexto;
  fcegh: TFuenteSintetizadorCEGH;
  Catalogo: TCatalogoReferencias;
  a: TCosa;
begin
  //  Cargar los datos del cono
  Catalogo := TCatalogoReferencias.Create;
  ArchiCono := getDir_Tmp + 'fuente_tmp.xlt';

  TextoCono := TArchiTexto.CreateForRead(1, Catalogo, ArchiCono, True);
  try
    TextoCono.rd(ENombre.Text, a);
    fcegh := TFuenteSintetizadorCEGH(a);
  finally
    TextoCono.Free;
  end;

  Self.escenariosDePronosticos :=
    fcegh.escenariosDePronosticos.Create_Clone(catalogo, 0) as
    TEscenarioDePronosticos;

  Catalogo.Free;

  cbEditarParametrosDelCono.Checked := False;

  ShowMessage('Pronóstico importado desde: ' + ArchiCono);
  //  //  Habilitar a graficar
  //  GroupBox7.Enabled := true;
  //  eNPasosCono.Enabled := true;
  //  eNCronCono.Enabled := true;
  //  btGraficarCono.Enabled := true;
  //  ConoDesdeArchi := True;
end;

procedure TEditarFuenteSintetizador.btAyudaExportarImportarClick(Sender: TObject);
begin
  // Ayuda parametros simplificados
  verdoc(3827, 'ExportarImportarConoArchi');
end;

procedure TEditarFuenteSintetizador.FormCloseQuery(Sender: TObject;
  var CanClose: boolean);
var
  numeroDeSerie: integer;
begin
  inherited FormCloseQuery(Sender, CanClose);
  if CanClose then
  begin
    if cegh <> nil then
      cegh.Free;
    if (ModalResult <> mrOk) then
    begin
      //if pronosticos <> nil then
      //begin
      //  Pronosticos.Free;
      //  Pronosticos := nil;
      //end;

      for numeroDeSerie := 0 to high(trx) do
        if trx[numeroDeSerie] <> nil then
          trx[numeroDeSerie].Close;
      SetLength(trx, 0);
    end;
  end;
end;

procedure TEditarFuenteSintetizador.setComponentesTipoEsclavizador;
begin
  if cegh.durPasoDeSorteoEnHoras < sala.globs.HorasDelPaso then
  begin
    eTipoDeEsclavizacion.Text := rsSubMuestreada;
    cbResumirPromediando.Enabled := True;
  end
  else if cegh.durPasoDeSorteoEnHoras = sala.globs.HorasDelPaso then
  begin
    eTipoDeEsclavizacion.Text := rsSinEsclavizar;
    cbResumirPromediando.Enabled := False;
  end
  else
  begin
    eTipoDeEsclavizacion.Text := rsSobreMuestreada;
    cbResumirPromediando.Enabled := False;
  end;
end;



procedure TEditarFuenteSintetizador.BCancelarClick(Sender: TObject);
begin
  inherited BCancelarClick(Sender);
end;


procedure TEditarFuenteSintetizador.BGuardarClick(Sender: TObject);
var
  fuente: TFuenteSintetizadorCEGH;
  archiref, archiref_DatHisto, archiref_ModAux: string;
  validoParaGuardar: boolean;
begin
  // Se permite guardar la fuente en dos casos:
  //   1- Que la fuente se haya armado respetando correctamente el formato del
  //      permitido por el editor manualmente. Chequeando los parametros.
  //   2- Que la fuente se haya cargado usando un archivo .xlt precalibrado.
  //      Sin chequear los parametros, bajo responsabilidad del usuario. Mas
  //      adelante se podria implementar que se chequeen los valores del archivo.
  //      Si se respetara de usar el calibradorCEGHconEnsemble no se deberian
  //      dar errores.

  validoParaGuardar := validarFormulario;

  if validoParaGuardar then
  begin
    if valorCBArchiRef(cbArchiRef) <> nil then
      archiref := valorCBArchiRef(cbArchiRef).ArchiRef.get_archi
    else
      archiref := '';
    if valorCBArchiRef(cbArchiRef_DatHisto) <> nil then
      archiref_DatHisto := valorCBArchiRef(cbArchiRef_DatHisto).ArchiRef.get_archi
    else
      archiref_DatHisto := '';
    if valorCBArchiRef(cbArchiRef_ModAux) <> nil then
      archiref_ModAux := valorCBArchiRef(cbArchiRef_ModAux).ArchiRef.get_archi
    else
      archiref_ModAux := '';

    if cosaConNombre = nil then
    begin
      cosaConNombre := TFuenteSintetizadorCEGH.Create(
        capa, ENombre.Text, archiref, archiref_DatHisto,
        cbSimularUsandoDatosHistoricos.Checked, cbSincronizarConHistoricos.Checked,
        cbSincronizarConSemillaAleatoria.Checked, archiref_ModAux,
        cbUsarModeloAuxiliarParaOpt.Checked, self.escenariosDePronosticos,
        cbResumirPromediando.Checked, eurl_get.Text, self.flg_MODELO_ENTRADA_SALIDA,
        self.listaFuentesEntrada, self.flg_modo_cono);
      RellenarListaEntradas;
    end
    else
    begin
      fuente := TFuenteSintetizadorCEGH(cosaConNombre);
      fuente.nombre := ENombre.Text;
      fuente.nombreArchivoModelo := valorCBArchiRef(cbArchiRef);
      fuente.nombreArchivoDatosHistoricos := valorCBArchiRef(cbArchiRef_DatHisto);
      fuente.simularConDatosHistoricos := cbSimularUsandoDatosHistoricos.Checked;
      fuente.sincronizarConHistoricos := cbSincronizarConHistoricos.Checked;
      fuente.SincronizarConSemillaAleatoria := cbSincronizarConSemillaAleatoria.Checked;
      fuente.nombreArchivoModeloAuxiliar := valorCBArchiRef(cbArchiRef_ModAux);
      fuente.usarModeloAuxiliar := cbUsarModeloAuxiliarParaOpt.Checked;
      fuente.ResumirPromediando := cbResumirPromediando.Checked;
      fuente.escenariosDePronosticos.Free;
      fuente.escenariosDePronosticos := self.escenariosDePronosticos;
      fuente.url_get := eurl_get.Text;
      fuente.InitModeloFromFile;
      fuente.capa := capa;
      fuente.flg_modo_cono := flg_modo_cono;

      {$IFDEF  MODELO_ENTRADA_SALIDA}
      //      fuente.fuenteIN := valorCBFuente(CBFuenteIN);
      //      fuente.borneIN := valorCBString(CBBorneIN);
      fuente.fuentesEntrada := listaFuentesEntrada;
      fuente.flg_MODELO_ENTRADA_SALIDA := flg_MODELO_ENTRADA_SALIDA;
      //      mostrarListaEntradas;
      //     RellenarListaEntradas;

      {$ENDIF}
    end;

    ModalResult := mrOk;
  end;
end;

procedure TEditarFuenteSintetizador.BAyudaClick(Sender: TObject);
begin
  verdoc(3827, TFuenteSintetizadorCEGH);
end;


procedure TEditarFuenteSintetizador.btGraficarPronosticosClick(Sender: TObject);
var
  fcegh: TFuenteSintetizadorCEGH;
  escenario_aux: TEscenarioDePronosticos;

  SeriesCono: TSeriesConoPronostico;
  fechaIniSim, fechaFinSim: TFecha;
  hayCambios, hayErrores, validoParaGuardar: boolean;
  NPasosT: integer;
  Catalogo: TCatalogoReferencias;
  archi_Modelo, archi_DatosHistoricos, archi_ModeloAux: string;
begin
  {$IFDEF CALIBRAR_PRONOSTICOS_TRAZOSXY}
  if flg_GraficosActivos then
    CerrarTodosLosGraficos;
  {$ENDIF}


  fcegh := nil;
  escenario_aux := nil;
  Catalogo := nil;

  //  if flg_modo_cono = 1 then
  //     validoParaGuardar := True
  //  else
  validoParaGuardar := validarFormulario;

  if validoParaGuardar then
  begin
    if valorCBArchiRef(cbArchiRef) <> nil then
      archi_Modelo := valorCBArchiRef(cbArchiRef).ArchiRef.get_archi
    else
      archi_Modelo := '';
    if valorCBArchiRef(cbArchiRef_DatHisto) <> nil then
      archi_DatosHistoricos := valorCBArchiRef(cbArchiRef_DatHisto).ArchiRef.get_archi
    else
      archi_DatosHistoricos := '';
    if valorCBArchiRef(cbArchiRef_ModAux) <> nil then
      archi_ModeloAux := valorCBArchiRef(cbArchiRef_ModAux).ArchiRef.get_archi
    else
      archi_ModeloAux := '';

    if flg_modo_cono <> 1 then
    begin
      hayErrores := False;
      hayCambios := False;
      dump_pronosticos(hayCambios, hayErrores);
      if hayCambios then
        self.guardado := False;
      if hayErrores then
        exit;

      if (eNPasosPlot.Text <> '') and (StrToInt(eNPasosPlot.Text) > 0) then
        NPasosT := StrToInt(eNPasosPlot.Text)
      else
      begin
        MessageDlg('Info', 'El número de pasos a graficar debe ser mayor a 0.',
          mtInformation, [mbClose], 0);
        Exit;
      end;
      Catalogo := TCatalogoReferencias.Create;
      escenario_aux := escenariosDePronosticos.Create_Clone(Catalogo, 0) as
        TEscenarioDePronosticos;

      fcegh := TFuenteSintetizadorCEGH.Create(capa, ENombre.Text,
        archi_Modelo, archi_DatosHistoricos,
        cbSimularUsandoDatosHistoricos.Checked,
        cbSincronizarConHistoricos.Checked,
        cbSincronizarConSemillaAleatoria.Checked, archi_ModeloAux,
        cbUsarModeloAuxiliarParaOpt.Checked, escenario_aux,
        cbResumirPromediando.Checked, eurl_get.Text, flg_MODELO_ENTRADA_SALIDA,
        nil );

    end
    else
    begin
      if (eNPasosPlot.Text <> '') and (StrToInt(eNPasosPlot.Text) > 0) then
        NPasosT := StrToInt(eNPasosPlot.Text)
      else
      begin
        MessageDlg('Info', 'El número de pasos a graficar debe ser mayor a 0.',
          mtInformation, [mbClose], 0);
        Exit;
      end;
      Catalogo := TCatalogoReferencias.Create;
      escenario_aux := escenariosDePronosticos.Create_Clone(Catalogo, 0) as
        TEscenarioDePronosticos;
      fcegh := TFuenteSintetizadorCEGH.Create(capa, ENombre.Text,
        archi_Modelo, archi_DatosHistoricos, False, False,
        cbSincronizarConSemillaAleatoria.Checked, archi_ModeloAux,
        False, escenario_aux, cbResumirPromediando.Checked, eurl_get.Text,
        flg_MODELO_ENTRADA_SALIDA, listaFuentesEntrada);
    end;

    fechaIniSim := TFecha.Create_Clone(sala.globs.fechaIniSim);
    fechaFinSim := TFecha.Create_Clone(fechaIniSim);
    fechaFinSim.addHoras(NPasosT * fcegh.durPasoDeSorteoEnHoras);

    SeriesCono := TSeriesConoPronostico.CreateFromSim(
      0, fcegh, fechaIniSim, fechaFinSim, 100, 0.05, 0.95);

  {$IFDEF CALIBRAR_PRONOSTICOS_TRAZOSXY}
    SeriesCono.plot(self);
    SeriesCono.Free;
    SeriesCono:= nil;
    flg_GraficosActivos := True;
  {$EndIf}
    fcegh.Free;
    fcegh := nil;
    Catalogo.Free;
    Catalogo := nil;
  end;

end;

procedure TEditarFuenteSintetizador.btGetPronosticosClick(Sender: TObject);
var
  fcegh: TFuenteSintetizadorCEGH;
  pronosticos_aux: TPronosticos;
  SeriesCono: TSeriesConoPronostico;
  fechaIniSim, fechaFinSim: TFecha;
  hayCambios, hayErrores: boolean;
  NPasosT: integer;
  bProno: TPronostico;

  Catalogo: TCatalogoReferencias;
  esc_pronosticos_aux: TPronosticos;
  fuente: TFuenteSintetizadorCEGH;
  NSeries: integer;
  kSerie: integer;
  aRecCono: TRecConoPronosticos;
  kIni: integer;
  aSerie: TDAOfNReal;
  dtIniSim: TDateTime;
  dtPrimeraMuestra: TDateTime;
  dtEntreMuestras: TDateTime;
  nDatos: integer;
  kDato: integer;

  s: string;
  nueva_guia: TDAOfNReal;

begin

  if cegh = nil then
  begin
    ShowMessage(
      'Necesita guardar y volver abrir este formulario para que esté bien definida la fuente'
      );
    exit;
  end;
  hayErrores := False;
  hayCambios := False;
  dump_pronosticos(hayCambios, hayErrores);
  if hayCambios then
    self.guardado := False;
  if hayErrores then
    exit;



  //  strUrl := 'http://pronos.adme.com.uy/getcono.php?dtIniSim=' + FloatToStr( dtIni);

  bProno := escenariosDePronosticos.items[0].items[0];

  dtIniSim := sala.globs.fechaIniSim.dt - (cegh.CalcOrdenDelFiltro - 1) *
    cegh.durPasoDeSorteoEnHoras / 24.0;
  aRecCono := TRecConoPronosticos.Create(self.eurl_get.Text +
    '?dtIniSim=' + FloatToStr(sala.globs.fechaIniSim.dt));
  nDatos := length(aRecCono.series[0]);
  kIni := round((dtIniSim - aRecCono.dtPrimeraMuestra) * 24 /
    aRecCono.HorasEntreMuestras);

  // la primer serie del cono es un timestamp ... la salteo
  for kSerie := 1 to high(aRecCono.series) do
  begin
    aSerie := aRecCono.series[kSerie];
    setlength(nueva_guia, length(aSerie) - kIni);
    for kDato := kIni to high(aSerie) do
      nueva_guia[kDato - kIni] := aSerie[kDato];
    cambiar_guia(kSerie - 1, nueva_guia);
    setlength(nueva_guia, 0);
  end;


    (**

     Catalogo:= TCatalogoReferencias.Create;
     esc_pronosticos_aux := escenarioDePronosticos.Create_Clone( Catalogo, 0 ) as TPronosticos;// pronosticos.Create_Clone as TPronosticos;

    fcegh := TFuenteSintetizadorCEGH.Create(capa, ENombre.Text,
      ENArch.Text, EArchiDatosHistoricos.Text, cbSimularUsandoDatosHistoricos.Checked,
      cbSincronizarConHistoricos.Checked, cbSincronizarConSemillaAleatoria.Checked,
      eArchiModeloAuxiliar.Text, cbUsarModeloAuxiliarParaOpt.Checked,
      esc_pronosticos_aux, cbResumirPromediando.Checked, eurl_get.text );
    //fcegh:= escenarioDePronosticos.items[0].xcegh;

    fcegh.PrepararMemoria( Catalogo, sala.globs );
    if fcegh.GetPronosticos( sala.globs.fechaIniSim ) then
    begin
       escenarioDePronosticos.Free;
       escenarioDePronosticos:= fcegh.escenarioDePronosticos.Create_Clone( Catalogo, 0 ) as TPronosticos;
       bProno:= escenarioDePronosticos.items[0].items[0];
       guardado:= false;
    end
    else
      showmessage( 'Imposible obtener los pronósticos.' );
    fcegh.Free;

     Catalogo.Free;

    **)

  populate_Pronosticos;
end;



procedure TEditarFuenteSintetizador.CopiadoYPegadoDeterminismos(Sender: TObject;
  var Key: word; Shift: TShiftState);
var
  stringAParsear: string;
begin
  if (((ssCtrl in Shift) and (Key = Ord('V'))) or
    ((ssShift in Shift) and (Key = VK_INSERT))) then
  begin
    if Clipboard.HasFormat(CF_TEXT) then
      ClipBoard.Clear;
    stringAParsear := Clipboard.AsText;
    stringAParsear := StringReplace(stringAParsear, #9, ';', [rfReplaceAll]);
    //Saco los tabs
    stringAParsear := StringReplace(stringAParsear, #13#10, '', [rfReplaceAll]);
    //La porqueria esta viene con un enter al final
    TEdit(Sender).Text := stringAParsear;
    Key := 0;
  end;

  if (((ssCtrl in Shift) and (Key = Ord('C'))) or
    ((ssCtrl in Shift) and (Key = VK_INSERT))) then
  begin
    if Clipboard.HasFormat(CF_TEXT) then
      ClipBoard.Clear;
    stringAParsear := TEdit(Sender).Text;
    stringAParsear := StringReplace(stringAParsear, ';', #9, [rfReplaceAll]);
    //Pongo los tabs
    Clipboard.AsText := stringAParsear;
    Key := 0;
  end;
end;

procedure TEditarFuenteSintetizador.BAyudaTipoEsclavizadorClick(Sender: TObject);
begin
  verdoc(3827, TEsclavizador);
end;

procedure TEditarFuenteSintetizador.FormCreate(Sender: TObject);
begin
  flg_GraficosActivos := False;
end;



initialization
  trx := nil;
end.
