unit uSendFileInChunksThread;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,Contnrs,SyncObjs,System.IOUtils,

  //myUnits
  uVisualFrame,uUploadFrame,uSendFileInChunks,uSendFileInChunks2

  ;

type
  TSendFileInChunksThread = class(TThread)
  private
    { Private declarations }


    FFilePath:string;    // wrapped in critical section
    FMaxCountBytes:Int64;

    FGuidString:string;

    FUploadFrame:TUploadFrame;

    FUploadFrameOL:TObjectList;
    FUploadThreadsOL:TObjectList;

    FVisualFrame:TVisualFrame_HTTP;

    FSendFileInChunks:TSendFileInChunks;

    FSendFileInChunks2:TSendFileInChunks2;


    FIsKeep2Share:boolean;

    FProgressPercentString:string;
    FStatus:String;



    fEx : Exception;
    procedure QueryError;

    procedure OnUploadInChunksBegin(Sender: TObject; ACountBytes:Int64);
    procedure OnDivideInChunksOnClient(Sender: TObject; ACountBytes:Int64);
    procedure OnSendingChunksInfo(Sender: TObject; ACountBytes:Int64);
    procedure OnSendingChunksToServer(Sender: TObject; ACountBytes:Int64);


    procedure OnUploadInChunks(Sender: TObject; ACountBytes:Int64);
    procedure OnGatherChunksOnServer(Sender: TObject; ACountBytes:Int64);
    procedure OnUploadInChunksEnd(Sender: TObject; ACountBytes:Int64);



    function  GetFilePath:string;
    procedure SetFilePath(AValue:string);

    function  GetVisualFrame:TVisualFrame_HTTP;
    procedure SetVisualFrame(AValue:TVisualFrame_HTTP);


    function  GetGUIDString:string;
    procedure SetGUIDString(AValue:string);

    function  GetUploadFrameOL:TObjectList;
    procedure SetUploadFrameOL(AValue:TObjectList);

    function  GetUploadThreadOL:TObjectList;
    procedure SetUploadThreadOL(AValue:TObjectList);

  public


  property IsKeep2Share:boolean read FIsKeep2Share write FIsKeep2Share;


  property FilePath:string read GetFilePath write SetFilePath; // wrapped in critical section
  property VisualFrame:TVisualFrame_HTTP read GetVisualFrame write SetVisualFrame; // wrapped in critical section
  property Guidstring:string read GetGUIDString write SetGUIDString; // wrapped in critical section

  property UploadFrameOL:TObjectList read GetUploadFrameOL write SetUploadFrameOL;
  property UploadThreadOL:TObjectList read GetUploadThreadOL write SetUploadThreadOL;

  property SendFileInChunks:TSendFileInChunks read FSendFileInChunks write FSendFileInChunks;
  property SendFileInChunks2:TSendFileInChunks2 read FSendFileInChunks2 write FSendFileInChunks2;


 // property UploadFrame:TUploadFrame  read GetUploadFrame write SetUploadFrame;

  property UploadFrame:TUploadFrame  read FUploadFrame write FUploadFrame;

  //FUploadFrame

  protected

    procedure Execute; override;


  end;

implementation

//uses  ;


{
  Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,

      Synchronize(UpdateCaption);

  and UpdateCaption could look like,

    procedure TSendFileInChunksThread.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end;

    or

    Synchronize(
      procedure
      begin
        Form1.Caption := 'Updated in thread via an anonymous method'
      end
      )
    );

  where an anonymous method is passed.

  Similarly, the developer can call the Queue method with similar parameters as
  above, instead passing another TThread class as the first parameter, putting
  the calling thread in a queue with the other thread.

}

{ TSendFileInChunksThread }

procedure TSendFileInChunksThread.Execute;


var   ChunkSize:Int64;
//      SendFileInChunks: TSendFileInChunks;


begin
  { Place thread code here }


   //  SendFileInChunks:=TSendFileInChunks.Create(FVisualFrame);
  //   SendFileInChunks.CS:=FVisualFrame.CS; // giving link to critical section



   try

         FVisualFrame.CS2.Enter;
         try

         //Firing Event
         if Assigned(FVisualFrame.OnKeep2ShareStartUpload) and (FIsKeep2Share) then
         FVisualFrame.OnKeep2ShareStartUpload(Self);


         //if Assigned(SendFileInChunks) then

          begin
          {
           SendFileInChunks.OnUploadInChunksBegin:=OnUploadInChunksBegin;
           SendFileInChunks.OnUploadInChunks:=OnUploadInChunks;
           SendFileInChunks.OnUploadInChunksEnd:=OnUploadInChunksEnd;

       //    SendFileInChunks.SomeThread:=Self;

           ChunkSize:=4*1024*1024; // 1mb
           SendFileInChunks.IsKeep2Share:=FIsKeep2Share;
           SendFileInChunks.SendFileInChunks(FilePath,ChunkSize);
          }
          end;
         // }

          if Assigned(SendFileInChunks2) then

          begin

           SendFileInChunks2.OnUploadInChunksBegin:=OnUploadInChunksBegin;

           SendFileInChunks2.OnDivideInChunksOnClient:=OnDivideInChunksOnClient;
           SendFileInChunks2.OnSendingChunksInfo:=OnSendingChunksInfo;
           SendFileInChunks2.OnSendingChunksToServer:=OnSendingChunksToServer;


           SendFileInChunks2.OnUploadInChunks:=OnUploadInChunks;
           SendFileInChunks2.OnGatherChunksOnServer:=OnGatherChunksOnServer;


           SendFileInChunks2.OnUploadInChunksEnd:=OnUploadInChunksEnd;

       //    SendFileInChunks.SomeThread:=Self;

           ChunkSize:=4*1024*1024; // 4mb
           SendFileInChunks2.SendFileInChunks(FilePath,ChunkSize);

          end;





         if Assigned(FVisualFrame.OnKeep2ShareEndUpload) and (FIsKeep2Share) then

          begin

          FVisualFrame.LinksOnKeep2Share.Add(

            //SendFileInChunks.LinkKeep2Share

            FFilePath+'='+SendFileInChunks.LinkKeep2Share

           );

          // Firing event here
          FVisualFrame.OnKeep2ShareEndUpload(Self);

          end;




         finally

         FVisualFrame.CS2.Leave;
         //FreeAndNil(SendFileInChunks);


         end;



   except

   fEx := ExceptObject as Exception;
   Synchronize( QueryError );

   end;





end;



procedure TSendFileInChunksThread.OnDivideInChunksOnClient(Sender: TObject; ACountBytes: Int64);
begin
if Assigned(FUploadFrameOL) then
  begin

 //   TFile.AppendAllText('SomeFile.txt','ACountBytes '+ACountBytes.ToString());

         Synchronize(
      procedure

    var
      I: Integer;
   begin
                if FMaxCountBytes<>0 then

              begin
                                    {

                     FUploadFrame.ProgressBar.Position:=
                                        Trunc( (ACountBytes/FMaxCountBytes)*100 );

                                        FUploadFrame.Edit.Text:=
                                       ( Trunc ( (ACountBytes/FMaxCountBytes)*100 ) ).ToString;

                                      }


                    for I := 0 to FUploadFrameOL.Count-1  do

                     begin

                     if Assigned(TUploadFrame(FUploadFrameOL[i])) then

                     begin


                     if TUploadFrame(FUploadFrameOL[i]).GuidString=
                        Self.FGuidString then
                                       begin



                                        //TUploadFrame(FUploadFrameOL[i]).lStatus.Caption:='Dividing in chunks'

                                        //FProgressPercentString:=( Trunc ( (ACountBytes/FMaxCountBytes)*100 ) ).ToString+' %';
                                       FStatus:='Dividing in chunks ';

                                       TUploadFrame(FUploadFrameOL[i]).Edit.Text:=FStatus+FProgressPercentString


                                       // FUploadFrame.Repaint;


                                       end;


                     end;

                     end;





              end;


      end
      )


  end;


end;

procedure TSendFileInChunksThread.OnGatherChunksOnServer(Sender: TObject; ACountBytes: Int64);
begin
if Assigned(FUploadFrameOL) then
  begin

 //   TFile.AppendAllText('SomeFile.txt','ACountBytes '+ACountBytes.ToString());

         Synchronize(
      procedure

    var
      I: Integer;
   begin
                if FMaxCountBytes<>0 then

              begin
                                    {

                     FUploadFrame.ProgressBar.Position:=
                                        Trunc( (ACountBytes/FMaxCountBytes)*100 );

                                        FUploadFrame.Edit.Text:=
                                       ( Trunc ( (ACountBytes/FMaxCountBytes)*100 ) ).ToString;

                                      }


                    for I := 0 to FUploadFrameOL.Count-1  do

                     begin

                     if Assigned(TUploadFrame(FUploadFrameOL[i])) then

                     begin


                     if TUploadFrame(FUploadFrameOL[i]).GuidString=
                        Self.FGuidString then
                                       begin




                                       //TUploadFrame(FUploadFrameOL[i]).lStatus.Caption:='Gather chunks on Server'

                                       // FUploadFrame.Repaint;

                                       //FProgressPercentString:=( Trunc ( (ACountBytes/FMaxCountBytes)*100 ) ).ToString+' %';
                                       FStatus:='Gathering chunks on Server ';

                                       TUploadFrame(FUploadFrameOL[i]).Edit.Text:=FStatus+FProgressPercentString




                                       end;


                     end;

                     end;





              end;


      end
      )


  end;


end;

procedure TSendFileInChunksThread.OnSendingChunksInfo(Sender: TObject; ACountBytes: Int64);
begin
//
if Assigned(FUploadFrameOL) then
  begin

 //   TFile.AppendAllText('SomeFile.txt','ACountBytes '+ACountBytes.ToString());

         Synchronize(
      procedure

    var
      I: Integer;
   begin
                if FMaxCountBytes<>0 then

              begin
                                    {

                     FUploadFrame.ProgressBar.Position:=
                                        Trunc( (ACountBytes/FMaxCountBytes)*100 );

                                        FUploadFrame.Edit.Text:=
                                       ( Trunc ( (ACountBytes/FMaxCountBytes)*100 ) ).ToString;

                                      }


                    for I := 0 to FUploadFrameOL.Count-1  do

                     begin

                     if Assigned(TUploadFrame(FUploadFrameOL[i])) then

                     begin


                     if TUploadFrame(FUploadFrameOL[i]).GuidString=
                        Self.FGuidString then
                                       begin




//                                       TUploadFrame(FUploadFrameOL[i]).lStatus.Caption:='Sending chunks info'

                                       //FProgressPercentString:=( Trunc ( (ACountBytes/FMaxCountBytes)*100 ) ).ToString+' %';
                                       FStatus:='Sending chunks info ';

                                       TUploadFrame(FUploadFrameOL[i]).Edit.Text:=FStatus+FProgressPercentString


                                       // FUploadFrame.Repaint;


                                       end;


                     end;

                     end;





              end;


      end
      )


  end;



end;

procedure TSendFileInChunksThread.OnSendingChunksToServer(Sender: TObject; ACountBytes: Int64);
begin
if Assigned(FUploadFrameOL) then
  begin

 //   TFile.AppendAllText('SomeFile.txt','ACountBytes '+ACountBytes.ToString());

         Synchronize(
      procedure

    var
      I: Integer;
   begin
                if FMaxCountBytes<>0 then

              begin
                                    {

                     FUploadFrame.ProgressBar.Position:=
                                        Trunc( (ACountBytes/FMaxCountBytes)*100 );

                                        FUploadFrame.Edit.Text:=
                                       ( Trunc ( (ACountBytes/FMaxCountBytes)*100 ) ).ToString;

                                      }


                    for I := 0 to FUploadFrameOL.Count-1  do

                     begin

                     if Assigned(TUploadFrame(FUploadFrameOL[i])) then

                     begin


                     if TUploadFrame(FUploadFrameOL[i]).GuidString=
                        Self.FGuidString then
                                       begin

                                       //TUploadFrame(FUploadFrameOL[i]).lStatus.Caption:='Sending Chunks To Server...'

                                       //FProgressPercentString:=( Trunc ( (ACountBytes/FMaxCountBytes)*100 ) ).ToString+' %';
                                       FStatus:='Sending chunks to Server ';

                                       TUploadFrame(FUploadFrameOL[i]).Edit.Text:=FStatus+FProgressPercentString



                                       end;


                     end;

                     end;





              end;


      end
      )


  end;

end;

procedure TSendFileInChunksThread.OnUploadInChunks(Sender: TObject; ACountBytes: Int64);


begin


if Assigned(FUploadFrameOL) then
  begin

 //   TFile.AppendAllText('SomeFile.txt','ACountBytes '+ACountBytes.ToString());

         Synchronize(
      procedure

    var
      I: Integer;
   begin
                if FMaxCountBytes<>0 then

              begin
                                    {

                     FUploadFrame.ProgressBar.Position:=
                                        Trunc( (ACountBytes/FMaxCountBytes)*100 );

                                        FUploadFrame.Edit.Text:=
                                       ( Trunc ( (ACountBytes/FMaxCountBytes)*100 ) ).ToString;

                                      }


                    for I := 0 to FUploadFrameOL.Count-1  do

                     begin

                     if Assigned(TUploadFrame(FUploadFrameOL[i])) then

                     begin


                     if TUploadFrame(FUploadFrameOL[i]).GuidString=
                        Self.FGuidString then
                                       begin


                                        TUploadFrame(FUploadFrameOL[i]).ProgressBar.Position:=
                                        Trunc( (ACountBytes/FMaxCountBytes)*100 );

                                        TUploadFrame(FUploadFrameOL[i]).Edit.Text:=
                                       ( Trunc ( (ACountBytes/FMaxCountBytes)*100 ) ).ToString+' %';

                                       //TUploadFrame(FUploadFrameOL[i]).lStatus.Caption:='Uploading...'

                                       // FUploadFrame.Repaint;


                                       FProgressPercentString:=( Trunc ( (ACountBytes/FMaxCountBytes)*100 ) ).ToString+' %';
                                       FStatus:='Uploading ';

                                       TUploadFrame(FUploadFrameOL[i]).Edit.Text:=FStatus+FProgressPercentString


                                       end;


                     end;

                     end;





              end;


      end
      )


  end;


end;


procedure TSendFileInChunksThread.OnUploadInChunksBegin(Sender: TObject; ACountBytes: Int64);



begin



if Assigned(FUploadFrameOL) then
  begin



          Synchronize(
      procedure

    var  I: Integer;

   begin

      //   FMaxCountBytes:=ACountBytes;
      //   FUploadFrame.ProgressBar.Max:=100;


        for I := 0 to FUploadFrameOL.Count-1  do

         begin

         if Assigned(TUploadFrame(FUploadFrameOL[i])) then
         begin



             if TUploadFrame(FUploadFrameOL[i]).GuidString=
                Self.FGuidString then

                               begin

                                FMaxCountBytes:=ACountBytes;
                                TUploadFrame(FUploadFrameOL[i]).ProgressBar.Max:=100; // norm on 100

                                    FProgressPercentString:='0 %';
                                    FStatus:='Begin uploading ';

                                    TUploadFrame(FUploadFrameOL[i]).Edit.Text:=FStatus+FProgressPercentString;

                               end;
             end;


         end;







      end
      )




  end;


end;

procedure TSendFileInChunksThread.OnUploadInChunksEnd(Sender: TObject; ACountBytes: Int64);
begin

//
  if Assigned(FVisualFrame) then begin



   Synchronize(
   procedure
   begin
   FVisualFrame.UpdateCurrentFolder;
   FVisualFrame.DataBaseUnit.SortByCreationDate;
   FVisualFrame.DownloadAndSetOnePicture;
   end

   );





  end;



if Assigned(FUploadFrameOL) then
  begin



          Synchronize(
      procedure

    var  I: Integer;

   begin

      //   FMaxCountBytes:=ACountBytes;
      //   FUploadFrame.ProgressBar.Max:=100;


        for I := 0 to FUploadFrameOL.Count-1  do

         begin

         if Assigned(TUploadFrame(FUploadFrameOL[i])) then
         begin



             if TUploadFrame(FUploadFrameOL[i]).GuidString=
                Self.FGuidString then

                               begin

                                FMaxCountBytes:=ACountBytes;
                                TUploadFrame(FUploadFrameOL[i]).ProgressBar.Max:=100; // norm on 100

                                FMaxCountBytes:=ACountBytes;

                                    FProgressPercentString:='100 %';
                                    FStatus:='Ready ';

                                    TUploadFrame(FUploadFrameOL[i]).Edit.Text:=FStatus+FProgressPercentString;
                                    //' Open medialibrary now';





                                //TUploadFrame(FUploadFrameOL[i]).lStatus.Caption:='Ready';

                               end;
             end;


         end;







      end
      )




  end;







end;

procedure TSendFileInChunksThread.QueryError;
begin
Application.OnException( Self, fEx );
end;



function TSendFileInChunksThread.GetFilePath: string;
begin
// Result:=FFilePath;

 FVisualFrame.CS.Enter;
 try
 Result:=FFilePath;
 finally
 FVisualFrame.CS.Leave;
 end;

end;

function TSendFileInChunksThread.GetGUIDString: string;
begin
// Result:=FGuidString;

 FVisualFrame.CS.Enter;
 try
 Result:=FGuidString;
 finally
 FVisualFrame.CS.Leave;
 end;


end;




function TSendFileInChunksThread.GetUploadFrameOL: TObjectList;
begin
//
 FVisualFrame.CS.Enter;
 try
 Result:=FUploadFrameOL;

 finally
 FVisualFrame.CS.Leave;
 end;

end;

function TSendFileInChunksThread.GetUploadThreadOL: TObjectList;
begin

 FVisualFrame.CS.Enter;

 try
 Result:=FUploadThreadsOL;

 finally
 FVisualFrame.CS.Leave;
 end;


end;

function TSendFileInChunksThread.GetVisualFrame: TVisualFrame_HTTP;
begin
// Result:=FVisualFrame;

 FVisualFrame.CS.Enter;
 try
 Result:=FVisualFrame;

 finally
 FVisualFrame.CS.Leave;
 end;

end;




procedure TSendFileInChunksThread.SetFilePath(AValue: string);
begin
// FFilePath:=AValue;

 FVisualFrame.CS.Enter;
 try
 FFilePath:=AValue;

 finally
 FVisualFrame.CS.Leave;
 end;


end;

procedure TSendFileInChunksThread.SetGUIDString(AValue: string);
begin

// FGuidString:=AValue;

 FVisualFrame.CS.Enter;
 try
 FGuidString:=AValue;

 finally
 FVisualFrame.CS.Leave;
 end;


end;




procedure TSendFileInChunksThread.SetUploadFrameOL(AValue: TObjectList);
begin

 FVisualFrame.CS.Enter;
 try
 FUploadFrameOL:=AValue;

 finally
 FVisualFrame.CS.Leave;
 end;



end;

procedure TSendFileInChunksThread.SetUploadThreadOL(AValue: TObjectList);
begin



 FVisualFrame.CS.Enter;
 try
 FUploadThreadsOL:=AValue;

 finally
 FVisualFrame.CS.Leave;
 end;



end;

procedure TSendFileInChunksThread.SetVisualFrame(AValue: TVisualFrame_HTTP);
begin

 FVisualFrame:=AValue; // because it contains CS

{
 FVisualFrame.CS.Enter;
 try
 FVisualFrame:=AValue;

 finally
 FVisualFrame.CS.Leave;
 end;

}
end;



end.
