unit uVisualFrame;
{<uVisualFrame

this unit is central in component
all methods of developed component will be gathered here,

to call some method or property we should do following

 MyNewComponent.VisualFrame.SomeMethod
 or
 MyNewComponent.VisualFrame.SomeProperty

}

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, IdBaseComponent, IdComponent, IdTCPConnection,
  IdTCPClient, IdHTTP,


  HTTPApp,
  IdMultipartFormData, FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error, FireDAC.UI.Intf, FireDAC.Phys.Intf,
  FireDAC.Stan.Def, FireDAC.Stan.Pool, FireDAC.Stan.Async, FireDAC.Phys, FireDAC.VCLUI.Wait, Data.DB,
  FireDAC.Comp.Client, System.IOUtils,IdIOHandlerStack,IdIOHandlerSocket,IdIOHandler,System.RegularExpressions,
  System.Types, System.SyncObjs,

  //MyUnits

  uHTTP_ConnectionParams, uHTTPRequests,
  uDivideAndGatherFile,
  uSendFileInChunks,
  uSendFileInChunks2,
  uDataBaseUnit,uDBGridSort,uSearch, uControlPanel,
  uGetLink,uFileType,
  uInsertPictureInDocument,
  uInsertVideoInDocument,
  uDelete_PS_HTTPClient,
  uFileProperties,

  Vcl.ComCtrls, Vcl.Buttons, Vcl.AppEvnts,
  Vcl.ExtCtrls, Vcl.Grids, Vcl.DBGrids, System.ImageList, Vcl.ImgList, FireDAC.Phys.MySQL, FireDAC.Phys.MySQLDef,
  FireDAC.Stan.Param, FireDAC.DatS, FireDAC.DApt.Intf, FireDAC.DApt, FireDAC.Comp.DataSet, FireDAC.Comp.UI, Vcl.Menus

  // IdSSL, IdSSLOpenSSL
  ;


type
  TVisualFrame_HTTP = class(TFrame)
    OpenDialog: TOpenDialog;
    IdHTTP: TIdHTTP;
    PageControl: TPageControl;
    tsInsertLink: TTabSheet;
    tsMediaLibrary: TTabSheet;
    tsLoadFile: TTabSheet;
    tsLastUploads: TTabSheet;
    bUpload: TButton;
    ApplicationEvents: TApplicationEvents;
    tsTest: TTabSheet;
    bTest: TButton;
    sbUploads: TScrollBox;
    pLeftPanelMediaLibrary: TPanel;
    ilControlButtons: TImageList;
    tsKeep2Share: TTabSheet;
    mLinks: TMemo;
    pTopPanelK2S: TPanel;
    bUploadOnKeep2Share: TButton;
    bGetFirstLinkExample: TButton;
    DataSource: TDataSource;
    FDGUIxWaitCursor: TFDGUIxWaitCursor;
    FDTable: TFDTable;
    FDTableid: TFDAutoIncField;
    FDTableidParent: TIntegerField;
    FDTablecreationDateTime: TDateTimeField;
    FDTablechangesDateTime: TDateTimeField;
    FDTablelastAccessDateTime: TDateTimeField;
    FDTableisFolder: TBooleanField;
    FDTableusers_id: TIntegerField;
    FDTableLink: TStringField;
    Splitter1: TSplitter;
    pRightPanelMediaLibrary: TPanel;
    pNavPanel: TPanel;
    pNavPanelButtons: TPanel;
    bHome: TBitBtn;
    bUp: TBitBtn;
    bUpdate: TBitBtn;
    eAdress: TEdit;
    pSearchPanel: TPanel;
    pSearchPanelTop: TPanel;
    bSearch: TBitBtn;
    eSearch: TEdit;
    pSearchPanelBottom: TPanel;
    lSearchResultLabel: TLabel;
    bNextSearchResult: TBitBtn;
    bPreviousSearchResult: TBitBtn;
    cbSearchType: TComboBox;
    pSortPanel: TPanel;
    cbSortParameter: TComboBox;
    cbSortDirection: TComboBox;
    bSort: TBitBtn;
    ScrollBoxMediaLibrary: TScrollBox;
    ImageList: TImageList;
    cbAllFilesOrByDate: TComboBox;
    cbFileTypes: TComboBox;
    cbTableOrGallery: TComboBox;
    IdHTTPDownloadPicture: TIdHTTP;
    ZaplatkaTimer: TTimer;
    DBGrid: TDBGrid;
    Bevel: TBevel;
    image: TImage;
    FDConnectionForTest: TFDConnection;
    FDTableNameWideString: TWideStringField;
    FDTablerelPath: TWideStringField;
    FDTableabsPath: TWideStringField;
    IdHTTPDownloadFile: TIdHTTP;
    SaveDialog: TSaveDialog;
    pBottomPanel: TPanel;
    StatusBar: TStatusBar;
    pBottomRightPanel: TPanel;
    ProgressBar: TProgressBar;
    ilFoldersAndFiles16: TImageList;
    FDTableFileSizeCalc: TStringField;
    FDTablefileSize: TIntegerField;
    MainPopupMenu: TPopupMenu;
    pInsertInDocument: TMenuItem;
    pAddFile: TMenuItem;
    pDeleteFile: TMenuItem;
    pGetLink: TMenuItem;
    pDownloadFile: TMenuItem;
    pSearch: TMenuItem;
    pSort: TMenuItem;
    pTopPanelLastUploads: TPanel;
    bOpenAllFiles: TBitBtn;
    procedure FrameResize(Sender: TObject);
    procedure bUploadClick(Sender: TObject);
    procedure bTestClick(Sender: TObject);
    procedure ApplicationEventsException(Sender: TObject; E: Exception);
    procedure bAllFilesClick(Sender: TObject);
    procedure bUploadOnKeep2ShareClick(Sender: TObject);
    procedure bGetFirstLinkExampleClick(Sender: TObject);



    procedure DBGridDblClick(Sender: TObject);
    procedure FDTableForTestCalcFields(DataSet: TDataSet);
    procedure FDTableCalcFields(DataSet: TDataSet);
    procedure PageControlChange(Sender: TObject);
    procedure bUpClick(Sender: TObject);
    procedure bUpdateClick(Sender: TObject);
    procedure bHomeClick(Sender: TObject);
    procedure DBGridTitleClick(Column: TColumn);
    procedure bSortClick(Sender: TObject);
    procedure bSearchClick(Sender: TObject);
    procedure bNextSearchResultClick(Sender: TObject);
    procedure bPreviousSearchResultClick(Sender: TObject);
    procedure ScrollBoxMediaLibraryResize(Sender: TObject);
    procedure cbFileTypesSelect(Sender: TObject);
    procedure cbAllFilesOrByDateSelect(Sender: TObject);
    procedure DBGridCellClick(Column: TColumn);
    procedure imageClick(Sender: TObject);
    procedure ZaplatkaTimerTimer(Sender: TObject);
    procedure FDTableAfterGetRecord(DataSet: TFDDataSet);
    procedure DBGridKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure DBGridKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
    procedure StatusBarClick(Sender: TObject);
    procedure imageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure cbTableOrGallerySelect(Sender: TObject);
    procedure DBGridDrawColumnCell(Sender: TObject; const [Ref] Rect: TRect; DataCol: Integer; Column: TColumn;
      State: TGridDrawState);
    procedure pInsertInDocumentClick(Sender: TObject);
    procedure pAddFileClick(Sender: TObject);
    procedure pDeleteFileClick(Sender: TObject);
    procedure pGetLinkClick(Sender: TObject);
    procedure pDownloadFileClick(Sender: TObject);
    procedure pSearchClick(Sender: TObject);
    procedure pSortClick(Sender: TObject);
    procedure bOpenAllFilesClick(Sender: TObject);




  private
    { Private declarations }

    //Fields
    FHTTP_ConnectionParams:THTTP_ConnectionParams;
    FHTTPServerToRequest:string;

    FHTTPRequests:THTTPRequests;

    FCS:TCriticalSection;
    FCS2:TCriticalSection;

    FLinksOnKeep2Share:TStringList;

    FFilesSL:TStringList;

    FSendFileInChunks:TSendFileInChunks;
    FSendFileInChunks2:TSendFileInChunks2;

    //Events
    FOnKeep2ShareStartUpload:TNotifyEvent;
    FOnKeep2ShareEndUpload:TNotifyEvent;

    FDataBaseUnit:TDataBaseUnit;




    FDBGridSort:TDBGridSort;

    FSearch:TSearch;

    FControlPanel:TControlPanel;

    FGetLinkForm:TFGetLink;

    FFileType:TFileType;

    FIsAllFilesMode:boolean;

    FInsertPictureInDocument:TInsertPictureInDocument;

    FDelete_PS_HTTPClient:TDelete_PS_HTTPClient;


    FFDConnection:TFDConnection;

    FCSDownloadPicture:TCriticalSection;
    FCSDownloadFile:TCriticalSection;

    FCurrentPictureWidth:Integer;


    FidCurrentParent:integer;


    FAdresses:TStringList;

    FFileProperties:TFileProperties;

    FInsertVideoInDocument:TInsertVideoInDocument;

    FSomeNumberForTest:integer;



    procedure CenterButton;
    {< centering some visual elements relatively to self}


    procedure DisposeControlPanel;
    {< will arrange buttons on Control Panel}

    procedure SetDefaultImagetoMediaLibrary;

    procedure DrawFoldersAndFilesIcons(Column: TColumn; Sender: TObject; Rect: TRect);
    {< will draw folder or file icons}




  public
    { Public declarations }


   constructor Create(AOwner: TComponent); override;
   destructor  Destroy; override;

   procedure DefineServerToRequest;
   {< this will define Server To Request like

   FHTTPServerToRequest := Protocol + '://' + Host + ':' + Port;
   we define it in one unit and can use in different one

   }



    procedure InitialUpdate;
    {< uploads root directory for current user}

    procedure UpdateCurrentFolder;

    procedure DownloadAndSetOnePicture;

    procedure DownloadFile;

    procedure GiveHumanFileSize(FilSizeBytes: Int64; var HumanFileSize: String);

   //properties

   {Connection property}

   property FDConnection:TFDConnection read FFDConnection write FFDConnection;

   property HTTP_ConnectionParams:THTTP_ConnectionParams read
   FHTTP_ConnectionParams write FHTTP_ConnectionParams;

   property HTTPServerToRequest:string read FHTTPServerToRequest
   write FHTTPServerToRequest;

   property HTTPRequests:THTTPRequests read FHTTPRequests write FHTTPRequests;

   property  CS:TCriticalSection read  FCS write  FCS;

   property  CS2:TCriticalSection read FCS2 write FCS2;

   property LinksOnKeep2Share:TStringList read FLinksOnKeep2Share write FLinksOnKeep2Share;

   property SendFileInChunks:TSendFileInChunks
   read FSendFileInChunks write FSendFileInChunks;

   property OnKeep2ShareEndUpload:TNotifyEvent
   read FOnKeep2ShareEndUpload write FOnKeep2ShareEndUpload;

   property FilesSL:TStringList read FFilesSL write FFilesSL;

   property OnKeep2ShareStartUpload:TNotifyEvent read FOnKeep2ShareStartUpload
   write FOnKeep2ShareStartUpload;

   property DataBaseUnit:TDataBaseUnit read FDataBaseUnit write FDataBaseUnit;

   property GetLinkForm:TfGetLink read FGetLinkForm write FGetLinkForm;

   property FileType:TFileType read FFileType write FFileType;

   property InsertPictureInDocument:TInsertPictureInDocument
   read FInsertPictureInDocument write FInsertPictureInDocument;

   property IsAllFilesMode:boolean
   read FIsAllFilesMode write FIsAllFilesMode;

   property Delete_PS_HTTPClient:TDelete_PS_HTTPClient read FDelete_PS_HTTPClient
   write FDelete_PS_HTTPClient;


   property CSDownloadPicture:TCriticalSection
   read FCSDownloadPicture write FCSDownloadPicture;

   property CSDownloadFile:TCriticalSection
   read FCSDownloadFile write FCSDownloadFile;




   property CurrentPictureWidth:Integer read FCurrentPictureWidth write FCurrentPictureWidth;
   property CurrentPictureHeight:Integer read FCurrentPictureWidth write FCurrentPictureWidth;


  property idCurrentParent:integer read FidCurrentParent write FidCurrentParent;

  end;

implementation

{$R *.dfm}

uses

//My Units
uCreateUniqueName,uSendManyFilesInChunks, uSendFileInChunksThread,
uDownloadPictureThread,uDownLoadFileThread;

var FSendManyFilesInChunks_UnitVar:TSendManyFilesInChunks;

procedure TVisualFrame_HTTP.ApplicationEventsException(Sender: TObject; E: Exception);
begin

if (Sender is TSendFileInChunksThread) then

begin

      ShowMessage(

      'Error Raised '+E.ClassName+'Error Message : '+
                  E.Message

                  );

end;



// TDownloadPictureThread Exception catching
if (Sender is TDownloadPictureThread) then

begin

      ShowMessage(

      'Error Raised '+E.ClassName+'Error Message : '+
                  E.Message

                  );

end;





// TDownloadFileThread Exception catching
if (Sender is TDownloadFileThread) then

begin

      ShowMessage(

      'Error Raised '+E.ClassName+'Error Message : '+
                  E.Message

                  );

end;






end;


procedure TVisualFrame_HTTP.bAllFilesClick(Sender: TObject);
begin

PageControl.ActivePageIndex:=1;

end;


procedure TVisualFrame_HTTP.bGetFirstLinkExampleClick(Sender: TObject);
begin

if FFilesSL.Count>0 then

ShowMessage(
FLinksOnKeep2Share.Values[FFilesSL[0]]
);



end;



procedure TVisualFrame_HTTP.bHomeClick(Sender: TObject);
begin
InitialUpdate;
end;

procedure TVisualFrame_HTTP.bNextSearchResultClick(Sender: TObject);

var NextID:integer;

begin
//



  with FSearch do begin

  if IDSearchResult.Count=0 then Exit;

  if CurrentIndex<MaxIndex then

   begin
   CurrentIndex:=CurrentIndex+1;
   NextID:=IDSearchResult[CurrentIndex].ToInteger;
   FDTable.Locate('id',NextID,[]);

   lSearchResultLabel.Caption:=
   'Результаты '+ (CurrentIndex+1).ToString+' / '+(MaxIndex+1).ToString;

   end;


  end;


end;

procedure TVisualFrame_HTTP.bOpenAllFilesClick(Sender: TObject);
begin

cbAllFilesOrByDate.ItemIndex:=0;
cbAllFilesOrByDateSelect(Self);
PageControl.ActivePage:=tsMediaLibrary;
tsMediaLibrary.Show;
end;

procedure TVisualFrame_HTTP.bPreviousSearchResultClick(Sender: TObject);
VAR NextID:Integer;
begin


  with FSearch do begin

  if IDSearchResult.Count=0 then Exit;
  

  if CurrentIndex>0 then

   begin
   CurrentIndex:=CurrentIndex-1;
   NextID:=IDSearchResult[CurrentIndex].ToInteger;
   FDTable.Locate('id',NextID,[]);

   lSearchResultLabel.Caption:=
   'Результаты '+ (CurrentIndex+1).ToString+' / '+(MaxIndex+1).ToString;

   end;


  end;



end;

procedure TVisualFrame_HTTP.bSearchClick(Sender: TObject);
begin


if Trim(eSearch.Text)='' then Exit;


 case cbSearchType.ItemIndex of

 0:FSearch.EntrySearch( Trim(eSearch.Text) );
 1:FSearch.ExactSearch( Trim(eSearch.Text) );
 2:FSearch.CaseSensitiveSearch( Trim(eSearch.Text) );

 end;



end;

procedure TVisualFrame_HTTP.bSortClick(Sender: TObject);
begin

FDBGridSort.
DBGridSortComboboxes(cbSortParameter.ItemIndex,cbSortDirection.ItemIndex);

end;

procedure TVisualFrame_HTTP.InitialUpdate;

var IDOfRootFolderOfUser:Integer;
    IDUser:integer;

begin


 if FDConnection.Connected then

 begin

 IDUser:=HTTP_ConnectionParams.IDUser.ToInteger();


   if FIsAllFilesMode then

   begin

   FDataBaseUnit.OpenFilesOfUser(IDUser);
   ZaplatkaTimer.Enabled:=True;

   // adress string
   FAdresses.Clear;
   FAdresses.Add(DBGrid.DataSource.DataSet.FieldByName('Link').AsString);
   eAdress.Text:=FAdresses[0];

   end


   else

   begin

      IDOfRootFolderOfUser:=
      FDataBaseUnit.GetIDOfRootFolderOfUser(IDUser);

      FidCurrentParent:=IDOfRootFolderOfUser;

      FDataBaseUnit.OpenFolder(IDOfRootFolderOfUser,IDUser);

     // adress string
     FAdresses.Clear;
     FAdresses.Add('/');
     eAdress.Text:=FAdresses[0];


   end;



 end;


 // Status Bar
 if ( Assigned(FDTable) )
and Assigned( StatusBar.Panels[0] )

 then
StatusBar.Panels[0].Text:='Всего элементов '+FDTable.RecordCount.ToString;


end;

procedure TVisualFrame_HTTP.pDeleteFileClick(Sender: TObject);
begin
FControlPanel.bDeleteClick(Self);
end;

procedure TVisualFrame_HTTP.pDownloadFileClick(Sender: TObject);
begin
FControlPanel.bDownLoadFileClick(Self);
end;

procedure TVisualFrame_HTTP.pGetLinkClick(Sender: TObject);
begin
FControlPanel.bGetLinkClick(Self);
end;

procedure TVisualFrame_HTTP.pInsertInDocumentClick(Sender: TObject);
begin
FControlPanel.bInsertToDocumentClick(Self);
end;

procedure TVisualFrame_HTTP.pSearchClick(Sender: TObject);
begin
FControlPanel.bSearchClick(Self);
end;

procedure TVisualFrame_HTTP.pSortClick(Sender: TObject);
begin
FControlPanel.bSortClick(Self);
end;

procedure TVisualFrame_HTTP.pAddFileClick(Sender: TObject);
begin
FControlPanel.bAddClick(Self);
end;

procedure TVisualFrame_HTTP.UpdateCurrentFolder;
var
  idUser: Integer;
begin

  FDTable.Close;
  FDTable.Open;
idUser := FHTTP_ConnectionParams.IDUser.ToInteger;

 if FIsAllFilesMode then
 FDataBaseUnit.OpenFilesOfUser(idUser) else
 FDataBaseUnit.OpenFolder(FDataBaseUnit.IDCurrentFolder, idUser);


if ( Assigned(FDTable) )

and Assigned( StatusBar.Panels[0] )

 then
StatusBar.Panels[0].Text:='Всего элементов '+FDTable.RecordCount.ToString;


end;

procedure TVisualFrame_HTTP.PageControlChange(Sender: TObject);
begin


  if PageControl.ActivePage=tsLoadFile then
  begin
  CenterButton;
  bUpload.SetFocus;
  end;


  if PageControl.ActivePage=tsMediaLibrary then
  begin
  tsMediaLibrary.Show;
  if FFDConnection.Connected then
    bUpdateClick(Self);

  end;


end;

procedure TVisualFrame_HTTP.bTestClick(Sender: TObject);



begin
//

if OpenDialog.Execute then

 begin


  FSendFileInChunks2.SendFileInChunks(

   OpenDialog.FileName,
   4*1024*1024

  );


 end;



end;



procedure TVisualFrame_HTTP.bUpClick(Sender: TObject);
var

  idUser: integer;
  IDOfRootFolderOfUser: Integer;
  idParent_of_IDOfRootFolderOfUser:integer;

begin

if FIsAllFilesMode then exit;



// looking for top id higher of which we cannot go up
IDOfRootFolderOfUser:=FDataBaseUnit.IDOfRootFolderOfUser;

// idParent of IDOfRootFolderOfUser
with DataBaseUnit.qSelectParentOfParent do begin

Params.ParamValues['id']:=IDOfRootFolderOfUser;

Open();
idParent_of_IDOfRootFolderOfUser:=FieldByName('idParent').AsInteger;
Close();

{
// Status bar
if ( Assigned(FDTable) )
and Assigned( StatusBar.Panels[0] )

 then
StatusBar.Panels[0].Text:='Всего элементов '+FDTable.RecordCount.ToString;
}

end;



//idCurrentParent:=DBGrid.DataSource.DataSet.
//FieldByName('idParent').AsInteger;

idUser:=FHTTP_ConnectionParams.IDUser.ToInteger;

with DataBaseUnit.qSelectParentOfParent do begin

Params.ParamValues['id']:=FidCurrentParent;//idCurrentParent;

Open();
FidCurrentParent:=FieldByName('idParent').AsInteger;
Close();
end;


if FidCurrentParent=idParent_of_IDOfRootFolderOfUser then

begin

//ShowMessage('AСHTUNG');

Exit;
end;



FDataBaseUnit.OpenFolder(FidCurrentParent,idUser);

 //adding adress

  if FAdresses.Count>1 then

   begin



    eAdress.Text:=FAdresses[FAdresses.Count-2];
    FAdresses.Delete(FAdresses.Count-1);

   end;



end;


procedure TVisualFrame_HTTP.bUpdateClick(Sender: TObject);


begin
  UpdateCurrentFolder;


end;


procedure TVisualFrame_HTTP.bUploadClick(Sender: TObject);
var SendFileInChunksThread:TSendFileInChunksThread;


    AllowedExtensionsSL:TStringList;
    ForbiddenExtensionsSL:TStringList;
    i:integer;

begin

FSendManyFilesInChunks_UnitVar.IsKeep2Share:=false;
FSendManyFilesInChunks_UnitVar.VisualMode:=true;

if OpenDialog.Execute then
 begin

   AllowedExtensionsSL:=TStringList.Create;
   ForbiddenExtensionsSL:=TStringList.Create;

   try

   //Dividing on allowed and not allowed files
   for i := 0 to OpenDialog.Files.Count-1 do
     begin

      if FFileType.IsForbiddenExtensions(OpenDialog.Files[i]) then
      ForbiddenExtensionsSL.Add(OpenDialog.Files[i]) else
      AllowedExtensionsSL.Add(OpenDialog.Files[i]);

     end;


           if ForbiddenExtensionsSL.Count>0 then begin

            case
              Application.MessageBox('Файлы с разрешениями EXE и PHP не могут быть загружены.'
              + #13#10 + 'Продолжить загрузку остальных файлов?', 'Сообщение системы',
              MB_YESNO + MB_ICONQUESTION) of
              IDYES:
                begin

                 FSendManyFilesInChunks_UnitVar.
                 SendFilesOnServer(AllowedExtensionsSL);




                end;
              IDNO:
                begin

                exit;

                end;
            end;


           end else

                begin

                 if FSendManyFilesInChunks_UnitVar.IsSomeThreadsNotFinished then

                 begin
                   ShowMessage('Дождитесь окончания текущих загрузок и попробуйте снова');
                   Exit;
                 end else

                 begin

                   if Assigned(FSendManyFilesInChunks_UnitVar) then                   
                   FreeAndNil(FSendManyFilesInChunks_UnitVar);

                   FSendManyFilesInChunks_UnitVar:=TSendManyFilesInChunks.Create(Self);
                   FSendManyFilesInChunks_UnitVar.VisualMode:=true;
                   FSendManyFilesInChunks_UnitVar.SendFileInChunks:=FSendFileInChunks;
                   FSendManyFilesInChunks_UnitVar.SendFileInChunks2:=FSendFileInChunks2;

                   FSendManyFilesInChunks_UnitVar.
                 SendFilesOnServer(AllowedExtensionsSL);

                 end;



                end;


   finally

    //Freeing
   AllowedExtensionsSL.Free;
   ForbiddenExtensionsSL.Free;

   end;



 end;




end;

procedure TVisualFrame_HTTP.CenterButton;
begin

 bUpload.Left:=trunc(Self.width/2-bUpload.width/2);
 bUpload.Top:=trunc(Self.Height/2-bUpload.height/2);

end;

constructor TVisualFrame_HTTP.Create(AOwner: TComponent);
begin
  inherited;

FSomeNumberForTest:=1;

//DataBaseUnit
FDataBaseUnit:=TDataBaseUnit.Create(Self);
DataSource.DataSet:=FDTable;



// idHTTP
IdHTTP.ConnectTimeout:=5*60000; // 5 minutes for big files
IdHTTP.ReadTimeout:=5*60000;  // 5 minutes for big files

FHTTP_ConnectionParams:=THTTP_ConnectionParams.Create(Self);



// Sort
FDBGridSort:=TDBGridSort.Create(Self);

//Search
FSearch:=TSearch.Create(Self);
lSearchResultLabel.Caption:='';
eSearch.Text:='';

FLinksOnKeep2Share:=TStringList.Create;

FSendFileInChunks:=TSendFileInChunks.Create(Self);
FSendFileInChunks2:=TSendFileInChunks2.Create(Self);

FSendManyFilesInChunks_UnitVar:=TSendManyFilesInChunks.Create(Self);
FSendManyFilesInChunks_UnitVar.SendFileInChunks:=FSendFileInChunks;
FSendManyFilesInChunks_UnitVar.SendFileInChunks2:=FSendFileInChunks2;


FHTTPRequests:=THTTPRequests.Create(Self);
FHTTPRequests.SendFileInChunks2:=FSendFileInChunks2;

 FCS:=TCriticalSection.Create;
 FCS2:=TCriticalSection.Create;

CenterButton;

FFilesSL:=TStringList.Create;




//IdHTTP.ReadTimeout:=30000;


// Assigning pictures to buttons on pNavPanelButtons

pNavPanelButtons.ShowCaption:=false;
bHome.Caption:='';
bUp.Caption:='';
bUpdate.Caption:='';

ilControlButtons.GetBitmap(0,bHome.Glyph);
ilControlButtons.GetBitmap(1,bUp.Glyph);
ilControlButtons.GetBitmap(2,bUpdate.Glyph);




//DefaultImage to MediaLibrary
SetDefaultImagetoMediaLibrary;


// ControlPanel with buttons
FControlPanel:=TControlPanel.Create(Self);
FControlPanel.Parent:=ScrollBoxMediaLibrary;



// GetLink DataModule
FGetLinkForm:=TFGetLink.Create(Self);



//FileType DataModule
FFileType:=TFileType.Create(Self);


// FInsertPictureInDocument:TInsertPictureInDocument;
FInsertPictureInDocument:=
TInsertPictureInDocument.Create(Self);


//
FDelete_PS_HTTPClient:=TDelete_PS_HTTPClient.Create(Self);

FIsAllFilesMode:=true;



//Critical Section for download pictures and files

FCSDownloadPicture:=TCriticalSection.Create;

FCSDownloadFile:=TCriticalSection.Create;

//Dispose Control Panel
//DisposeControlPanel;

FAdresses:=TStringList.Create;


FFileProperties:=TFileProperties.Create(Self);


FInsertVideoInDocument:=TInsertVideoInDocument.Create(Self);

end;

//-------------------------------------




procedure TVisualFrame_HTTP.ScrollBoxMediaLibraryResize(Sender: TObject);
begin
DisposeControlPanel;
end;



procedure TVisualFrame_HTTP.imageClick(Sender: TObject);
begin

//DownloadAndSetOnePicture;

 if DataBaseUnit.IsThisPictureByID(
 DBGrid.DataSource.DataSet.FieldByName('id').AsInteger
 ) then

 begin


  FInsertPictureInDocument.Image.Picture.Bitmap.Assign(
    image.Picture.Bitmap
    );

  FInsertPictureInDocument.ShowModal;

 end;

end;

procedure TVisualFrame_HTTP.imageMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin


if not
FileType.
IsFilePicture(DBGrid.DataSource.DataSet.FieldByName('Link').AsString) then
image.ShowHint:=false;


end;

procedure TVisualFrame_HTTP.DisposeControlPanel;
var
  i: Integer;
begin

if Assigned(FControlPanel) then with FControlPanel

 do begin


   Top:=image.Top+image.Height+15;
   Left:=10;
   Width:=ScrollBoxMediaLibrary.ClientWidth-10-20;
//   VerticalAlign;
   AlignCompact2;

   FControlPanel.Show;


   image.Left:=trunc(ScrollBoxMediaLibrary.ClientWidth/2-image.Width/2)-2;
   Bevel.Left:=0;


   image.Width:=pLeftPanelMediaLibrary.Width-10-20;
   Bevel.Width:=ScrollBoxMediaLibrary.ClientWidth;


 //  Bevel.Width:=ScrollBoxMediaLibrary.ClientWidth-10-20;

 end;




end;




procedure TVisualFrame_HTTP.DownloadAndSetOnePicture;
var DownloadPictureThread:TDownloadPictureThread;
begin
//

 DownloadPictureThread:=TDownloadPictureThread.Create(true);
 DownloadPictureThread.FreeOnTerminate:=true;
 DownloadPictureThread.VisualFrame_HTTP:=Self;

 //DownloadPictureThread.Link:=DBGrid.DataSource.DataSet.FieldByName('Link').AsString;
 DownloadPictureThread.Link:=DBGrid.DataSource.DataSet.FieldByName('relPath').AsString;
 DownloadPictureThread.Start;


end;


procedure TVisualFrame_HTTP.DownloadFile;

var DownloadFileThread:TDownloadFileThread;
    SplittedString:TArray<String>;


begin
//

SplittedString:=DBGrid.DataSource.DataSet.FieldByName('relPath').AsString.Split(['/']);
SaveDialog.FileName:=SplittedString[ High(SplittedString) ];


  if SaveDialog.Execute then begin

   DownloadFileThread:=TDownloadFileThread.Create(true);
   DownloadFileThread.FreeOnTerminate:=true;
   DownloadFileThread.VisualFrame_HTTP:=Self;

   //DownloadPictureThread.Link:=DBGrid.DataSource.DataSet.FieldByName('Link').AsString;
   DownloadFileThread.Link:=DBGrid.DataSource.DataSet.FieldByName('relPath').AsString;
   DownloadFileThread.Start;


  end;


end;





procedure TVisualFrame_HTTP.FDTableAfterGetRecord(DataSet: TFDDataSet);
begin
//DownloadAndSetOnePicture;
end;

procedure TVisualFrame_HTTP.FDTableCalcFields(DataSet: TDataSet);
begin

   //https://direct.yandex.ru
 with HTTP_ConnectionParams do begin

 FDTableLink.Value:=

     Protocol+'://'+
     Host+':'+
     Port+FDTablerelPath.Value;

 end;



 // FileSizeCalc from FileSize

 if FDTablefileSize.Value >=0 then begin

      if FDTablefileSize.Value<1024 then FDTableFileSizeCalc.Value:=FDTablefileSize.Value.ToString()+' Bytes';

       if (FDTablefileSize.Value>1024) and (FDTablefileSize.Value<(1024*1024)) then
       FDTableFileSizeCalc.Value:=(Trunc(FDTablefileSize.Value/1024)).ToString()+' KB';

       if (FDTablefileSize.Value>(1024*1024)) {and (FileSize<(1024*1024*1024))} then
       FDTableFileSizeCalc.Value:=(Trunc(FDTablefileSize.Value/(1024*1024))).ToString()+' MB';

  end;



// :='123'

end;


procedure TVisualFrame_HTTP.GiveHumanFileSize(FilSizeBytes:Int64; var HumanFileSize:String);
begin

 // FileSizeCalc from FileSize

 if FilSizeBytes >=0 then begin

      if FilSizeBytes<1024 then HumanFileSize:=FilSizeBytes.ToString()+' Bytes';

       if (FilSizeBytes>1024) and (FilSizeBytes<(1024*1024)) then
       HumanFileSize:=(Trunc(FilSizeBytes/1024)).ToString()+' KB';

       if (FilSizeBytes>(1024*1024)) {and (FileSize<(1024*1024*1024))} then
       HumanFileSize:=(Trunc(FilSizeBytes/(1024*1024))).ToString()+' MB';

  end;




end;

procedure TVisualFrame_HTTP.FDTableForTestCalcFields(DataSet: TDataSet);
begin
//
//FDTableForTestLink2.Value:='1234';
//DataSet.FieldByName('Link').AsString:='1234';

end;

procedure TVisualFrame_HTTP.FrameResize(Sender: TObject);
begin
CenterButton;


image.Left:=trunc(ScrollBoxMediaLibrary.Width/2-image.Width/2);
Bevel.Left:=Trunc(ScrollBoxMediaLibrary.Width/2-bevel.Width/2);

//if Self.Height>Trunc(2/3 *Screen.Height) then


//if (ScrollBoxMediaLibrary.Height-image.Height)>
//Trunc(FControlPanel.MaxHeightCompact*1.05) then

//ShowMessage('ok');
//FControlPanel.VerticalAlign else
FControlPanel.AlignCompact2;



//;


end;




procedure TVisualFrame_HTTP.SetDefaultImagetoMediaLibrary;
begin

ImageList.GetBitmap(0,image.Picture.Bitmap);

end;

procedure TVisualFrame_HTTP.StatusBarClick(Sender: TObject);

var IDList:TStringList;

  i: integer;
  s:string;

begin


 IDList:=TStringList.Create;

if DBGrid.SelectedRows.Count>0 then
with DBGrid.DataSource.DataSet do
for i:=0 to DBGrid.SelectedRows.Count-1 do

begin

GotoBookmark(pointer(DBGrid.SelectedRows.Items[i]));

IDList.Add(

FieldByName('id').AsInteger.ToString()

);



end;


for i := 0 to IDList.Count-1 do
s:=s+IDList[i]+#13#10;


ShowMessage(s);
IDList.Free;

end;


procedure TVisualFrame_HTTP.ZaplatkaTimerTimer(Sender: TObject);
begin


ZaplatkaTimer.Tag:=ZaplatkaTimer.Tag+1;

if ZaplatkaTimer.Tag=1 then
 begin
   ZaplatkaTimer.Enabled:=False;
   DownloadAndSetOnePicture;

//   if Assigned(FDTable.DataSource.DataSet) then

//  StatusBar.Panels[0].Text:='Всего элементов '+'123';
//  FDTable.RecordCount.ToString;  //DataSource.DataSet.RecordCount.ToString;



 end;

end;

procedure TVisualFrame_HTTP.bUploadOnKeep2ShareClick(Sender: TObject);

var FilesSL:TStringList; i:integer;

begin

FSendManyFilesInChunks_UnitVar.IsKeep2Share:=true;
FSendManyFilesInChunks_UnitVar.VisualMode:=false;


if OpenDialog.Execute then
 begin

   FilesSL:=TStringList.Create;
   FilesSL.Assign(OpenDialog.Files);

   for i := 0 to FilesSL.Count-1 do
   FFilesSL.Add(FilesSL[i]);

   FSendManyFilesInChunks_UnitVar.SendFilesOnServer(FilesSL);

   FilesSL.Free;

 end;




end;

procedure TVisualFrame_HTTP.cbAllFilesOrByDateSelect(Sender: TObject);
begin

case cbAllFilesOrByDate.ItemIndex of

 0: begin
   FIsAllFilesMode:=True; InitialUpdate;
   DownloadAndSetOnePicture;

   eAdress.Text:=
   DBGrid.DataSource.DataSet.
   FieldByName('Link').AsString;

 end;

  1: begin
   FIsAllFilesMode:=False; InitialUpdate;
   DownloadAndSetOnePicture;
 end;


end;

end;

procedure TVisualFrame_HTTP.cbFileTypesSelect(Sender: TObject);
begin

case cbFileTypes.ItemIndex of

 0: UpdateCurrentFolder;


 1: FDataBaseUnit.SelectByFileType('Picture');


 2: FDataBaseUnit.SelectByFileType('Video');


 3: FDataBaseUnit.SelectByFileType('Audio');





end;


// Status Bar
 if ( Assigned(FDTable) )
and Assigned( StatusBar.Panels[0] )

 then
StatusBar.Panels[0].Text:='Всего элементов '+FDTable.RecordCount.ToString;


end;

procedure TVisualFrame_HTTP.cbTableOrGallerySelect(Sender: TObject);
begin

case cbTableOrGallery.ItemIndex of

  1: begin

   ShowMessage('Gallery Mode Will be Done In Next Version');
   cbTableOrGallery.ItemIndex:=0;
   Exit();

  end;

end;

end;

//-----------------------------------------------


procedure TVisualFrame_HTTP.DBGridCellClick(Column: TColumn);
var
  Link:string;
  idParentNew: Integer;

begin

Link:=DBGrid.DataSource.DataSet.
FieldByName('Link').AsString;

DownloadAndSetOnePicture;

if IsAllFilesMode then

eAdress.Text:=
DBGrid.DataSource.DataSet.FieldByName('Link').AsString

//idUser:=FHTTP_ConnectionParams.IDUser.ToInteger;
//FDataBaseUnit.OpenFolder(idParentNew,idUser);

end;

procedure TVisualFrame_HTTP.DBGridDblClick(Sender: TObject);
var
  idParentNew: Integer;
  idUser: integer;
  FilePropertiesLocal: TFileProperties;
begin

// if DBGrid is Empty
if (DBGrid.DataSource.DataSet.RecordCount=0) then Exit;


idParentNew:=DBGrid.DataSource.DataSet.FieldByName('id').AsInteger;
FidCurrentParent:=idParentNew;




if (not FIsAllFilesMode)

and (DBGrid.DataSource.DataSet.RecordCount>0)

and DataBaseUnit.IsFolder(idParentNew)

then


begin

 //adding adress

  if FAdresses.Count>0 then

   begin

    FAdresses.Add(

      FAdresses[ FAdresses.Count-1]+
      DBGrid.DataSource.DataSet.FieldByName('Name').AsString
      +'/'

    );

    eAdress.Text:=FAdresses[FAdresses.Count-1];



   end;




end;






idUser:=FHTTP_ConnectionParams.IDUser.ToInteger;
FDataBaseUnit.OpenFolder(idParentNew,idUser);
DownloadAndSetOnePicture;


// Handling double click on file

if not FDataBaseUnit.IsFolder(idParentNew)

//and (FDataBaseUnit.IsThisPictureByID(idParentNew))

then

 begin

  //FFileProperties.Image:=nil;

  FilePropertiesLocal:=TFileProperties.Create(Self);

  FilePropertiesLocal.Image.Picture.Bitmap.Assign(

     image.Picture.Bitmap

  );


  if (FilePropertiesLocal.Image.Picture.Bitmap.Width<100) or
  (FilePropertiesLocal.Image.Picture.Bitmap.Height<100) then
  FilePropertiesLocal.Image.Stretch:=False else
  FilePropertiesLocal.Image.Stretch:=true;



  FilePropertiesLocal.ShowModal;

  if FilePropertiesLocal.ModalResult=mrOk then

  begin

            FilePropertiesLocal.Free;


            if FFileType.IsFilePicture(

             DBGrid.DataSource.DataSet.FieldByName('Link').AsString

            ) then

               begin

                   FInsertPictureInDocument.Image.Picture.Bitmap.Assign(
                image.Picture.Bitmap
                );

               FInsertPictureInDocument.ShowModal;



               end;





                      if FFileType.IsFileVideo(

                     DBGrid.DataSource.DataSet.FieldByName('Link').AsString

                    ) then

                       begin

                           FInsertVideoInDocument.Image.Picture.Bitmap.Assign(
                        image.Picture.Bitmap
                        );

                       FInsertVideoInDocument.ShowModal;



                       end;



    // FilePropertiesLocal.ModalResult=mrOk
          end;






       end;












  end;



















procedure TVisualFrame_HTTP.DBGridDrawColumnCell(Sender: TObject; const [Ref] Rect: TRect; DataCol: Integer;
  Column: TColumn; State: TGridDrawState);
begin

// Drawing files and folders icons in DBGrid
DrawFoldersAndFilesIcons(Column,Sender,Rect);

end;


procedure TVisualFrame_HTTP.DrawFoldersAndFilesIcons(Column: TColumn;Sender: TObject;Rect:TRect);

var X:integer; ImageIndex:integer;

begin


  X:=Rect.Left;
//  X:=Trunc((Rect.Left+Rect.Width)/2);
//  Y:=Trunc((Rect.Top+Rect.Height)/2);

 //Рисуем иконку в самой левой иконке

 if Column.Index=2 then
 begin

 if DBGrid.DataSource.DataSet.FieldByName('IsFolder').AsBoolean then
  begin
   ImageIndex:=0;
   ilFoldersAndFiles16.Draw(TDBGrid(Sender).Canvas,X,Rect.Top, ImageIndex );

  end else
  begin

   ImageIndex:=1;
  ilFoldersAndFiles16.Draw(TDBGrid(Sender).Canvas,X,Rect.Top, ImageIndex );

  end;



 end;





end;


procedure TVisualFrame_HTTP.DBGridKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin

//

end;

procedure TVisualFrame_HTTP.DBGridKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin

if Key=40 then
begin
DownloadAndSetOnePicture;

if IsAllFilesMode then
eAdress.Text:=
DBGrid.DataSource.DataSet.FieldByName('Link').AsString

end;


if Key=38 then
begin
DownloadAndSetOnePicture;

if IsAllFilesMode then
eAdress.Text:=
DBGrid.DataSource.DataSet.FieldByName('Link').AsString

end;



// ShowMessage(Key.ToString());

end;

procedure TVisualFrame_HTTP.DBGridTitleClick(Column: TColumn);
begin


FDBGridSort.DBGridSortColumns(Column.FieldName);


end;

procedure TVisualFrame_HTTP.DefineServerToRequest;
begin
  // Defining Server To Request
  with FHTTP_ConnectionParams do
  begin
    FHTTPServerToRequest := Protocol + '://' + Host + ':' + Port;
  end;
  //for example like http://localhost:40000
end;

destructor TVisualFrame_HTTP.Destroy;
begin
//FreeAndNil(FHTTP_ConnectionParams); // will be deleted automatically

FreeAndNil(FCS);
FreeAndNil(FCS2);
FreeAndNil(FLinksOnKeep2Share);
FreeAndNil(FFilesSL);

FreeAndNil(FCSDownloadPicture);
FreeAndNil(FCSDownloadFile);

FreeAndNil(FAdresses);



  inherited;
end;




//-------------------------------------

end.
