unit Unit1;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls, ComCtrls, Menus, INIFiles, fphttpclient;

type

  { TForm1 }

  TForm1 = class(TForm)
    LoadSettings: TButton;
    MenuItem1: TMenuItem;
    MenuItem2: TMenuItem;
    PopupMenu1: TPopupMenu;
    SaveSettings: TButton;
    SaveButton: TButton;
    ComboBox1: TComboBox;
    Edit1: TEdit;
    IdleTimer1: TIdleTimer;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    MemoLog: TMemo;
    StatusBar1: TStatusBar;
    Timer1: TTimer;
    TrayIcon1: TTrayIcon;
    procedure Edit1Change(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure FormWindowStateChange(Sender: TObject);
    procedure LoadSettingsClick(Sender: TObject);
    procedure MenuItem1Click(Sender: TObject);
    procedure MenuItem2Click(Sender: TObject);
    procedure SaveButtonClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure IdleTimer1Timer(Sender: TObject);
    procedure SaveSettingsClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure TrayIcon1Click(Sender: TObject);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;
  msec_to_run: cardinal;

implementation

{$R *.lfm}

{ TForm1 }

procedure MemoScroll();
begin
  while Form1.MemoLog.Lines.Count > 30 do
    Form1.MemoLog.Lines.Delete(0);
  Form1.MemoLog.SelLength := 0;
  Form1.MemoLog.SelStart := length(Form1.MemoLog.Lines.Text);;
end;

function IsValidUrl(s: string): boolean;
var
  i: integer;
begin
  Result := false;
  if Length(s) < 8 then exit;
  if Copy(s, 1, 7)<>'http://' then exit;
  if (s[Length(s)] = '.')  or (Pos('..', s) > 0) then exit;
  for i := 1 to Length(s) do if (Ord(s[i]) < 33) or (Ord(s[i]) > 126) then exit;
  if (Pos('@', s) > 1) then exit;
  Result := true;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
  LoadSettings.Click;
end;

procedure TForm1.FormWindowStateChange(Sender: TObject);
begin
  if Form1.WindowState = wsMinimized then begin
      Form1.WindowState := wsNormal;
      Form1.Hide;
      Form1.ShowInTaskBar := stNever;
      TrayIcon1.Show;
  end;
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin
  SaveButton.Enabled:=true;
  IdleTimer1.Enabled:=false;
end;

procedure TForm1.LoadSettingsClick(Sender: TObject);
var ini: TIniFile;
    ws: integer;
begin
  if(IdleTimer1.Enabled = false) then
  begin
  MemoLog.Lines.Add('Старт программы и попытка загрузки файла настроек');

    //загрузка параметров формы и dbgrids
  if(FileExists(ExtractFilePath(Application.ExeName)+'settings.ini'))then
     begin
     MemoLog.Lines.Add('Файл настроек обнаружен, чтение..');
     MemoScroll();
     ini := TINIFile.Create(ExtractFilePath(Application.ExeName)+'settings.ini');
     Form1.Top:=ini.ReadInteger('form1','top',Form1.Top);
     Form1.Left:=ini.ReadInteger('form1','left',Form1.Left);
     ws:=ini.ReadInteger('form1','ws',0);
     if(ws = 1) then
         begin
         Form1.WindowState := wsNormal;
         Form1.Hide;
         Form1.ShowInTaskBar := stNever;
         TrayIcon1.Show;
         end;
     case ini.ReadString('update','time','5m') of
          '5m': ComboBox1.ItemIndex:=0;
          '10m': ComboBox1.ItemIndex:=1;
          '15m': ComboBox1.ItemIndex:=2;
          '30m': ComboBox1.ItemIndex:=3;
          '1h': ComboBox1.ItemIndex:=4;
          '3h': ComboBox1.ItemIndex:=5;
          '6h': ComboBox1.ItemIndex:=6;
     end;
     Edit1.Text:=ini.ReadString('update','url','');
     if IsValidUrl(Edit1.Text) then
        begin
        MemoLog.Lines.Add('URL соответствует формату. Старт обновления.');
        MemoScroll();
        SaveButton.Enabled := false;
        case ComboBox1.Text of
             '5m': IdleTimer1.Interval:= 5 * 60 * 1000;
             '10m': IdleTimer1.Interval:= 10 * 60 * 1000;
             '15m': IdleTimer1.Interval:= 15 * 60 * 1000;
             '30m': IdleTimer1.Interval:= 30 * 60 * 1000;
             '1h': IdleTimer1.Interval:= 1 * 3600 * 1000;
             '3h': IdleTimer1.Interval:= 3 * 3600 * 1000;
             '6h': IdleTimer1.Interval:= 6 * 3600 * 1000;
        end;
        IdleTimer1.OnTimer(Form1);
        IdleTimer1.Enabled:= true;
        end
     else
        begin
        MemoLog.Lines.Add('Ошибка: URL не соответствует формату!');
        MemoScroll();
        SaveButton.Enabled := true;
        IdleTimer1.Enabled:= false;
        end;
  end else
  begin
     MemoLog.Lines.Add('Файл настроек отсутствует, значения по умолчанию');
     MemoScroll();
  end;
  end;
end;

procedure TForm1.MenuItem1Click(Sender: TObject);
begin
  Form1.WindowState := wsNormal;
  Form1.ShowInTaskBar := stDefault;
  Form1.Show;
  TrayIcon1.Hide;
end;

procedure TForm1.MenuItem2Click(Sender: TObject);
begin
  Form1.Close;
end;

procedure TForm1.SaveButtonClick(Sender: TObject);
begin
  SaveSettings.Click;
  LoadSettings.Click;
  SaveButton.Enabled:=false;
end;

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  if MessageDlg('Закрыть программу? Обновление прекратится!', mtCustom, [mbYes, mbNo], 0) = mrYES then
     begin
     SaveSettings.Click;
     end
  else
     begin
     CloseAction := caNone;
     end;
end;

procedure TForm1.IdleTimer1Timer(Sender: TObject);
var s: string;
begin
  try
     s := TFPCustomHTTPClient.SimpleGet(Edit1.Text);
  except
      on E: Exception do
      begin
        s:= 'ошибка, '+E.Message;
        MemoScroll();
      end;
   end;
   MemoLog.Lines.Add('Обновление, результат: '+ s);
   MemoScroll();
   Timer1.Enabled:=false;
   msec_to_run := IdleTimer1.Interval;
   Timer1.Enabled:=true;
end;

procedure TForm1.SaveSettingsClick(Sender: TObject);
var ini: TIniFile;
begin
  ini := TINIFile.Create(ExtractFilePath(Application.ExeName)+'settings.ini');
  if Form1.Visible then
     begin
     ini.WriteInteger('form1','top', Form1.Top);
     ini.WriteInteger('form1','left', Form1.Left);
     end;
  case Form1.visible of
    true: ini.WriteInteger('form1', 'ws', 0);
    false: ini.WriteInteger('form1', 'ws', 1);
  end;
  ini.WriteString('update', 'time', ComboBox1.Text);
  ini.WriteString('update', 'url', Edit1.Text);

end;

procedure TForm1.Timer1Timer(Sender: TObject);
var h,m,s,c: integer;
    hh,mm,ss: string;
begin
  if(IdleTimer1.Enabled) then
     begin
     if(msec_to_run > 0) then
        begin
        c := trunc(msec_to_run / 1000);
        h := trunc(c / 3600);
        m := trunc((c - (h * 3600)) / 60);
        s := trunc(c - ((h * 3600) + (m * 60)));
        if (h < 10) then hh := '0'+IntToStr(h) else hh := IntToStr(h);
        if (m < 10) then mm := '0'+IntToStr(m) else mm := IntToStr(m);
        if (s < 10) then ss := '0'+IntToStr(s) else ss := IntToStr(s);
        StatusBar1.Panels[0].Text:='До следующего обновления: '+hh+':'+mm+':'+ss;
        TrayIcon1.Hint:='hldns.ru | '+StatusBar1.Panels[0].Text;
        msec_to_run := msec_to_run - Timer1.Interval;
        end;
     end
  else
    begin
    StatusBar1.Panels[0].Text:='Обновление остановлено';
    end;
end;

procedure TForm1.TrayIcon1Click(Sender: TObject);
begin
  TrayIcon1.PopUpMenu.PopUp;
end;

end.

