{$DEFINE RETROCESO_BARRIDO}
unit uMonitorGraficoSimple;

interface

uses
  uMonitores, uVarDefs, SysUtils, utrazosxy, Controls, Classes,
  uconstantesSimSEE, Graphics;

type
  TDescSerie = class
  public
    nombre: string;
    color: TColor;
    varDef: TVarDef;
    constructor Create(nombre: string; color: TColor; varDef: TVarDef);
  end;


  //TMonGraficoSimple representa un monitor que representa los valores monitoreados
  //en un grafico. Esta versión debe tener valores en el eje de las x con diferencias
  //constantes y ademas la cantidad de puntos a dibujar debe coincidir con la
  //cantidad de puntos calculados

  TMonGraficoSimple = class(TMonitores)
  private
    xIni: integer;
      {$IFDEF RETROCESO_BARRIDO}
    xFin: integer;
      {$ENDIF}
    pasoX: integer;
    diffX: integer;
    MaxNPuntos: integer;
    seriesy: TDAOfVarDef;
    posEnSala: integer;
  public
    ventanaGrafico: TfrmDllForm;

    constructor Create(AOwner: TWinControl; nombreGrafico: string;
      MaxNPuntos: integer; nombre_sx: string; xetiquetax, xetiquetay: string;
      x1, x2, y1, y2: double; NDivisionesX, NDivisionesY: integer;
      xIni: integer; diffX: integer; seriesy: TList; // of TDescSerie;
      xgrilla: boolean; xposEnSala: integer);

    //AOwner es el dueño de la ventana que contendra al gráfico.
    //cosa y defVar son la cosa que voy a monitorear y la definición de la variable
    //MaxNPuntos es la maxima cantidad de números que se van a almacenar
    //Circular indica si la memoria es circular
    //nombre_sx y nombre_sy son los nombres de las series x e y respectivamente
    //color_sy1 es el color de la serie y
    //x1 y x2 ; y y1 e y2 son los limites en donde se van a dibujar los puntos
    //de las series
    //NDivisionesX y NDivisionesY son la cantidad de marcas divisorias en el espacio
    //dibujado de cada serie, no tiene que ver con los puntos donde se calculan
    //los valores
    //xIni es el valor inicial de la serie x.
    //diffX es la diferencia entre dos valores consecutivos de la serie x

    function resolverRefProc(refProc: integer): TProcWrapper; override;
    procedure Graficar;
    procedure Limpiar;
    procedure Free; override;
  end;


implementation

//----------------------
// Métodos de TDescSerie
//======================

constructor TDescSerie.Create(nombre: string; color: TColor; varDef: TVarDef);
begin
  self.nombre := nombre;
  Self.color := color;
  self.varDef := varDef;
end;

//-----------------------------
// Métodos de TMonGraficoSimple
//=============================

constructor TMonGraficoSimple.Create(AOwner: TWinControl;
  nombreGrafico: string; MaxNPuntos: integer; nombre_sx: string;
  xetiquetax, xetiquetay: string; x1, x2, y1, y2: double;
  NDivisionesX, NDivisionesY: integer; XIni: integer; diffX: integer;
  seriesy: TList; xgrilla: boolean; xposEnSala: integer);
var
  serie: TDescSerie;
  i: integer;
begin
  if seriesy.Count <= 0 then
    raise Exception.Create('El monitor gráfico de ' + xetiquetay +
      ' contra ' + xetiquetax + ' no tiene ninguna serie Y');
  inherited Create;
  ventanaGrafico := TfrmDllForm.Create(AOwner);
  posEnSala := xposEnSala;

  SetLength(self.seriesy, seriesy.Count);
  serie := seriesy[0];
  self.seriesy[0] := serie.varDef;
  ventanaGrafico.CrearDiagramaXY(nombreGrafico, MaxNPuntos, True, nombre_sx,
    serie.nombre, serie.color, x1, x2, y1, y2, NDivisionesX,
    NDivisionesY, seriesY.Count);
  for i := 1 to seriesy.Count - 1 do
  begin
    serie := seriesy[i];
    self.seriesy[i] := serie.varDef;
    ventanaGrafico.CrearSerieXY(serie.nombre, MaxNPuntos, True, serie.color);
    serie.Free;
  end;
  seriesy.Free;

  ventanaGrafico.xlabel(xetiquetax);
  ventanaGrafico.ylabel(xetiquetay);
  ventanaGrafico.Etiquetas_x(x1, x2);
  ventanaGrafico.Etiquetas_y(y1, y2);
  ventanaGrafico.titulo(nombreGrafico);

  ventanaGrafico.Show;

  ventanaGrafico.dbj_xlabel;
  ventanaGrafico.dbj_ylabel;
  ventanaGrafico.dbj_titulo;
  ventanaGrafico.dbj_etiquetasx;
  ventanaGrafico.dbj_etiquetasy;
  ventanaGrafico.dbj_borde;

  if xgrilla then
  begin
    ventanaGrafico.dbj_gridX;
    ventanaGrafico.dbj_gridY;
  end;

  ventanaGrafico.BringToFront;
  self.xIni := xIni;
  pasoX := xIni;
  self.diffX := diffX;
  self.MaxNPuntos := MaxNPuntos;
{$IFDEF RETROCESO_BARRIDO}
  self.xFin := xIni + (diffX * MaxNPuntos - 1);
{$ENDIF}
  ventanaGrafico.RegisterWinForClose(AOwner.Handle, WM_CLOSETRAZOSXY,
    xposEnSala + 1, -1{NO SE USA});
{$IFDEF FTRX_NILONCLOSE}
ventanaGrafico.nilOnClose := @ventanaGrafico;
{$ENDIF}

end;

function TMonGraficoSimple.resolverRefProc(refProc: integer): TProcWrapper;
var
  aux: TProcWrapper;
begin
  case refProc of
    1: aux := TProcWrapper.Create(self, self.Graficar);
    2: aux := TProcWrapper.Create(self, self.Limpiar);
    else
      raise Exception.Create('Metodo no registrado para ' + self.ClassName +
        IntToStr(refProc));
  end;
  Result := aux;
end;

procedure TMonGraficoSimple.Graficar;
var
  i: integer;
begin
  ventanaGrafico.tr1.PlotNuevo_x(pasoX);
  for i := 0 to high(seriesy) do
    ventanaGrafico.tr1.PlotNuevo_y(i + 1, seriesy[i].asNR);
  pasoX := pasoX + diffX;
  {$IFDEF RETROCESO_BARRIDO}
  if pasoX > xFin then
  begin
    pasoX := xIni;
    ventanaGrafico.tr1.desligueCanales;
  end;
  {$ENDIF}

end;

procedure TMonGraficoSimple.Limpiar;
begin
  if ventanaGrafico <> nil then
  begin
    pasoX := xIni;
    ventanaGrafico.tr1.limpiarCanales;
    ventanaGrafico.Repaint;
  end;
end;

procedure TMonGraficoSimple.Free;
begin
  if ventanaGrafico <> nil then
    ventanaGrafico.CloseForzado;
  SetLength(seriesy, 0);
  inherited Free;
end;

end.
