unit uAppTheme;

interface

uses
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Themes, Vcl.Styles, System.UIConsts,
  System.Classes, System.SysUtils;

type
  TAppTheme = class
  public
    // Colores Corporativos (RGB -> Integer TColor)
    const COLOR_MAIN_RED     = $2D2BA1; // #A12B2D (Rojo Raúl Asencio)
    const COLOR_DARK_RED     = $1A1A7A; // #7A1A1A (Rojo oscuro acento)
    const COLOR_HEADER_BLACK = $2A2A2A; // #2A2A2A (Gris casi negro para barras)
    const COLOR_SOFT_GRAY    = $E6E6E6; // #E6E6E6 (Gris claro elegante pedido por el usuario)
    const COLOR_TEXT_WHITE   = clWhite;
    const COLOR_TEXT_DARK    = $333333; // #333333

    // Colores de filas alternas para DBGrid
    const COLOR_GRID_ROW_EVEN = clWhite;           // Filas pares: blanco
    const COLOR_GRID_ROW_ODD  = $F5F0EB;           // Filas impares: crema muy suave (#EBF0F5 invertido BGR)
    
    // Fuentes estandarizadas
    const FONT_NAME_MAIN     = 'Segoe UI';
    const FONT_NAME_HEADER   = 'Segoe UI Semibold';
    
    /// <summary>
    /// Aplica el tema visual a un formulario y sus componentes hijos recursivamente.
    /// </summary>
    class procedure ApplyToForm(AForm: TForm);
    
    /// <summary>
    /// Configura todos los controles de texto editables del formulario para escribir en mayúsculas por defecto.
    /// </summary>
    class procedure ApplyUpperCaseToEdits(AForm: TCustomForm);
    
    /// <summary>
    /// Cambia el estilo global de la VCL (Claro/Oscuro).
    /// </summary>
    class procedure SwitchTheme(const AStyleName: string);
  end;

implementation

uses
  System.Rtti, System.TypInfo, Vcl.StdCtrls;

{ TAppTheme }

class procedure TAppTheme.ApplyToForm(AForm: TForm);
var
  I: Integer;
begin
  AForm.Font.Name := FONT_NAME_MAIN;
  AForm.Font.Color := COLOR_TEXT_DARK;
  
  // Si no hay un tema VCL cargado (modo Claro manual)
  if TStyleManager.ActiveStyle.Name = 'Windows' then
  begin
    AForm.Color := COLOR_SOFT_GRAY;
  end;
end;

class procedure TAppTheme.ApplyUpperCaseToEdits(AForm: TCustomForm);
var
  I: Integer;
  LContext: TRttiContext;
  LType: TRttiType;
  LProp: TRttiProperty;
  LCompName: string;
  LShouldExclude: Boolean;
  LComp: TComponent;
begin
  if SameText(AForm.ClassName, 'TfrmEnviosConfig') or 
     SameText(AForm.ClassName, 'TfrmFichaTecnicaEditor') or 
     SameText(AForm.ClassName, 'TfrmUsuariosEditor') or 
     SameText(AForm.ClassName, 'TfrmUsuarios') or 
     SameText(AForm.ClassName, 'TfrmLogin') then Exit;

  LContext := TRttiContext.Create;
  try
    for I := 0 to AForm.ComponentCount - 1 do
    begin
      LComp := AForm.Components[I];
      // Excluir TCustomMemo para evitar errores de la API ES_UPPERCASE de Windows con teclas muertas (tildes)
      if (LComp is TCustomEdit) and not (LComp is TCustomMemo) then
      begin
        LCompName := LowerCase(LComp.Name);
        
        // Excluir campos especiales como correos, webs, contraseñas, usuarios, observaciones, alérgenos, etc.
        LShouldExclude := (Pos('email', LCompName) > 0) or
                          (Pos('correo', LCompName) > 0) or
                          (Pos('web', LCompName) > 0) or
                          (Pos('url', LCompName) > 0) or
                          (Pos('pass', LCompName) > 0) or
                          (Pos('pwd', LCompName) > 0) or
                          (Pos('clave', LCompName) > 0) or
                          (Pos('contrase', LCompName) > 0) or
                          (Pos('user', LCompName) > 0) or
                          (Pos('usuario', LCompName) > 0) or
                          (Pos('login', LCompName) > 0) or
                          (Pos('token', LCompName) > 0) or
                          (Pos('host', LCompName) > 0) or
                          (Pos('apikey', LCompName) > 0) or
                          (Pos('iamodelo', LCompName) > 0) or
                          (Pos('modelo', LCompName) > 0) or
                          (Pos('obs', LCompName) > 0) or
                          (Pos('alergeno', LCompName) > 0) or
                          (Pos('ingrediente', LCompName) > 0);
                          
        if not LShouldExclude then
        begin
          LType := LContext.GetType(LComp.ClassType);
          if Assigned(LType) then
          begin
            LProp := LType.GetProperty('CharCase');
            if Assigned(LProp) and LProp.IsWritable and (LProp.PropertyType.TypeKind = tkEnumeration) then
            begin
              // ecUpperCase tiene ordinal 1 en TEditCharCase
              LProp.SetValue(LComp, TValue.FromOrdinal(LProp.PropertyType.Handle, 1));
            end;
          end;
        end;
      end;
    end;
  finally
    LContext.Free;
  end;
end;

class procedure TAppTheme.SwitchTheme(const AStyleName: string);
begin
  if not TStyleManager.TrySetStyle(AStyleName) then
    // Opcional: Log o fallback
    ;
end;

end.
