unit uEditarUnidades;

  {$MODE Delphi}

interface

uses
  {$IFDEF WINDOWS}
  Windows,
  {$ELSE}
  LCLType,
  {$ENDIF}
  // Messages,
  SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, Grids, ExtCtrls, ComCtrls, uBaseFormularios, uActores,
  utilidades, ufichasLPD,
  uunidades,
  usalasdejuegoParaEditor,
  uEditarFichaUnidades, uCosa, uVisorFichasExpandidas, uCosaConNombre,
  uverdoc,
  uopencalc,
  uSalasDeJuego, uConstantesSimSEE,
  uFechas,
  uAuxiliares, xMatDefs, Types;

resourcestring
  rsCapa = 'Capa';
  rsFechaDeInicio = 'Fecha de Inicio';
  rsNumeroDeMaquinas_Instaladas = 'Instaladas';
  rsNumeroDeMaquinas_EnMantenimiento = 'En M.Prog.';
  rsPeriodicaQ = 'Periodica?';
  mesConfirmaEliminarFicha = '¿Confirma que desea eliminar la ficha seleccionada?';
  mesActorDebeTener1Ficha =
    'El Actor debe tener al menos una ficha indicando la cantidad de unidades disponibles';

type

  { TEditarUnidades }

  TEditarUnidades = class(TBaseFormularios)
    BAgregarFicha: TButton;
    BAyuda: TButton;
    BCancelar: TButton;
    BGuardar: TButton;
    btExportar_ods: TButton;
    btImportar_ods: TButton;
    BVerExpandida: TButton;
    Panel2: TPanel;
    pb_EstadoImpExp: TProgressBar;
    sgUnidades: TStringGrid;
    procedure BAyudaClick(Sender: TObject);
    procedure BCancelarClick(Sender: TObject);
    procedure btExportar_odsClick(Sender: TObject);
    procedure btImportar_odsClick(Sender: TObject);
    procedure cb_AltaUnidades_CON_INCERTIDUMBREChange(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure Panel1Click(Sender: TObject);
    procedure Panel2Click(Sender: TObject);
    procedure pb_EstadoImpExpContextPopup(Sender: TObject; MousePos: TPoint;
      var Handled: boolean);
    procedure sgUnidadesDrawCell(Sender: TObject; ACol, ARow: integer;
      Rect: TRect; State: TGridDrawState);
    procedure sgUnidadesMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: integer);
    procedure sgUnidadesMouseMove(Sender: TObject; Shift: TShiftState;
      X, Y: integer);
    procedure sgUnidadesMouseUp(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: integer);
    procedure BAgregarFichaClick(Sender: TObject);
    procedure BGuardarClick(Sender: TObject); override;
    procedure BVerExpandidaClick(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: boolean);
    procedure sgUnidadesValidarCambio(Sender: TObject);
    procedure sgUnidadesGetEditText(Sender: TObject; ACol, ARow: integer;
      var Value: string);
  private
    lista_aux: TFichasLPD;
    actor: TActor;
    tiposColsUnidades: TDAOfTTipoColumna;


    function editar(fila: integer; clonar: boolean): boolean;
    procedure eliminar(fila: integer);
    procedure actualizarTablaUnidades;
    function validarCambioTablaUnidades(listado: TStringGrid;
      fila, columna: integer): boolean;
    procedure cambioValorTablaUnidades(listado: TStringGrid; fila, columna: integer);
  public
    etiquetasUnidades: TDAofString;
    constructor Create(AOwner: TControl; xsala: TSalaDeJuego;
      actor: TActor; listaUnidades: TFichasLPD; etiquetasUnidades: TDAofString);
      reintroduce;
    function darLista_: TFichasLPD;
  end;

implementation

uses ueditor_resourcestrings, SimSEEEditMain;

{$R *.lfm}

constructor TEditarUnidades.Create(AOwner: TControl; xsala: TSalaDeJuego;
  actor: TActor; listaUnidades: TFichasLPD; etiquetasUnidades: TDAofString);
var
  etiquetas: array of string;
begin
  inherited Create_conSalaYEditor_(AOwner, xsala);

  self.Top := AOwner.Top + plusTop;
  self.Left := AOwner.Left + plusLeft;

  listaUnidades.clearExpanded;
  lista_aux := listaUnidades.Create_Clone(rbtEditorSala.CatalogoReferencias, 0) as
    TFichasLPD;
  self.actor := actor;
  self.etiquetasUnidades := etiquetasUnidades;

  rbtEditorSala.CatalogoReferencias.resolver_referenciasDeCosa(
    lista_aux, sala.listaActores);
  rbtEditorSala.CatalogoReferencias.eliminar_referencias_del(lista_aux);

  //Aca escribo las etiquetas q salen en el formulario
  setlength(etiquetas, 8);
  etiquetas[0] := encabezadoTextoEditable + rsFechaDeInicio;
  etiquetas[1] := rsNumeroDeMaquinas_Instaladas;
  etiquetas[2] := rsNumeroDeMaquinas_EnMantenimiento;
  etiquetas[3] := rsPeriodicaQ;
  etiquetas[4] := rsCapa;
  etiquetas[5] := encabezadoBTEditar;
  etiquetas[6] := encabezadoBTEliminar;
  etiquetas[7] := encabezadoBTClonar;

  utilidades.initListado(sgUnidades, etiquetas, tiposColsUnidades, False);
  actualizarTablaUnidades;
  guardado := True;
end;

function TEditarUnidades.darLista_: TFichasLPD;
begin
  Result := lista_aux;
end;

function TEditarUnidades.editar(fila: integer; clonar: boolean): boolean;
var
  form: TEditarFichaUnidades;
  ficha: TFichaUnidades;
  res: boolean;
begin
  res := False;
  if fila = 0 then
    ficha := nil
  else
    ficha := TFichaUnidades(lista_aux[fila - 1]);

  form := TEditarFichaUnidades.Create(self, actor, ficha, nil, etiquetasUnidades);
  if form.ShowModal = mrOk then
  begin
    if ficha <> nil then
    begin
      if not clonar then
      begin
        lista_aux.Remove(ficha);
        ficha.Free;
      end;
    end;
    lista_aux.add(form.darFicha());
    actualizarTablaUnidades;
    guardado := False;
    res := True;
  end;
  form.Free;
  Result := res;
end;

procedure TEditarUnidades.eliminar(fila: integer);
begin
  if lista_aux.Count > 1 then
  begin
    if (Application.MessageBox(PChar(mesConfirmaEliminarFicha),
      PChar(mesConfirmarEliminacion), MB_OKCANCEL + MB_ICONEXCLAMATION) = idOk) then
    begin
      lista_aux[fila - 1].Free;
      lista_aux.Delete(fila - 1);
      actualizarTablaUnidades;
      guardado := False;
    end;
  end
  else
    ShowMessage(mesActorDebeTener1Ficha);
end;

procedure TEditarUnidades.actualizarTablaUnidades;
var
  i: integer;
  oldItemRow: TCosa;
begin
  if (sgUnidades.row > 0) and (sgUnidades.row < lista_aux.Count) then
    oldItemRow := lista_aux.items[sgUnidades.row - 1]
  else
    oldItemRow := nil;

  lista_aux.SortByFecha;

  sgUnidades.RowCount := lista_aux.Count + 1;
  if sgUnidades.RowCount > 1 then
    sgUnidades.FixedRows := 1
  else
    sgLimpiarSeleccion(sgUnidades);

  for i := 0 to lista_aux.Count - 1 do
  begin
    sgUnidades.cells[0, i + 1] :=
      FSimSEEEdit.fechaIniToString(TFichaUnidades(lista_aux[i]).fecha);
    sgUnidades.cells[1, i + 1] :=
      TDAOfNIntToStringSinTamanio(TFichaUnidades(lista_aux[i]).nUnidades_Instaladas, ';');
    sgUnidades.cells[2, i + 1] :=
      TDAOfNIntToStringSinTamanio(TFichaUnidades(lista_aux[i]).nUnidades_EnMantenimiento, ';');
    sgUnidades.Cells[3, i + 1] :=
      boolToSiNo(TFichaLPD(lista_aux[i]).periodicidad <> nil);
    sgUnidades.Cells[4, i + 1] := IntToStr(TFichaUnidades(lista_aux[i]).capa);
  end;

  for i := 0 to sgUnidades.ColCount - 1 do
    utilidades.AutoSizeTypedCol(sgUnidades, i, tiposColsUnidades[i], iconos);

  (*
  BAgregarFicha.Left := sgUnidades.Left + sgUnidades.Width - BAgregarFicha.Width;
  BVerExpandida.Left := BAgregarFicha.Left - BVerExpandida.Width - 10;
    *)

  if oldItemRow <> nil then
    sgUnidades.Row := lista_aux.IndexOf(oldItemRow) + 1;

end;

function TEditarUnidades.validarCambioTablaUnidades(listado: TStringGrid;
  fila, columna: integer): boolean;
begin
  case columna of
    0:
      Result := inherited validarCeldaFecha(listado, fila, columna);
    1:
      Result := inherited validarCeldaNInt(listado, fila, columna);
    else
      Result := True;
  end;
end;

procedure TEditarUnidades.cambioValorTablaUnidades(listado: TStringGrid;
  fila, columna: integer);
begin
  if columna = 0 then //Fecha
  begin
    TFichaUnidades(lista_aux[fila - 1]).fecha.Free;
    TFichaUnidades(lista_aux[fila - 1]).fecha :=
      StrToFecha(listado.Cells[columna, fila]);
    guardado := False;
    actualizarTablaUnidades;
  end
  else if columna = 1 then //NUnidades_Instaladas
  begin
    TFichaUnidades(lista_aux[fila - 1]).nUnidades_Instaladas[0] :=
      StrToInt(listado.Cells[columna, fila]);
    guardado := False;
  end
  else if columna = 2 then //NUnidades_EnMantenimiento
  begin
    TFichaUnidades(lista_aux[fila - 1]).nUnidades_EnMantenimiento[0] :=
      StrToInt(listado.Cells[columna, fila]);
    guardado := False;
  end;
end;

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




procedure exportarUnidadesAODS(Lista: TFichasLPD; bImportar: TButton;
  PBExportacion: TProgressBar);
var
  kfil, jCol: integer;
  ctipo: char;
  ts: string;
  cursorAnterior: TCursor;
  NFils: integer;
  NCols: integer;

  aFicha: TFichaUnidades;
  xls: TLibroOpenCalc;
begin

  // primero cheque si hay alguna ficha con periodicidad pues por ahora no
  // implemento exportar/importar con periodicidad.

  for kFil := 0 to lista.Count - 1 do
  begin
    aFicha := lista.f[kFil] as TFichaUnidades;
    if aFicha.periodicidad <> nil then
    begin
      ShowMessage('Lo siento, pero por ahora no está implementado exportar fichas con PERIODICIDAD');
      exit;
    end;
  end;


  aFicha := lista.f[0] as TFichaUnidades;
  NCols := length(aFicha.nUnidades_Instaladas);

  NFils := lista.Count;

  cursorAnterior := Screen.Cursor;
  Screen.Cursor := crHourGlass;
  if PBExportacion <> nil then
  begin
    PBExportacion.Min := 0;
    PBExportacion.Max := NCols;
    PBExportacion.Position := 0;
    PBExportacion.Step := 1;
  end;

  xls := TLibroOpenCalc.Create(True);
  try
    xls.go('x', 1, 1);

    xls.Write('capa');
    xls.Write('Fecha');
    for jCol := 1 to NCols do
    begin
      xls.Write('NU_Inst' + IntToStr(jCol));
      xls.Write('NU_EnMP' + IntToStr(jCol));
    end;
    for jCol := 1 to NCols do
      xls.Write('AI_' + IntToStr(jCol));
    for jCol := 1 to NCols do
      xls.Write('ICI_' + IntToStr(jCol));
    xls.writeln('');


    for kFil := 0 to NFils - 1 do
    begin
      aFicha := lista.f[kFil] as TFichaUnidades;

      xls.Write(aFicha.capa);
      xls.WriteDateTime(aFicha.fecha.AsDt);

      for jCol := 0 to NCols - 1 do
      begin
        xls.Write(aFicha.nUnidades_Instaladas[jCol]);
        xls.Write(aFicha.nUnidades_EnMantenimiento[jCol]);
      end;

      for jCol := 0 to NCols - 1 do
        xls.Write(boolToInt(aFicha.AltaConIncertidumbre[jCol]));
      for jCol := 0 to NCols - 1 do
        xls.Write(boolToInt(aFicha.InicioCronicaConIncertidumbre[jCol]));

      xls.writeln;

      if (PBExportacion <> nil) then
        PBExportacion.StepIt;
    end;

    xls.SelRango(1 + 1, 2, 1 + NFils, 2);
    xls.CambiarFormato(SysUtils.ShortDateFormat + ' hh');

    bImportar.Enabled := True;
    xls.VisibleOn;
    Screen.Cursor := cursorAnterior;
  except
    Screen.Cursor := cursorAnterior;
  end;
  xls.Free;
end;


procedure importarUnidadesDesdeODS(var lista: TFichasLPD; bImportar: TButton;
  PBImportacion: TProgressBar);
var
  encabsIguales: boolean;
  valCeldaReal: double;
  valCelda: string;
  cursorAnterior: TCursor;
  kFil, jCol: integer;
  NCols, NFils: integer;
  s: string;
  aFicha: TFichaUnidades;

  // auxiliares para armar las fichas
  capa: integer;
  dtfecha: TDateTime;
  fecha: TFecha;
  nUnidades_Instaladas, nUnidades_EnMantenimiento: TDAofNInt;
  AltaConIncertidumbre: TDAOfBoolean;
  InicioCronicaConIncertidumbre: TDAOfBoolean;

  res: TList;
  xls: TLibroOpenCalc;

begin
  aFicha := lista.f[0] as TFichaUnidades;
  NCols := length(aFicha.nUnidades_Instaladas);

  cursorAnterior := Screen.Cursor;
  Screen.Cursor := crHourGlass;

  bImportar.Enabled := False;
  xls := TLibroOpenCalc.Create(False);
  try
    xls.VisibleOff;
    xls.ActivoHoja_numero(1);
    encabsIguales := True;

    setlength(nUnidades_Instaladas, NCols);
    setlength(nUnidades_EnMantenimiento, NCols);
    setlength(AltaConIncertidumbre, NCols);
    setlength(InicioCronicaConIncertidumbre, NCols);


    NFils := 0;
    s := trim(xls.ReadStr(2 + NFils, 1 + NCols));
    while (NFils < 1000) and (s <> '') do
    begin
      Inc(NFils);
      s := trim(xls.ReadStr(2 + NFils, 1 + NCols));
    end;

    if PBImportacion <> nil then
    begin
      PBImportacion.Min := 0;
      PBImportacion.Max := NFils;
      PBImportacion.Position := 0;
      PBImportacion.Step := 1;
    end;


    res := TList.Create;

    xls.ir(1, 2);


    for kFil := 0 to NFils - 1 do
    begin
      capa := xls.ReadInt(2 + kFil, 1);
      dtFecha := xls.ReadFloat(2 + kFil, 2);
      Fecha := TFecha.Create_Dt(dtFecha);

      for jCol := 0 to NCols - 1 do
      begin
        s := trim(xls.ReadStr(2 + kFil, 3 + jCol * 2));
        nunidades_Instaladas[jCol] := StrToInt(s);
        s := trim(xls.ReadStr(2 + kFil, 3 + jCol * 2 + 1));
        nunidades_EnMantenimiento[jCol] := StrToInt(s);
      end;

      for jCol := 0 to NCols - 1 do
      begin
        s := trim(xls.ReadStr(2 + kFil, 3 + 2 * NCols + jCol));
        AltaConIncertidumbre[jCol] := s <> '0';
      end;

      for jCol := 0 to NCols - 1 do
      begin
        s := trim(xls.ReadStr(2 + kFil, 3 + 3 * NCols + jCol));
        InicioCronicaConIncertidumbre[jCol] := s <> '0';
      end;

      aFicha := TFichaUnidades.Create(capa, fecha, nil,
        nUnidades_Instaladas, nUnidades_EnMantenimiento, AltaConIncertidumbre,
        InicioCronicaConIncertidumbre);
      res.add(aFicha);
      if (PBImportacion <> nil) then
        PBImportacion.StepIt;
    end;
  finally
    Screen.Cursor := cursorAnterior;
  end;
  xls.Free;
  Screen.Cursor := cursorAnterior;
  lista.clearAll;
  for kFil := 0 to res.Count - 1 do
  begin
    aFicha := res[kFil];
    lista.insertar(aFicha);
  end;

  setlength(nUnidades_Instaladas, 0);
  setlength(nUnidades_EnMantenimiento, 0);
  setlength(AltaConIncertidumbre, 0);
  setlength(InicioCronicaConIncertidumbre, 0);
end;




procedure TEditarUnidades.btExportar_odsClick(Sender: TObject);
begin
  exportarUnidadesAODS(lista_aux,
    self.btImportar_ods,
    self.pb_EstadoImpExp);
end;

procedure TEditarUnidades.btImportar_odsClick(Sender: TObject);
begin
  importarUnidadesDesdeODS(lista_aux,
    self.btImportar_ods,
    self.pb_EstadoImpExp);
  actualizarTablaUnidades;
end;

procedure TEditarUnidades.BAyudaClick(Sender: TObject);
begin
  verdoc( 3826, TFichaUnidades);
end;

procedure TEditarUnidades.cb_AltaUnidades_CON_INCERTIDUMBREChange(Sender: TObject);
begin
  guardado := False;
end;

procedure TEditarUnidades.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  inherited FormClose(Sender, CloseAction);
end;

procedure TEditarUnidades.FormCreate(Sender: TObject);
begin

end;

procedure TEditarUnidades.Panel1Click(Sender: TObject);
begin

end;

procedure TEditarUnidades.Panel2Click(Sender: TObject);
begin

end;

procedure TEditarUnidades.pb_EstadoImpExpContextPopup(Sender: TObject;
  MousePos: TPoint; var Handled: boolean);
begin

end;

procedure TEditarUnidades.sgUnidadesDrawCell(Sender: TObject;
  ACol, ARow: integer; Rect: TRect; State: TGridDrawState);
begin
  utilidades.listadoDrawCell(Sender, ACol, ARow, Rect, State, tiposColsUnidades[ACol],
    nil, iconos, validarCambioTablaUnidades);
end;

procedure TEditarUnidades.sgUnidadesGetEditText(Sender: TObject;
  ACol, ARow: integer; var Value: string);
begin
  utilidades.listadoGetEditText(Sender, ACol, ARow);
end;



procedure TEditarUnidades.sgUnidadesValidarCambio(Sender: TObject);
begin
  utilidades.listadoValidarCambio(Sender, tiposColsUnidades,
    self.validarCambioTablaUnidades, self.cambioValorTablaUnidades);
end;

procedure TEditarUnidades.sgUnidadesMouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: integer);
begin
  utilidades.ListadoMouseDown(Sender, Button, Shift, X, Y);
end;

procedure TEditarUnidades.sgUnidadesMouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: integer);
begin
  utilidades.ListadoMouseMove(Sender, Shift, X, Y, tiposColsUnidades);
end;

procedure TEditarUnidades.sgUnidadesMouseUp(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: integer);
var
  res: TTipoColumna;
begin
  res := utilidades.ListadoMouseUp(Sender, Button, Shift, X, Y, tiposColsUnidades);
  case res of
    TC_btEditar: editar(TStringGrid(Sender).row, False);
    TC_btEliminar: eliminar(TStringGrid(Sender).row);
    TC_btClonar: if editar(TStringGrid(Sender).row, True) then
        sgUnidades.Row := sgUnidades.RowCount - 1;
  end;
end;

procedure TEditarUnidades.BAgregarFichaClick(Sender: TObject);
begin
  editar(0, False);
end;

procedure TEditarUnidades.BGuardarClick(Sender: TObject);
begin
  ModalResult := mrOk;
end;

procedure TEditarUnidades.BVerExpandidaClick(Sender: TObject);
var
  form: TVisorFichasExpandidas;
begin
  form := TVisorFichasExpandidas.Create(self, self.sala, actor, lista_aux);
  form.ShowModal;
end;

procedure TEditarUnidades.FormCloseQuery(Sender: TObject; var CanClose: boolean);
begin
  inherited FormCloseQuery(Sender, CanClose);
end;

end.
