unit frm_AsignarMateriasPrimas;
interface
uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls,
  Vcl.Grids, Vcl.DBGrids, Data.DB, Vcl.Buttons, uAppTheme, FireDAC.Stan.Param,
  FireDAC.Comp.Client, uUIAutoScaler, FireDAC.Stan.Intf, FireDAC.Stan.Option,
  FireDAC.Stan.Error, FireDAC.DatS, FireDAC.Phys.Intf, FireDAC.DApt.Intf,
  FireDAC.Stan.Async, FireDAC.DApt, FireDAC.Comp.DataSet;
type
  TfrmAsignarMateriasPrimas = class(TForm)
    pnlLeft: TPanel;
    pnlHeaderOur: TPanel;
    lblSearchOur: TLabel;
    edtSearchOur: TEdit;
    btnSearchOur: TSpeedButton;
    btnNuevaMateria: TSpeedButton;
    dbgOurMaterias: TDBGrid;
    dsOurMaterias: TDataSource;
    qryOurMaterias: TFDQuery;
    
    pnlMiddle: TPanel;
    
    pnlRight: TPanel;
    pnlHeaderSupplier: TPanel;
    lblSearchSupplier: TLabel;
    edtSearchSupplier: TEdit;
    btnSearchSupplier: TSpeedButton;
    btnCrearNuestraDesdeProveedor: TSpeedButton;
    dbgSupplierMaterias: TDBGrid;
    dsSupplierMaterias: TDataSource;
    qrySupplierMaterias: TFDQuery;
    
    pnlAssignedBottom: TPanel;
    pnlAssignedHeader: TPanel;
    lblAssignedHeader: TLabel;
    dbgAssignedSupplier: TDBGrid;
    dsAssignedSupplier: TDataSource;
    qryAssignedSupplier: TFDQuery;
    
    SplitterRight: TSplitter;
    btnAssign: TSpeedButton;
    btnUnassign: TSpeedButton;
    procedure FormShow(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnSearchOurClick(Sender: TObject);
    procedure btnSearchSupplierClick(Sender: TObject);
    procedure btnNuevaMateriaClick(Sender: TObject);
    procedure btnCrearNuestraDesdeProveedorClick(Sender: TObject);
    procedure dbgOurMateriasCellClick(Column: TColumn);
    procedure btnAssignClick(Sender: TObject);
    procedure btnUnassignClick(Sender: TObject);
    procedure edtSearchOurKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure edtSearchSupplierKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure dbgGridDrawColumnCell(Sender: TObject; const Rect: TRect;
      DataCol: Integer; Column: TColumn; State: TGridDrawState);
    procedure dbgOurMateriasTitleClick(Column: TColumn);
    procedure dbgSupplierMateriasTitleClick(Column: TColumn);
    procedure dbgAssignedSupplierTitleClick(Column: TColumn);
  private
    FLastSortColOur: string;
    FLastSortDirOur: string;
    FLastSortColSupplier: string;
    FLastSortDirSupplier: string;
    FLastSortColAssigned: string;
    FLastSortDirAssigned: string;
    FSelectedCatalogId: Integer;
    
    procedure RefreshOurMaterias;
    procedure RefreshSupplierMaterias;
    procedure RefreshAssignedSupplier;
  public
    { Public declarations }
    property SelectedCatalogId: Integer read FSelectedCatalogId write FSelectedCatalogId;
  end;
var
  frmAsignarMateriasPrimas: TfrmAsignarMateriasPrimas;
implementation
uses
  dmg_Main, frm_MateriasPrimasEditor;
{$R *.dfm}
procedure TfrmAsignarMateriasPrimas.FormCreate(Sender: TObject);
begin
  TUIAutoScaler.RegisterForm(Self);
  
  // Asignar conexiones de base de datos
  qryOurMaterias.Connection := dmgMain.dbConn;
  qrySupplierMaterias.Connection := dmgMain.dbConn;
  qryAssignedSupplier.Connection := dmgMain.dbConn;
  // Asignar fuentes de datos
  dsOurMaterias.DataSet := qryOurMaterias;
  dsSupplierMaterias.DataSet := qrySupplierMaterias;
  dsAssignedSupplier.DataSet := qryAssignedSupplier;
  
  // Asignar eventos de click en cabecera para ordenación
  dbgOurMaterias.OnTitleClick := dbgOurMateriasTitleClick;
  dbgSupplierMaterias.OnTitleClick := dbgSupplierMateriasTitleClick;
  dbgAssignedSupplier.OnTitleClick := dbgAssignedSupplierTitleClick;
end;
procedure TfrmAsignarMateriasPrimas.FormDestroy(Sender: TObject);
begin
  TUIAutoScaler.UnregisterForm(Self);
  if frmAsignarMateriasPrimas = Self then
    frmAsignarMateriasPrimas := nil;
end;
procedure TfrmAsignarMateriasPrimas.FormShow(Sender: TObject);
var
  LQry: TFDQuery;
  LIdMateria: Integer;
begin
  TAppTheme.ApplyToForm(Self);
  TAppTheme.ApplyUpperCaseToEdits(Self);
  
  // Conectar evento para coloreado/checkboxes automático según directiva
  dbgOurMaterias.OnDrawColumnCell := dbgGridDrawColumnCell;
  dbgSupplierMaterias.OnDrawColumnCell := dbgGridDrawColumnCell;
  dbgAssignedSupplier.OnDrawColumnCell := dbgGridDrawColumnCell;
  RefreshOurMaterias;
  RefreshSupplierMaterias;

  if FSelectedCatalogId > 0 then
  begin
    LQry := TFDQuery.Create(nil);
    try
      LQry.Connection := qryOurMaterias.Connection;
      LQry.SQL.Text := 'SELECT id_materia_prima FROM ge_proveedores_materias_primas WHERE id = :id';
      LQry.ParamByName('id').AsInteger := FSelectedCatalogId;
      LQry.Open;
      if not LQry.IsEmpty then
      begin
        if not LQry.FieldByName('id_materia_prima').IsNull then
        begin
          LIdMateria := LQry.FieldByName('id_materia_prima').AsInteger;
          if qryOurMaterias.Active and qryOurMaterias.Locate('id', LIdMateria, []) then
          begin
            RefreshAssignedSupplier;
            if qryAssignedSupplier.Active then
              qryAssignedSupplier.Locate('id', FSelectedCatalogId, []);
          end;
        end
        else
        begin
          if qrySupplierMaterias.Active then
            qrySupplierMaterias.Locate('id', FSelectedCatalogId, []);
        end;
      end;
    finally
      LQry.Free;
    end;
  end;
end;
procedure TfrmAsignarMateriasPrimas.RefreshOurMaterias;
var
  LSql: string;
begin
  qryOurMaterias.Close;
  LSql := 'SELECT id, descripcion, codigo_barras, activo FROM ge_materias_primas WHERE activo = 1 ';
  
  if Trim(edtSearchOur.Text) <> '' then
    LSql := LSql + 'AND (descripcion LIKE :search OR codigo_barras LIKE :search) ';
    
  LSql := LSql + 'ORDER BY descripcion';
  qryOurMaterias.SQL.Text := LSql;
  
  if Trim(edtSearchOur.Text) <> '' then
    qryOurMaterias.ParamByName('search').AsString := '%' + Trim(edtSearchOur.Text) + '%';
    
  qryOurMaterias.Open;
  RefreshAssignedSupplier;
end;
procedure TfrmAsignarMateriasPrimas.RefreshSupplierMaterias;
var
  LSql: string;
begin
  qrySupplierMaterias.Close;
  LSql := 'SELECT pm.id, pm.descripcion, pm.codigo_articulo_proveedor, pm.ult_precio, pm.id_materia_prima, pm.id_proveedor, p.nombre as proveedor_nombre, pm.activo ' +
          'FROM ge_proveedores_materias_primas pm ' +
          'LEFT JOIN ge_proveedores p ON pm.id_proveedor = p.id ' +
          'WHERE pm.id_materia_prima IS NULL AND p.tipo = ''MATERIA_PRIMA'' ';
          
  if Trim(edtSearchSupplier.Text) <> '' then
    LSql := LSql + 'AND (pm.descripcion LIKE :search OR pm.codigo_articulo_proveedor LIKE :search OR p.nombre LIKE :search) ';
    
  LSql := LSql + 'ORDER BY pm.descripcion';
  qrySupplierMaterias.SQL.Text := LSql;
  
  if Trim(edtSearchSupplier.Text) <> '' then
    qrySupplierMaterias.ParamByName('search').AsString := '%' + Trim(edtSearchSupplier.Text) + '%';
    
  qrySupplierMaterias.Open;
end;
procedure TfrmAsignarMateriasPrimas.RefreshAssignedSupplier;
begin
  qryAssignedSupplier.Close;
  if not qryOurMaterias.Active or qryOurMaterias.IsEmpty then
    Exit;
    
  qryAssignedSupplier.SQL.Text := 
    'SELECT pm.id, pm.descripcion, pm.codigo_articulo_proveedor, pm.ult_precio, pm.id_proveedor, p.nombre as proveedor_nombre, pm.activo ' +
    'FROM ge_proveedores_materias_primas pm ' +
    'LEFT JOIN ge_proveedores p ON pm.id_proveedor = p.id ' +
    'WHERE pm.id_materia_prima = :id_materia_prima AND p.tipo = ''MATERIA_PRIMA'' ' +
    'ORDER BY pm.descripcion';
    
  qryAssignedSupplier.ParamByName('id_materia_prima').AsString := qryOurMaterias.FieldByName('id').AsString;
  qryAssignedSupplier.Open;
end;
procedure TfrmAsignarMateriasPrimas.btnSearchOurClick(Sender: TObject);
begin
  RefreshOurMaterias;
end;
procedure TfrmAsignarMateriasPrimas.btnSearchSupplierClick(Sender: TObject);
begin
  RefreshSupplierMaterias;
end;
procedure TfrmAsignarMateriasPrimas.btnNuevaMateriaClick(Sender: TObject);
var
  LNuevoId: string;
begin
  if not Assigned(frmMateriasPrimasEditor) then
    Application.CreateForm(TfrmMateriasPrimasEditor, frmMateriasPrimasEditor);
  
  frmMateriasPrimasEditor.ParentForm := Self;
  frmMateriasPrimasEditor.MateriaPrimaId := '';
  frmMateriasPrimasEditor.InitialDescripcion := '';
  frmMateriasPrimasEditor.InitialCodigoBarras := '';
  
  frmMateriasPrimasEditor.ShowModal;
  LNuevoId := frmMateriasPrimasEditor.MateriaPrimaId;
  if LNuevoId <> '' then
  begin
    RefreshOurMaterias;
    if qryOurMaterias.Active then
    begin
      qryOurMaterias.Locate('id', StrToIntDef(LNuevoId, 0), []);
      RefreshAssignedSupplier;
    end;
  end;
end;
procedure TfrmAsignarMateriasPrimas.btnCrearNuestraDesdeProveedorClick(Sender: TObject);
var
  LDesc, LCodigo, LNuevoId: string;
begin
  if not qrySupplierMaterias.Active or qrySupplierMaterias.IsEmpty then
  begin
    ShowMessage('Por favor, seleccione una materia prima de proveedor en la lista para crear la nuestra a partir de ella.');
    Exit;
  end;

  LDesc := qrySupplierMaterias.FieldByName('descripcion').AsString;
  LCodigo := '';
  if qrySupplierMaterias.FindField('codigo_articulo_proveedor') <> nil then
    LCodigo := qrySupplierMaterias.FieldByName('codigo_articulo_proveedor').AsString;

  if not Assigned(frmMateriasPrimasEditor) then
    Application.CreateForm(TfrmMateriasPrimasEditor, frmMateriasPrimasEditor);
  
  frmMateriasPrimasEditor.ParentForm := Self;
  frmMateriasPrimasEditor.MateriaPrimaId := '';
  frmMateriasPrimasEditor.InitialDescripcion := LDesc;
  frmMateriasPrimasEditor.InitialCodigoBarras := LCodigo;
  
  frmMateriasPrimasEditor.ShowModal;
  LNuevoId := frmMateriasPrimasEditor.MateriaPrimaId;
  if LNuevoId <> '' then
  begin
    RefreshOurMaterias;
    if qryOurMaterias.Active then
    begin
      qryOurMaterias.Locate('id', StrToIntDef(LNuevoId, 0), []);
      RefreshAssignedSupplier;
    end;
  end;
end;
procedure TfrmAsignarMateriasPrimas.dbgOurMateriasCellClick(Column: TColumn);
begin
  RefreshAssignedSupplier;
end;
procedure TfrmAsignarMateriasPrimas.btnAssignClick(Sender: TObject);
var
  LOurId, LSupplierId, LProveedorId, LCodigo: string;
begin
  if qryOurMaterias.IsEmpty then
  begin
    ShowMessage('Por favor, seleccione una de nuestras materias primas.');
    Exit;
  end;
  
  if qrySupplierMaterias.IsEmpty then
  begin
    ShowMessage('Por favor, seleccione una materia prima de proveedor.');
    Exit;
  end;
  
  LOurId := qryOurMaterias.FieldByName('id').AsString;
  LSupplierId := qrySupplierMaterias.FieldByName('id').AsString;
  LProveedorId := qrySupplierMaterias.FieldByName('id_proveedor').AsString;
  LCodigo := qrySupplierMaterias.FieldByName('codigo_articulo_proveedor').AsString;
  
  try
    // 1. Actualizar el mapeo de materias primas de proveedor
    dmgMain.qryExec.Close;
    dmgMain.qryExec.SQL.Text := 
      'UPDATE ge_proveedores_materias_primas ' +
      'SET id_materia_prima = :id_materia_prima, id_user_update = :id_user ' +
      'WHERE id = :id';
    dmgMain.qryExec.ParamByName('id_materia_prima').AsString := LOurId;
    dmgMain.qryExec.ParamByName('id_user').AsString := dmgMain.CurrentUserId;
    dmgMain.qryExec.ParamByName('id').AsString := LSupplierId;
    dmgMain.qryExec.ExecSQL;
    
    // 2. Actualización en cascada en las líneas de albaranes de proveedor
    if (LProveedorId <> '') and (LCodigo <> '') then
    begin
      dmgMain.qryExec.Close;
      dmgMain.qryExec.SQL.Text := 
        'UPDATE ge_prov_albaranes_detalle ' +
        'SET id_propio = :id_materia_prima, id_user_update = :id_user ' +
        'WHERE idproveedor = :idproveedor AND codigo = :codigo';
      dmgMain.qryExec.ParamByName('id_materia_prima').AsString := LOurId;
      dmgMain.qryExec.ParamByName('id_user').AsString := dmgMain.CurrentUserId;
      dmgMain.qryExec.ParamByName('idproveedor').AsString := LProveedorId;
      dmgMain.qryExec.ParamByName('codigo').AsString := LCodigo;
      dmgMain.qryExec.ExecSQL;
      
      // 3. Actualización en cascada en las líneas de facturas de proveedor
      dmgMain.qryExec.Close;
      dmgMain.qryExec.SQL.Text := 
        'UPDATE ge_prov_facturas_detalle ' +
        'SET id_propio = :id_materia_prima, id_user_update = :id_user ' +
        'WHERE idproveedor = :idproveedor AND codigo = :codigo';
      dmgMain.qryExec.ParamByName('id_materia_prima').AsString := LOurId;
      dmgMain.qryExec.ParamByName('id_user').AsString := dmgMain.CurrentUserId;
      dmgMain.qryExec.ParamByName('idproveedor').AsString := LProveedorId;
      dmgMain.qryExec.ParamByName('codigo').AsString := LCodigo;
      dmgMain.qryExec.ExecSQL;
    end;
    
    RefreshSupplierMaterias;
    RefreshAssignedSupplier;
    // ShowMessage('Mapeo de materia prima realizado con éxito en el catálogo y documentos asociados.');
  except
    on E: Exception do
      ShowMessage('Error al realizar la asignación: ' + E.Message);
  end;
end;
procedure TfrmAsignarMateriasPrimas.btnUnassignClick(Sender: TObject);
var
  LSupplierId, LProveedorId, LCodigo: string;
begin
  if qryAssignedSupplier.IsEmpty then
  begin
    ShowMessage('Seleccione una materia prima mapeada del proveedor para desasignarla.');
    Exit;
  end;
  
  LSupplierId := qryAssignedSupplier.FieldByName('id').AsString;
  LProveedorId := qryAssignedSupplier.FieldByName('id_proveedor').AsString;
  LCodigo := qryAssignedSupplier.FieldByName('codigo_articulo_proveedor').AsString;
  
//  if MessageDlg('¿Está seguro de que desea eliminar la asignación de este artículo y limpiar sus referencias en albaranes/facturas?', mtConfirmation, [mbYes, mbNo], 0) = mrYes then
//  begin
    try
      // 1. Limpiar el mapeo de materias primas de proveedor
      dmgMain.qryExec.Close;
      dmgMain.qryExec.SQL.Text :=
        'UPDATE ge_proveedores_materias_primas ' +
        'SET id_materia_prima = NULL, id_user_update = :id_user ' +
        'WHERE id = :id';
      dmgMain.qryExec.ParamByName('id_user').AsString := dmgMain.CurrentUserId;
      dmgMain.qryExec.ParamByName('id').AsString := LSupplierId;
      dmgMain.qryExec.ExecSQL;

      // 2. Limpieza en cascada en las líneas de albaranes de proveedor
      if (LProveedorId <> '') and (LCodigo <> '') then
      begin
        dmgMain.qryExec.Close;
        dmgMain.qryExec.SQL.Text :=
          'UPDATE ge_prov_albaranes_detalle ' +
          'SET id_propio = NULL, id_user_update = :id_user ' +
          'WHERE idproveedor = :idproveedor AND codigo = :codigo';
        dmgMain.qryExec.ParamByName('id_user').AsString := dmgMain.CurrentUserId;
        dmgMain.qryExec.ParamByName('idproveedor').AsString := LProveedorId;
        dmgMain.qryExec.ParamByName('codigo').AsString := LCodigo;
        dmgMain.qryExec.ExecSQL;

        // 3. Limpieza en cascada en las líneas de facturas de proveedor
        dmgMain.qryExec.Close;
        dmgMain.qryExec.SQL.Text :=
          'UPDATE ge_prov_facturas_detalle ' +
          'SET id_propio = NULL, id_user_update = :id_user ' +
          'WHERE idproveedor = :idproveedor AND codigo = :codigo';
        dmgMain.qryExec.ParamByName('id_user').AsString := dmgMain.CurrentUserId;
        dmgMain.qryExec.ParamByName('idproveedor').AsString := LProveedorId;
        dmgMain.qryExec.ParamByName('codigo').AsString := LCodigo;
        dmgMain.qryExec.ExecSQL;
      end;

      RefreshSupplierMaterias;
      RefreshAssignedSupplier;
      // ShowMessage('Asignación eliminada con éxito del catálogo y documentos asociados.');
    except
      on E: Exception do
        ShowMessage('Error al eliminar la asignación: ' + E.Message);
    end;
  //end;
end;
procedure TfrmAsignarMateriasPrimas.edtSearchOurKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if Key = VK_RETURN then
  begin
    Key := 0;
    btnSearchOurClick(nil);
  end;
end;
procedure TfrmAsignarMateriasPrimas.edtSearchSupplierKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if Key = VK_RETURN then
  begin
    Key := 0;
    btnSearchSupplierClick(nil);
  end;
end;
procedure TfrmAsignarMateriasPrimas.dbgOurMateriasTitleClick(Column: TColumn);
begin
  if not qryOurMaterias.Active or qryOurMaterias.IsEmpty then
    Exit;
  if FLastSortColOur = Column.FieldName then
  begin
    if FLastSortDirOur = 'A' then FLastSortDirOur := 'D' else FLastSortDirOur := 'A';
  end
  else
  begin
    FLastSortColOur := Column.FieldName;
    FLastSortDirOur := 'A';
  end;
  
  if FLastSortDirOur = 'D' then
    qryOurMaterias.IndexFieldNames := Column.FieldName + ':D'
  else
    qryOurMaterias.IndexFieldNames := Column.FieldName + ':A';
end;
procedure TfrmAsignarMateriasPrimas.dbgSupplierMateriasTitleClick(Column: TColumn);
begin
  if not qrySupplierMaterias.Active or qrySupplierMaterias.IsEmpty then
    Exit;
  if FLastSortColSupplier = Column.FieldName then
  begin
    if FLastSortDirSupplier = 'A' then FLastSortDirSupplier := 'D' else FLastSortDirSupplier := 'A';
  end
  else
  begin
    FLastSortColSupplier := Column.FieldName;
    FLastSortDirSupplier := 'A';
  end;
  
  if FLastSortDirSupplier = 'D' then
    qrySupplierMaterias.IndexFieldNames := Column.FieldName + ':D'
  else
    qrySupplierMaterias.IndexFieldNames := Column.FieldName + ':A';
end;
procedure TfrmAsignarMateriasPrimas.dbgAssignedSupplierTitleClick(Column: TColumn);
begin
  if not qryAssignedSupplier.Active or qryAssignedSupplier.IsEmpty then
    Exit;
  if FLastSortColAssigned = Column.FieldName then
  begin
    if FLastSortDirAssigned = 'A' then FLastSortDirAssigned := 'D' else FLastSortDirAssigned := 'A';
  end
  else
  begin
    FLastSortColAssigned := Column.FieldName;
    FLastSortDirAssigned := 'A';
  end;
  
  if FLastSortDirAssigned = 'D' then
    qryAssignedSupplier.IndexFieldNames := Column.FieldName + ':D'
  else
    qryAssignedSupplier.IndexFieldNames := Column.FieldName + ':A';
end;
procedure TfrmAsignarMateriasPrimas.dbgGridDrawColumnCell(Sender: TObject; const Rect: TRect;
  DataCol: Integer; Column: TColumn; State: TGridDrawState);
var
  Checked: Boolean;
  DrawRect: TRect;
  DrawState: Cardinal;
  Grid: TDBGrid;
  IsOddRow: Boolean;
begin
  Grid := TDBGrid(Sender);
  if not (gdSelected in State) then
  begin
    if Assigned(Grid.DataSource) and Assigned(Grid.DataSource.DataSet) and Grid.DataSource.DataSet.Active then
      IsOddRow := Odd(Grid.DataSource.DataSet.RecNo)
    else
      IsOddRow := False;
    if IsOddRow then
      Grid.Canvas.Brush.Color := TAppTheme.COLOR_GRID_ROW_ODD
    else
      Grid.Canvas.Brush.Color := TAppTheme.COLOR_GRID_ROW_EVEN;
  end;
  if Assigned(Column.Field) and 
     ((Column.Field is TBooleanField) or 
      (Pos('activo', LowerCase(Column.Field.FieldName)) > 0) or 
      (Pos('active', LowerCase(Column.Field.FieldName)) > 0)) then
  begin
    Grid.Canvas.Font.Color := Grid.Canvas.Brush.Color;
    Grid.Canvas.FillRect(Rect);
    
    if not Column.ReadOnly then
      Column.ReadOnly := True;
      
    if (Column.Field is TBooleanField) and (TBooleanField(Column.Field).DisplayValues <> ';') then
      TBooleanField(Column.Field).DisplayValues := ';';
    
    if Column.Field is TBooleanField then
      Checked := Column.Field.AsBoolean
    else
    begin
      var LValInt: Integer;
      var LValStr := Trim(Column.Field.AsString);
      if TryStrToInt(LValStr, LValInt) then
        Checked := (LValInt <> 0)
      else
        Checked := SameText(LValStr, 'S') or 
                   SameText(LValStr, 'T') or 
                   SameText(LValStr, 'True') or
                   SameText(LValStr, '1');
    end;
                 
    DrawRect := Rect;
    DrawRect.Left := Rect.Left + (Rect.Width - 14) div 2;
    DrawRect.Right := DrawRect.Left + 14;
    DrawRect.Top := Rect.Top + (Rect.Height - 14) div 2;
    DrawRect.Bottom := DrawRect.Top + 14;
    
    DrawState := DFCS_BUTTONCHECK;
    if Checked then
      DrawState := DrawState or DFCS_CHECKED;
      
    DrawFrameControl(Grid.Canvas.Handle, DrawRect, DFC_BUTTON, DrawState);
  end
  else
  begin
    Grid.DefaultDrawColumnCell(Rect, DataCol, Column, State);
  end;
end;
end.
