unit Main;

interface

uses
  PKSTController, frmDisplay,
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, Buttons, ExtCtrls, Menus, AppEvnts,
  AppEvent, Mask, IDStack, RXShell;

type
  TPKSTClientForm = class(TForm)
    PageControl1: TPageControl;
    tabCent: TTabSheet;
    tabStatus: TTabSheet;
    tabSetup: TTabSheet;
    Panel2: TPanel;
    lvDownloads: TListView;
    lvUploads: TListView;
    GroupBox1: TGroupBox;
    lstServer: TListBox;
    Panel1: TPanel;
    BitBtn1: TBitBtn;
    BitBtnCancle: TBitBtn;
    bitbtnApply: TBitBtn;
    Bevel1: TBevel;
    edtServer: TEdit;
    Button1: TButton;
    Button2: TButton;
    lbedtUpload: TLabeledEdit;
    lbedtDownload: TLabeledEdit;
    lbedtName: TLabeledEdit;
    lbGuid: TLabel;
    lbEdtRcv: TLabeledEdit;
    btnBrows: TButton;
    RxTrayIcon1: TRxTrayIcon;
    PopupMenu1: TPopupMenu;
    N3: TMenuItem;
    N1: TMenuItem;
    menuDisplay: TMenuItem;
    ApplicationEvents1: TApplicationEvents;
    Label2: TLabel;
    BitBtnOpen: TBitBtn;
    BitBtnStop: TBitBtn;
    TabSheet1: TTabSheet;
    Memo1: TMemo;
    Button3: TButton;
    Button4: TButton;
    chkboxCRC: TCheckBox;
    procedure N1Click(Sender: TObject);
    procedure menuDisplayClick(Sender: TObject);
    procedure bitbtnApplyClick(Sender: TObject);
    procedure RxTrayIcon1DblClick(Sender: TObject);
    procedure ApplicationEvents1Minimize(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure BitBtnOpenClick(Sender: TObject);
    procedure BitBtnStopClick(Sender: TObject);
    procedure BitBtn1Click(Sender: TObject);
    procedure lvDownloadsData(Sender: TObject; Item: TListItem);
    procedure btnBrowsClick(Sender: TObject);
    procedure lvUploadsData(Sender: TObject; Item: TListItem);
    procedure lbedtNameChange(Sender: TObject);
    procedure BitBtnCancleClick(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure lbedtDownloadKeyPress(Sender: TObject; var Key: Char);
    procedure lbedtUploadKeyPress(Sender: TObject; var Key: Char);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
    Atom: TAtom;
    CanClose : Boolean;
    DisplayForm: TDisplayForm;

    procedure initClient;
    procedure DownloadNotify(sender: TObject);
    procedure OnScheduleChange(sender: TObject);
    procedure OnSubTitle(Subtitle: string);
    procedure UploadNotify(sender: TObject);
  public
    { Public declarations }
    _ClientController: TPKSTController;
    procedure initschudle;
  end;

var
  PKSTClientForm: TPKSTClientForm;

implementation

uses HashUnit, PKSTconst, PKSTutils, FileCtrl, Contnrs;

{$R *.dfm}
procedure TPKSTClientForm.N1Click(Sender: TObject);
begin
  CanClose := true;
  _ClientController.Stop;
  Close;
end;

procedure TPKSTClientForm.menuDisplayClick(Sender: TObject);
begin
  if Visible then
  begin
    ShowWindow(Application.Handle, SW_SHOWMINIMIZED);
    hide;
    ShowWindow(Application.Handle, SW_Hide);
  end
  else
  begin
    ShowWindow(Application.Handle, SW_RESTORE);
    show;
    ShowWindow(Application.Handle, SW_SHOW);
  end;
  if Visible then
    menuDisplay.Caption := '隐藏'
  else
    menuDisplay.Caption := '显示'; {}
end;

procedure TPKSTClientForm.bitbtnApplyClick(Sender: TObject);
var
  i: Integer;
begin
  _ClientController.MaxDownloads := StrToInt(lbedtDownload.Text);
  _ClientController.MaxUpLoads := StrToInt(lbedtUpload.Text);
  _ClientController.NodeName := lbedtName.Text;
  _ClientController.RcvDir := lbEdtRcv.Text;
  _ClientController.CRCCheck := chkboxCRC.Checked;
  _ClientController.InitServers(lstServer.Items);
  _ClientController.Save(SlashSep(ExtractFilePath(Application.ExeName),'Client.Dat'));
  {TODO 更新服务器列表}
{  for i:= 0 to _ClientController.ServerCount-1 do
    _ClientController.Connect(_ClientController.ServerAdd[i], PKST_SERVERPORT);{}
  bitbtnApply.Enabled := false;  
{  Application.Minimize;
  Hide;{}
end;

procedure TPKSTClientForm.RxTrayIcon1DblClick(Sender: TObject);
begin
  menuDisplay.Click;
end;

procedure TPKSTClientForm.ApplicationEvents1Minimize(Sender: TObject);
begin
  ShowWindow(Application.Handle, SW_SHOWMINIMIZED);
  hide;
  ShowWindow(Application.Handle, SW_Hide);
  if Visible then
    menuDisplay.Caption := '隐藏'
  else
    menuDisplay.Caption := '显示'; {}
  if Assigned(DisplayForm) then
    DisplayForm.Show;
end;

procedure TPKSTClientForm.initClient;
var
  GUID: TGUID;
  i: integer;
begin
  if _ClientController=nil then
    exit;
  ForceDirectories(ExtractFilePath(Application.ExeName)+'TMP');
  if FileExists(ExtractFilePath(Application.ExeName)+'Client.Dat') then
    _ClientController.Init(SlashSep(ExtractFilePath(Application.ExeName),'Client.Dat'))
  else
  begin
    CreateGUID(GUID);
    _ClientController.Init(GUID);
    _ClientController.Save(SlashSep(ExtractFilePath(Application.ExeName),'Client.Dat'));
  end;
  lbGuid.Caption := 'GUID:'+GUIDToString(_ClientController.NodeID);
  lbedtName.Text := _ClientController.NodeName;
  lbedtDownload.Text := IntToStr(_ClientController.MaxDownloads);
  lbedtUpload.Text := IntToStr(_ClientController.MaxUpLoads);
  lbEdtRcv.Text := _ClientController.RcvDir;
  chkboxCRC.Checked := _ClientController.CRCCheck;
  _ClientController.Open;
  _ClientController.OnDownloadNotify := DownloadNotify;
  _ClientController.OnUploadNotify := UploadNotify;
  _ClientController.OnScheduleChange := OnScheduleChange;
  _ClientController.OnSubTitle := OnSubTitle;
  for i:= 0 to _ClientController.ServerCount-1 do
    lstServer.AddItem(_ClientController.ServerAdd[i],nil);{}
  bitbtnApply.Enabled := false;
end;

procedure TPKSTClientForm.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  if CanClose then
    exit;
  BitBtnCancle.Click;
  Abort;
end;

procedure TPKSTClientForm.FormCreate(Sender: TObject);
begin
  Atom := GlobalAddAtom('PerCast V1.0');
  Canclose := false;
  _ClientController := TPKSTController.Create(False);
  initClient;
  DisplayForm := TDisplayForm.Create(self);
  DisplayForm.Show;
  initschudle;
  DisplayForm.WindowState := wsMaximized;
end;

procedure TPKSTClientForm.Button1Click(Sender: TObject);
begin
  if lstServer.Items.Count >= PKST_ServerLicenses then exit;
  if edtServer.Text<>'' then
  begin
    if lstServer.Items.IndexOf(edtServer.Text)<0 then
      lstServer.Items.Add(edtServer.Text);
  end;
end;

procedure TPKSTClientForm.Button2Click(Sender: TObject);
begin
  if lstServer.ItemIndex>=0 then
  begin
    lstServer.Items.Delete(lstServer.ItemIndex);
  end;
end;

procedure TPKSTClientForm.FormDestroy(Sender: TObject);
begin
  DisplayForm.Free;
  DisplayForm := nil;
  GlobalDeleteAtom(Atom);
end;

procedure TPKSTClientForm.BitBtnOpenClick(Sender: TObject);
begin
  _ClientController.Open;
  BitBtnStop.Enabled := True;
  BitBtnOpen.Enabled := False;
end;

procedure TPKSTClientForm.BitBtnStopClick(Sender: TObject);
begin
  _ClientController.Stop;
  BitBtnStop.Enabled := False;
  BitBtnOpen.Enabled := True;
end;

procedure TPKSTClientForm.BitBtn1Click(Sender: TObject);
begin
  bitbtnApply.Click;
  bitbtnApply.Enabled := false;
  menuDisplay.Click;
end;

procedure TPKSTClientForm.DownloadNotify(sender: TObject);
begin
  with TPKSTDownLoadManager(sender) do
  begin
    lvDownloads.Items.Count := DownLoadCount+WaitCount+CompliteCount;
    lvDownloads.Refresh;
  end;{}
end;

type
  TController = class(TPKSTController);
procedure TPKSTClientForm.lvDownloadsData(Sender: TObject;
  Item: TListItem);
var
  Downloadinfo: TPKSTDLTaskInfo;
  stmp: string;
  Idx: Integer;
begin
  Idx := Item.Index;
  if idx < TController(_ClientController)._DownloadManager.DownLoadCount then
  begin
    Downloadinfo := TController(_ClientController)._DownloadManager.GetDownloadInfo(idx);
    Item.Caption := Downloadinfo.DownloadInfo.FileName;
    stmp := ' 接收中';
    Item.SubItems.Add(inttostr(Downloadinfo.DownloadInfo.DownloadedSize)+'/'+inttostr(Downloadinfo.DownloadInfo.FileSize)+stmp);
    Item.SubItems.Add(Downloadinfo.DownloadInfo.PublishServer);
    Item.SubItems.Add(Downloadinfo.DownloadHost);
    exit;
  end
  else
    Idx := Idx-TController(_ClientController)._DownloadManager.DownLoadCount;

  if Idx < TController(_ClientController)._DownloadManager.WaitCount then
  begin
    Downloadinfo := TController(_ClientController)._DownloadManager.GetWaiteInfo(idx);
    Item.Caption := Downloadinfo.DownloadInfo.FileName;
    stmp := ' 等待中';
    Item.SubItems.Add(inttostr(Downloadinfo.DownloadInfo.DownloadedSize)+'/'+inttostr(Downloadinfo.DownloadInfo.FileSize)+stmp);
    Item.SubItems.Add(Downloadinfo.DownloadInfo.PublishServer);
    Item.SubItems.Add(Downloadinfo.DownloadHost);
    exit;
  end
  else
    Idx := Idx-TController(_ClientController)._DownloadManager.WaitCount;

  if Idx < TController(_ClientController)._DownloadManager.CompliteCount then
  begin
    Downloadinfo := TController(_ClientController)._DownloadManager.GetCompliteInfo(idx);
    Item.Caption := Downloadinfo.DownloadInfo.FileName;
    stmp := ' 已完成';
    Item.SubItems.Add(inttostr(Downloadinfo.DownloadInfo.FileSize)+stmp);
    Item.SubItems.Add(Downloadinfo.DownloadInfo.PublishServer);
    Item.SubItems.Add(Downloadinfo.DownloadHost);
  end;
end;

procedure TPKSTClientForm.btnBrowsClick(Sender: TObject);
var
  dirstr: string;
begin
  if SelectDirectory('请选择存放路径', '', dirstr) then
  begin
    _ClientController.RcvDir := dirstr;
    lbEdtRcv.Text := dirstr;
  end;
end;

procedure TPKSTClientForm.UploadNotify(sender: TObject);
begin
  with TPKSTUpLoadManager(sender) do
  begin
    lvUploads.Items.Count := UpLoadCount;
//    lvUploads.Refresh;
  end;
end;

procedure TPKSTClientForm.lvUploadsData(Sender: TObject; Item: TListItem);
var
  Filename: string;
  FileSize: Int64;
  DownloadSize: Int64;
begin
  TController(_ClientController)._UpLoadManager.GetUpLoadInfo(Item.Index, Filename,FileSize,DownloadSize);
  Item.Caption := Filename;
  Item.SubItems.add(IntToStr(DownloadSize)+'/'+IntToStr(FileSize)+' 传递中');
end;

procedure TPKSTClientForm.lbedtNameChange(Sender: TObject);
begin
  bitbtnApply.Enabled := true;
end;

procedure TPKSTClientForm.BitBtnCancleClick(Sender: TObject);
begin
  initClient;
  bitbtnApply.Enabled := false;
  menuDisplay.Click;
end;

procedure TPKSTClientForm.FormShow(Sender: TObject);
begin
  Top := screen.WorkAreaHeight - Height;
  Left := screen.WorkAreaWidth - Width;
end;

procedure TPKSTClientForm.lbedtDownloadKeyPress(Sender: TObject;
  var Key: Char);
begin
  if not (key in ['0'..'9']) then
    Key := #0;
end;

procedure TPKSTClientForm.lbedtUploadKeyPress(Sender: TObject;
  var Key: Char);
begin
  if not (key in ['0'..'9']) then
    Key := #0;
end;


type
  TDController = class(TPKSTController);
  TDTaskManager = class(TPKSTTaskManager);
  TDNodeManager = class(TPKSTNodeManager);

procedure TPKSTClientForm.Button3Click(Sender: TObject);
var
  i,j: Integer;
begin
  memo1.Clear;
  memo1.Lines.BeginUpdate;
  with TDNodeManager(TDController(_ClientController)._NodeManager) do
  begin
    memo1.Lines.Add('已连接上的服务器:');
    for i:= ActiveNodes.Count-1 downto 0 do
      with TPKSTNodeInfoEX(ActiveNodes.Items[i]) do
      begin
        memo1.Lines.Add('=========================');
        memo1.Lines.Add(GUIDToString(ServerID));
        memo1.Lines.Add(ServerName);
        memo1.Lines.Add(ServerHost);
        memo1.Lines.Add(GStack.TInAddrToString(LocalIP));
        memo1.Lines.Add('上次响应时间:'+inttostr(GetTickCount-Lastresponse)+'MS前');
        memo1.Lines.Add('子节点数:'+inttostr(Nodes.count));
        for j:= Nodes.Count-1 downto 0 do
          with TPKSTNodeInfo(Nodes.Items[j]) do
          begin
            memo1.Lines.Add('-------------');
            memo1.Lines.Add(NodeName);
            memo1.Lines.Add(GUIDToString(NodeID));
            memo1.Lines.Add(GStack.TInAddrToString(NodeAdd.IP));
            memo1.Lines.Add(GStack.TInAddrToString(NodeAdd.LocalIP));
            memo1.Lines.Add(inttostr(NodeAdd.Port));
          end;
      end;

    memo1.Lines.Add('未连接上的服务器:');
    for i:= DeActiveNodes.Count-1 downto 0 do
      with TPKSTNodeInfoEX(DeActiveNodes.Items[i]) do
      begin
        memo1.Lines.Add('=========================');
        memo1.Lines.Add(GUIDToString(ServerID));
        memo1.Lines.Add(ServerName);
        memo1.Lines.Add(ServerHost);
        memo1.Lines.Add(GStack.TInAddrToString(LocalIP));
        memo1.Lines.Add('上次连接时间:'+inttostr(GetTickCount-Lastresponse)+'MS前');
        memo1.Lines.Add('子节点数:'+inttostr(Nodes.count));
        for j:= Nodes.Count-1 downto 0 do
          with TPKSTNodeInfo(Nodes.Items[j]) do
          begin
            memo1.Lines.Add('-------------');
            memo1.Lines.Add(NodeName);
            memo1.Lines.Add(GUIDToString(NodeID));
            memo1.Lines.Add(GStack.TInAddrToString(NodeAdd.IP));
            memo1.Lines.Add(GStack.TInAddrToString(NodeAdd.LocalIP));
            memo1.Lines.Add(inttostr(NodeAdd.Port));
          end;
      end;
  end;
  memo1.Lines.EndUpdate;
end;

procedure TPKSTClientForm.OnScheduleChange(sender: TObject);
begin
  initschudle;
end;

procedure TPKSTClientForm.OnSubTitle(Subtitle: string);
begin
  if Assigned(DisplayForm) then
    DisplayForm.ChangesSubTitle(Subtitle);
end;

procedure TPKSTClientForm.initschudle;
var
  fn: string;
begin
  fn := SlashSep(ExtractFilePath(application.ExeName), PKSTSCHFILENAME);
  if Assigned(DisplayForm) then
    DisplayForm.initschudle(fn);
end;

end.
