unit siuBuscaObjetosBasicaV3;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls,
  StdCtrls, DB, JvListView, jvtypes, ituMain, utuMessage,
  XMLIntf,
  msxmldom, ituUIController,
  XMLDoc, siuBuscaObjetos;

type
  TsiBuscaObjetosBasicaV3 = class(TsiBuscaObjetos)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    fMaxLinhas : Integer;
    fInterfaceController: itMain;
    fEntityCode: string;
    function GetNivel: integer;
  protected
    procedure ClearListViewObj;
    procedure ClearViewPanel; //Manter compatibilidade com o legado.
    procedure setListViewObj(const Value: TListView); override;
    procedure BuscaObjetos; virtual;
    procedure ResizeColumns; virtual;
    procedure PreencherMensagemBuscaObjetos(piMessage: mxMessage); virtual;
    procedure ChecarResultado(Dataset: TDataset);
    property InterfaceFromForm: itMain read fInterfaceController;
    function GetParamsDetailsRequest(piSuccessCallBackProcedure: itCallBackProcedure; piFailureCallBackProcedure: itCallBackProcedure = nil): acRequest;
  public
    { Public declarations }
    constructor Create(aowner:TComponent); overload; override;
    constructor Create(aowner:TComponent; piInterfaceController: itMain; piEntityCode: string); reintroduce; overload; override;
    procedure BuscaObjetosInicializacaoInterface; override;
    procedure SortMethod(Sender: TObject; Column: Integer; var AMethod: TJvSortMethod); virtual;
    procedure GetInitInterface(piMessage: mxMessage); virtual;
    procedure Inicializar(piXML: string); overload; virtual;
    procedure Inicializar(piField: utField); overload; virtual;
    procedure SetParamsDetails(piField: utField); virtual;
    procedure Inicializa; virtual;
    property MaxLinhas: Integer read fMaxLinhas write fMaxLinhas;
    property EntityCode: string read fEntityCode;
    property Nivel: integer read GetNivel;
    property ViewPanel: TListView read FListViewObj write setListViewObj;    
    procedure PreencherGrid(piXML:string); overload; virtual;
    procedure PreencherGrid(piField:utField); overload; virtual;
    procedure SetLabelsInGrid(piNode: IXMLNode); overload; virtual;
    procedure SetLabelsInGrid(piField: utField); overload; virtual;
    function Version: integer; override;
    function NewRequest(piID: cardinal): mxRequestMessage;
  end;

implementation

{$R *.dfm}

uses acuObject;

procedure TsiBuscaObjetosBasicaV3.ClearListViewObj;
var i: integer;
begin
  if self.Version = 1 then
  begin
      for i := 0 to pred(FListViewObj.Items.Count) do
      begin
        TObject(FListViewObj.Items.Item[i].Data).Free;
      end;
  end;
  FListViewObj.Items.Clear;
end;

procedure TsiBuscaObjetosBasicaV3.ClearViewPanel;
begin
  ClearListViewObj;
end;

procedure TsiBuscaObjetosBasicaV3.Button1Click(Sender: TObject);
begin
  if self.Version = 1 then ClearListViewObj;
  self.BuscaObjetos;
  self.ResizeColumns;
end;

procedure TsiBuscaObjetosBasicaV3.ChecarResultado(Dataset: TDataset);
begin
  if Dataset.RecordCount >= Maxlinhas then
     MessageDlg('Atenção: A consulta retorna mais de 100 registros.'
     + #13 +'Apenas os 100 primeiros registros serão exibidos,'
     + #13 + 'para obter resultados mais específicos mude os filtros da busca.'
     ,mtWarning, [mbOK], 0);
end;

constructor TsiBuscaObjetosBasicaV3.Create(aowner: TComponent);
begin
  inherited;
end;

constructor TsiBuscaObjetosBasicaV3.Create(aowner: TComponent; piInterfaceController: itMain; piEntityCode: string);
begin
  Self.Create(aowner);
  fMaxlinhas := 100;
  self.fInterfaceController := piInterfaceController;
  self.fEntityCode := piEntityCode;
  if self.Version = 3 then self.BuscaObjetosInicializacaoInterface;
end;

procedure TsiBuscaObjetosBasicaV3.SortMethod(Sender: TObject; Column: Integer; var AMethod: TJvSortMethod);
begin
  AMethod := smAutomatic;
end;

procedure TsiBuscaObjetosBasicaV3.BuscaObjetosInicializacaoInterface;
var
  lMessage: mxRequestMessage;
begin
  lMessage := self.NewRequest(UM_GET_PARAMS_INICIALIZATION);
  lMessage.Fields.AddField('ENTITY').AsString := self.EntityCode;
  self.GetInitInterface(lMessage);
  Self.InterfaceFromForm.PostMessage(lMessage);
end;

function TsiBuscaObjetosBasicaV3.GetParamsDetailsRequest(piSuccessCallBackProcedure: itCallBackProcedure; piFailureCallBackProcedure: itCallBackProcedure = nil): acRequest;
begin
  Result := Self.InterfaceFromForm.NewRequest(UM_GET_PARAMS_DETAILS, piSuccessCallBackProcedure, piFailureCallBackProcedure);
  Result.Message.Fields.AddField('ENTITY').AsString := self.EntityCode;
end;

procedure TsiBuscaObjetosBasicaV3.BuscaObjetos;
begin
end;

procedure TsiBuscaObjetosBasicaV3.Inicializar(piField: utField);
begin

end;

procedure TsiBuscaObjetosBasicaV3.Inicializar(piXML: string);
begin

end;

procedure TsiBuscaObjetosBasicaV3.PreencherGrid(piField: utField);
var
  ListItem: TJvListItem;
  lEnum: acEnumerator;
  lField: utField;
  lAttributeEnum: acEnumerator;
begin
  ClearListViewObj;
  try
    if piField.HasField('Objects') then
    begin
      if self.ListViewObj.Columns.Count = 0 then self.SetLabelsInGrid(piField);
      self.ListViewObj.Items.BeginUpdate;
      try
        lEnum := piField.FieldByName('Objects').GetFieldsEnumerator;
        try
          while not lEnum.EOL do
          begin
            lField := utField(lEnum.Current);
            ListItem := self.ListViewObj.Items.Add as TJvListItem;
            lAttributeEnum := lField.GetAttibutesEnumerator;
            try
              if not lAttributeEnum.EOL then
              begin
                if utAttribute(lAttributeEnum.Current).Name <> 'OID' then Raise Exception.Create('IDO do objeto não encontrado.');
                ListItem.Data := pointer(strtoint(utAttribute(lAttributeEnum.Current).AsString));
                lAttributeEnum.MoveNext;
              end;
              if not lAttributeEnum.EOL then
              begin
                ListItem.Caption := utAttribute(lAttributeEnum.Current).AsString;
                lAttributeEnum.MoveNext;
              end;
              while not lAttributeEnum.EOL do
              begin
                ListItem.SubItems.Add(utAttribute(lAttributeEnum.Current).AsString);
                lAttributeEnum.MoveNext;
              end;
            finally
              lAttributeEnum.Free;
            end;
            lEnum.MoveNext;
          end;
        finally
          lEnum.Free;
        end;
      finally
        self.ListViewObj.Items.EndUpdate;
      end;
    end;
  finally
    Screen.Cursor := crDefault;
  end;
end;

procedure TsiBuscaObjetosBasicaV3.PreencherGrid(piXML: string);
var
  lXMLDocumento: TXMLDocument;
  lIXMLDocumento: IXMLDocument;
  lUserNode: IXMLNode;
  li, lj: integer;
  ListItem: TJvListItem;
begin
  ClearListViewObj;
  lXMLDocumento := TXMLDocument.Create(nil);
  lXMLDocumento.DOMVendor := MSXML_DOM;
  lIXMLDocumento := lXMLDocumento;
  lIXMLDocumento.LoadFromXML(piXML);
  lIXMLDocumento.Active := True;
  try
    if not lIXMLDocumento.IsEmptyDoc then
    begin
      if lIXMLDocumento.DocumentElement.HasChildNodes then
      begin
        if self.ListViewObj.Columns.Count = 0 then
        begin
          if lIXMLDocumento.DocumentElement.ChildNodes.Count > 0 then
          begin
            self.SetLabelsInGrid(lIXMLDocumento.DocumentElement);
          end;
        end;
        self.ListViewObj.Items.BeginUpdate;
        try
          for li := 0  to lIXMLDocumento.DocumentElement.ChildNodes.Count - 1 do
          begin
            if lIXMLDocumento.DocumentElement.ChildNodes[li].NodeName <> 'Labels' then
            begin
              lUserNode := lIXMLDocumento.DocumentElement.ChildNodes[li];
              ListItem := self.ListViewObj.Items.Add as TJvListItem;
              if self.ListViewObj.Columns.Count >= 2 then
              begin
                ListItem.Caption := lUserNode.AttributeNodes[1].Text;
                for lj := 2 to  pred(lUserNode.AttributeNodes.Count) do
                begin
                  ListItem.SubItems.Add(lUserNode.AttributeNodes[lj].Text);
                end;
              end;
              if not lUserNode.HasAttribute('OID') then Raise Exception.Create('IDO do objeto não encontrado.');
              ListItem.Data := pointer(strtoint(lUserNode.Attributes['OID']));
            end;
          end;
        finally
          self.ListViewObj.Items.EndUpdate;
        end;
      end;
    end;
  finally
    Screen.Cursor := crDefault;
  end;
end;

procedure TsiBuscaObjetosBasicaV3.SetLabelsInGrid(piField: utField);
var lEnum: acEnumerator;
    lAttributeEnum: acEnumerator;
begin
  self.ListViewObj.Columns.Clear;
  begin
    if piField.HasField('Objects') then
    begin
      lEnum := piField.FieldByName('Objects').GetFieldsEnumerator;
      try
        if not lEnum.EOL then
        begin
          lAttributeEnum := utField(lEnum.Current).GetAttibutesEnumerator;
          try
            if not lAttributeEnum.EOL then lAttributeEnum.MoveNext; // Ignora attributo OID que e sempre o primeiro
            while not lAttributeEnum.EOL do
            begin
              Self.ListViewObj.Columns.Add.Caption := utField(lAttributeEnum.Current).Name;
              lAttributeEnum.MoveNext;
            end;
          finally
            lAttributeEnum.Free;
          end;
        end;
      finally
        lEnum.Free
      end;
    end;
  end;
  Self.ResizeColumns;
end;

procedure TsiBuscaObjetosBasicaV3.SetParamsDetails(piField: utField);
begin

end;

procedure TsiBuscaObjetosBasicaV3.SetLabelsInGrid(piNode: IXMLNode);
var
  lLabels: IXMLNode;
  li: integer;
begin
  self.ListViewObj.Columns.Clear;
  if assigned(piNode.ChildNodes.FindNode('Labels')) then
  begin
    lLabels := piNode.ChildNodes.Nodes['Labels'];
    for li := 0 to Pred(lLabels.ChildNodes.Count) do
    begin
      Self.ListViewObj.Columns.Add.Caption := lLabels.ChildNodes.Nodes[li].NodeName;
    end;
  end
  else
  begin
    lLabels := piNode.ChildNodes[0];
    for li := 1 to Pred(lLabels.AttributeNodes.Count) do
    begin
      Self.ListViewObj.Columns.Add.Caption := lLabels.AttributeNodes[li].NodeName;
    end;
  end;
  Self.ResizeColumns;
end;

procedure TsiBuscaObjetosBasicaV3.GetInitInterface(piMessage: mxMessage);
begin

end;

procedure TsiBuscaObjetosBasicaV3.PreencherMensagemBuscaObjetos(piMessage: mxMessage);
begin

end;

procedure TsiBuscaObjetosBasicaV3.ResizeColumns;
var li: integer;
begin
  Self.ListViewObj.Items.BeginUpdate;
  try
    for li := pred(self.ListViewObj.Columns.Count) downto 0 do
    begin
      Self.ListViewObj.Columns.Items[li].Width := -2;
    end;
  finally
    Self.ListViewObj.Items.EndUpdate;
  end;
end;

procedure TsiBuscaObjetosBasicaV3.Inicializa;
begin
end;

procedure TsiBuscaObjetosBasicaV3.SetListViewObj(const Value: TListView);
begin
  self.FListViewObj := Value;
  self.Inicializa;
  self.ResizeColumns;
end;

function TsiBuscaObjetosBasicaV3.Version: integer;
begin
  Result := 3;
end;

function TsiBuscaObjetosBasicaV3.GetNivel: integer;
begin
  result := fInterfaceController.Level;
end;

function TsiBuscaObjetosBasicaV3.NewRequest(piID: cardinal): mxRequestMessage;
begin
  result := mxRequestMessage.Create(piID, Self.InterfaceFromForm.UseCaseAddress, Self.InterfaceFromForm.Address);
end;

end.
