unit uListadoProblemasODDFACE;

{$mode delphi}

interface

uses
  SysUtils, Classes, Controls,
  Forms,
  Graphics,
  urosx,
  uDataSetGenerico,
  uvisordetabla,
  StdCtrls,
  uempaquetar,
  uconstantesSimSEE, unotificar, u_editorproblema,
  uoddface_consultar,
  u_updownload, uListadoProblemas;

type

  { TListadoProblemasODDFACE }

  TListadoProblemasODDFACE = class(TListadoProblemas)
  public
    constructor Create(dbconx: TDBrosxCon; AOwner: TComponent; Name: string ); reintroduce;
    procedure Editar_onClick(nidRec: string; kFila: integer); override;
    procedure SemaforoRojo_OnClick(nidRec: string; kFila: integer); override;
    procedure SemaforoVerde_OnClick(nidRec: string; kFila: integer); override;
    procedure Lupa_OnClick(nidRec: string; kFila: integer); override;
    procedure clonar_OnClick(nidRec: string; kFila: integer); override;
    procedure Populate; override;
    class function CrearNuevoProblema( dbconx: TDBrosxCon ): integer;
    procedure eliminarProblema( nidCarpeta: string ); override;
  end;


implementation

uses
  uoddface_prepare;

procedure CrearTabla_Inidviduos(dbcon: TDBrosxCon; nid_Problema: integer);
var
  sql: string;
  tabla: string;

begin
  tabla:= 'ofe_individuos_' + IntToStr( nid_problema) ;

  if dbcon.TipoServidor= CTS_PostgreSQL then
  begin
    sql := 'CREATE TABLE ' + tabla+ ' ('
       + '  nid SERIAL,'
       + '  adn bytea,'
       + '  dtc timestamp DEFAULT CURRENT_DATE,'
       + '  dtu timestamp DEFAULT CURRENT_DATE,'
       + '  f_VE double precision NOT NULL,'
       + '  f_CVaR double precision NOT NULL,'
       + '  f_VaR double precision NOT NULL,'
       + '  f_Objetivo double precision NOT NULL,'
       + '  f_MIN double precision NOT NULL,'
       + '  f_MAX double precision NOT NULL,'
       + '  cnt_evaluaciones int NOT NULL,'
       + '  detalle bytea NOT NULL,'
       + '  UNIQUE ( adn )'
       + ');';
     dbcon.sql_exec(sql);

     sql:= 'CREATE INDEX ' + tabla +'_idx_fo ON '+tabla+' ( f_objetivo );';
     dbcon.sql_exec(sql);
  end
  else
  begin
    // atención en mysql el adn se limita a 750 porque sino no se puede definir el índice.
  sql := 'CREATE TABLE `' + tabla + '` ('
  + '  `nid` int(11) NOT NULL,'
  + '  `adn` varbinary( 750 ) NOT NULL,'
  + '  `dtc` datetime NOT NULL,'
  + '  `dtu` datetime NOT NULL,'
  + '  `f_VE` double NOT NULL,'
  + '  `f_CVaR` double NOT NULL,'
  + '  `f_VaR` double NOT NULL,'
  + '  `f_Objetivo` double NOT NULL,'
  + '  `f_MIN` double NOT NULL,'
  + '  `f_MAX` double NOT NULL,'
  + '  `cnt_evaluaciones` int(11) NOT NULL,'
  + '  `detalle` blob NOT NULL,'
  + '  PRIMARY KEY  (`nid`),'
  + '  UNIQUE KEY `iadn` (`adn`),'
  + '  KEY `ifo` (`f_objetivo`)'
  + ');';
    dbcon.sql_exec(sql);
  end;

end;



class function TListadoProblemasODDFACE.CrearNuevoProblema(dbconx: TDBrosxCon
  ): integer;
var

  nid_problema: integer;
  sql: string;
  str_nombres, str_valores: string;
begin

  nid_problema := dbconx.sql_nextnid('ofe_problemas');

  AppendToInsertStr(str_nombres, str_valores, 'nid', IntToStr(nid_problema));

  AppendToInsertStr(str_nombres, str_valores, 'usuario', '0');
  AppendToInsertStr(str_nombres, str_valores, 'llave', '0');
  AppendToInsertStr(str_nombres, str_valores, 'dt_creacion', 'now()', False);
  AppendToInsertStr(str_nombres, str_valores, 'tipo', '0');

  AppendToInsertStr(str_nombres, str_valores, 'ro_VE', '1.0');
  AppendToInsertStr(str_nombres, str_valores, 'ro_VaR', '0.0');
  AppendToInsertStr(str_nombres, str_valores, 'ro_CVaR', '0.0');

  AppendToInsertStr(str_nombres, str_valores, 'N_CronicasPorVez', '100');
  AppendToInsertStr(str_nombres, str_valores, 'N_DiscretizacionesHistograma', '100');
  AppendToInsertStr(str_nombres, str_valores, 'semilla_madre', '31');

  AppendToInsertStr(str_nombres, str_valores, 'ro_GA', '0.95');
  AppendToInsertStr(str_nombres, str_valores, 'ro_EG', '0.00');
  AppendToInsertStr(str_nombres, str_valores, 'ro_MJ', '0.05');

  AppendToInsertStr(str_nombres, str_valores, 'GA_prob_premio_exito', '0.05');
  AppendToInsertStr(str_nombres, str_valores, 'GA_prob_mutacion', '0.01');
  AppendToInsertStr(str_nombres, str_valores, 'descripcion', '');

  AppendToInsertStr(str_nombres, str_valores, 'grupo', IntToStr( dbconx.usuario_grupo ) );


  sql := 'INSERT INTO ofe_problemas ( ' + str_nombres + ' ) VALUES ( ' + str_valores + ' ) ';

  dbconx.sql_exec(sql);

  CrearTabla_Inidviduos(dbconx, nid_Problema);

  Result := nid_problema;
end;





procedure TListadoProblemasODDFACE.eliminarProblema( nidCarpeta: string );
var
  pathCarpeta: String;
  sql: string;
begin

    pathCarpeta:= dbcon.sql_func('SELECT path FROM ofe_carpetas WHERE nid = ' + nidCarpeta );


   if dbcon.tipoServidor = CTS_MySQL then
     sql:= 'DELETE ofe_archivos_bloques FROM ofe_archivos_bloques '
       +' LEFT JOIN ofe_archivos ON ofe_archivos_bloques.nid_archivo = ofe_archivos.nid '
       +' WHERE ofe_archivos.nid_carpeta = ' + nidCarpeta
   else
     sql:= 'DELETE FROM ofe_archivos_bloques USING ofe_archivos '
        +' WHERE ofe_archivos_bloques.nid_archivo = ofe_archivos.nid AND ofe_archivos.nid_carpeta='+ nidCarpeta;


   if not dbcon.sql_exec( sql ) then
    raise Exception.Create( dbcon.UltimoError );

    sql:= 'DELETE FROM ofe_archivos WHERE nid_carpeta = ' + nidCarpeta;
    if not dbcon.sql_exec( sql ) then
      raise Exception.Create( dbcon.UltimoError );

    sql:= 'DELETE FROM ofe_carpetas WHERE nid = ' + nidCarpeta;
    if not dbcon.sql_exec( sql ) then
      raise Exception.Create( dbcon.UltimoError );

    sql:= 'DROP TABLE IF EXISTS ofe_individuos_'+  nidCarpeta ;
    dbcon.sql_exec( sql );
//      raise Exception.Create( urosx.UltimoError );



   sql:= 'DELETE FROM ofe_PIG_tecnologias WHERE nid_problema = ' + nidCarpeta;
   if not dbcon.sql_exec( sql ) then
    raise Exception.Create( dbcon.UltimoError );

   sql:= 'DELETE FROM ofe_PAM_ordenes WHERE nid_problema = ' + nidCarpeta;
   if not dbcon.sql_exec( sql ) then
    raise Exception.Create( dbcon.UltimoError );

   sql:= 'DELETE FROM ofe_RedCEGH_data WHERE nid_problema = ' + nidCarpeta;
   if not dbcon.sql_exec( sql ) then
    raise Exception.Create( dbcon.UltimoError );

   sql := 'DELETE FROM ofe_OptimA WHERE nid_problema = ' + nidCarpeta;
   if not dbcon.sql_exec(sql) then
     raise Exception.Create( dbcon.UltimoError);

    sql:= 'DELETE FROM ofe_problemas WHERE nid = ' + nidCarpeta;
    if not dbcon.sql_exec( sql ) then
      raise Exception.Create( dbcon.UltimoError );
end;


procedure TListadoProblemasODDFACE.Populate;
var
  k: integer;
  snid: string;
  ds: TResultadoQuery;
  r: TDataRecord;
  estado: integer;

begin
  flg_populate := False;
  ds := dbcon.Query(
    'SELECT nid, dt_creacion, tipo, descripcion,  estado FROM ofe_problemas WHERE grupo='+IntToStr( dbcon.usuario_grupo )+' ORDER BY nid DESC');
  if ds = nil then
    raise Exception.Create(dbcon.ultimoError);

  ClearRedim(ds.nrows + 1, 7);
  // fila encabezado
  wrTexto('', 0, 0, 'NID');
  wrTexto('', 0, 1, 'dt_creacion');
  wrTexto('', 0, 2, 'tipo');
  wrTexto('', 0, 3, 'Descripcion');

  AlinearCelda(0, 0, CAH_Izquierda, CAV_Centro);
  AlinearCelda(0, 1, CAH_Izquierda, CAV_Centro);
  AlinearCelda(0, 2, CAH_Izquierda, CAV_Centro);
  AlinearCelda(0, 3, CAH_Izquierda, CAV_Centro);


  Self.SetBgColorFila(0, clNavy);
  Self.SetFontColorFila(0, clYellow);

  Self.SetBgColorCelda(0, 0, clNavy);
  Self.SetBgColorCelda(0, 1, clNavy);

  k := 1;
  r := ds.First;
  while not ds.EOF do
  begin
    snid := r.GetByIdAsString(0);
    estado := r.GetByNameAsInt('estado');
    wrTexto('', k, 0, r.GetByNameAsString('nid'));
    wrTexto('', k, 1, r.GetByNameAsString('dt_creacion'));
    wrTexto('', k, 2, r.GetByNameAsString('tipo'));
    wrTexto('', k, 3, r.GetByNameAsString('descripcion'));
    AlinearCelda(k, 0, CAH_Izquierda, CAV_Centro);
    AlinearCelda(k, 1, CAH_Izquierda, CAV_Centro);
    AlinearCelda(k, 2, CAH_Izquierda, CAV_Centro);
    AlinearCelda(k, 3, CAH_Izquierda, CAV_Centro);

    // ahora la botonera en la última columna

    wrBotonera(snid, k, 4,
      [iid_fdownload, iid_Editar, iid_borrar, iid_clonar],
      [hintPorDefecto(iid_fdownload),
      hintPorDefecto(iid_Editar),
      hintPorDefecto(iid_Borrar),
      hintPorDefecto(iid_clonar)]);


    if (estado <= 0) then
      wrBotonera(snid, k, 5, [iid_SemaforoRojo, iid_Lupa], ['Activar', 'Consultar'])
    else
      wrBotonera(snid, k, 5, [iid_SemaforoVerde, iid_Lupa], ['Desactivar',
        'Consultar']);


    if (k mod 2) = 0 then
      if estado <= 0 then
        SetBgColorFila(k, clFondoFilaPar_Inactiva)
      else
        SetBgColorFila(k, clFondoFilaPar_Activa)
    else
    if estado <= 0 then
      SetBgColorFila(k, clFondoFilaImpar_Inactiva)
    else
      SetBgColorFila(k, clFondoFilaImpar_Activa);

    Inc(k);
    r := ds.Next;
  end;
  reposicionar;
end;


constructor TListadoProblemasODDFACE.Create(dbconx: TDBrosxCon; AOwner: TComponent; Name: string );
begin
  inherited Create(dbconx, AOwner, Name );
end;

procedure TListadoProblemasODDFACE.Editar_onClick(nidRec: string; kFila: integer);
var
  ufp: TForm_EditorProblema;
  res: integer;

begin

  ufp := TForm_EditorProblema.Create(self, dbcon);

  ufp.LoadRec(StrToInt(nidRec));
  res := ufp.ShowModal;
  if res > 0 then
  begin
    flg_populate := True;
    invalidate;
  end;
  ufp.Free;

end;


procedure TListadoProblemasODDFACE.SemaforoRojo_OnClick(nidRec: string; kFila: integer);
var
  sql: string;
begin
  sql := 'UPDATE ofe_problemas SET estado = 1 - estado  WHERE nid = ' + nidRec;
  dbcon.sql_exec(sql);
  flg_populate := True;
  invalidate;
end;

procedure TListadoProblemasODDFACE.SemaforoVerde_OnClick(nidRec: string; kFila: integer);
var
  sql: string;
begin
  sql := 'UPDATE ofe_problemas SET estado = - estado WHERE nid = ' + nidRec;
  dbcon.sql_exec(sql);
  flg_populate := True;
  invalidate;
end;

procedure TListadoProblemasODDFACE.Lupa_OnClick(nidRec: string; kFila: integer);
var
  fc: TConsultar;
begin
  fc := TConsultar.Create(self, dbcon);
  fc.eFrom.Text := 'ofe_individuos_' + nidRec;
  fc.nidProblema := StrToInt(nidRec);
  fc.ShowModal;
  fc.Free;
end;


procedure TListadoProblemasODDFACE.clonar_OnClick(nidRec: string; kFila: integer);
var
  nid_problema_destino, nid_problema_origen: integer;
  sql: string;

begin
  nid_problema_origen := StrToInt(nidRec);
  nid_problema_destino := dbcon.clonar_rec('ofe_problemas', nid_problema_origen,
    -1, 'estado=0, dt_creacion=now()');

  // cada problema tiene una carpeta con el mismo nid del problema.
  dbcon.clonar_rec('ofe_carpetas', nid_problema_origen, nid_problema_destino, '');

{
  // Clonamos los archivos que pudiera tener la carpeta
  dbcon.clonar_hijas('ofe_carpetas', 'ofe_archivos', 'nid_carpeta',
    nid_problema_origen, nid_problema_destino);
 }
   dbcon.clonar_hijas_y_nietas(
   // 'ofe_carpetas',
    'ofe_archivos', 'ofe_archivos_bloques', 'nid_carpeta', 'nid_archivo',
   nid_problema_origen, nid_problema_destino);


  // Clonamos los PIGs
  dbcon.clonar_hijas(
  //'ofe_problemas',
  'ofe_PIG_tecnologias', 'nid_problema',
    nid_problema_origen, nid_problema_destino);

  // Clonamos los PAMs
  dbcon.clonar_hijas(
   //'ofe_problemas',
   'ofe_PAM_ordenes', 'nid_problema',
    nid_problema_origen, nid_problema_destino);


  // Clonamos los RedCEGH s
  dbcon.clonar_hijas(
   //'ofe_problemas',
   'ofe_RedCEGH_data', 'nid_problema',
    nid_problema_origen, nid_problema_destino);


  // Clonamos los OptimA s
  dbcon.clonar_hijas(
  //'ofe_problemas',
  'ofe_OptimA', 'nid_problema',
    nid_problema_origen, nid_problema_destino);


  // creamos la tabla par el historial de evaluaciones
  CrearTabla_Inidviduos(dbcon, nid_Problema_destino);

  sql:=   'INSERT INTO ofe_individuos_'+IntToStr( nid_problema_destino )
+' (adn, f_ve, f_cvar, f_var, f_objetivo, f_min, f_max, cnt_evaluaciones, detalle ) '
+' SELECT  adn, 0,0,0,0,0,0,-1, 	'''' FROM ofe_individuos_'
+ IntToStr( nid_problema_origen )
+' ORDER BY f_Objetivo LIMIT 100 ';
  dbcon.sql_exec( sql );

  Editar_onClick(IntToStr(nid_problema_destino), 0);
end;

end.


