-- Copyright (c) 2019-2022 Bartek thindil Jasicki <thindil@laeran.pl>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.

with Ada.Directories;
with Interfaces.C;
with GNAT.OS_Lib;
with CArgv;
with Tcl.MsgCat.Ada; use Tcl.MsgCat.Ada;
with Tcl.Tk.Ada;
with Tcl.Tk.Ada.Widgets.Toplevel.MainWindow;
with Common; use Common;
with LoadData;
with LoadData.UI;
with MainWindow;
with Messages.UI; use Messages.UI;
with Preferences;
with RefreshData;
with ShowItems; use ShowItems;
with Utils;
with Utils.UI; use Utils.UI;

package body CopyItems.UI is

   --## rule off GLOBAL_REFERENCES
   -- ****iv* CopyItemsUI/CopyItemsUI.Source_Directory
   -- FUNCTION
   -- Full path to the source directory of copied files and directories
   -- SOURCE
   Source_Directory: Unbounded_String;
   -- ****
   --## rule on GLOBAL_REFERENCES

   -- ****o* CopyItemsUI/CopyItemsUI.Copy_Data_Command
   -- FUNCTION
   -- Enter or quit copying items mode
   -- PARAMETERS
   -- Client_Data - Custom data send to the command. Unused
   -- Interp     - Tcl interpreter in which command was executed.
   -- Argc       - Number of arguments passed to the command. Unused
   -- Argv       - Values of arguments passed to the command. Unused
   -- RESULT
   -- This function always return TCL_OK
   -- COMMANDS
   -- CopyData
   -- SOURCE
   function Copy_Data_Command
     (Client_Data: Integer; Interp: Tcl.Tcl_Interp; Argc: Interfaces.C.int;
      Argv: CArgv.Chars_Ptr_Ptr) return Interfaces.C.int with
      Convention => C;
      -- ****

   function Copy_Data_Command
     (Client_Data: Integer; Interp: Tcl.Tcl_Interp; Argc: Interfaces.C.int;
      Argv: CArgv.Chars_Ptr_Ptr) return Interfaces.C.int is
      pragma Unreferenced(Client_Data, Argc, Argv);
      use Ada.Directories;
      use GNAT.OS_Lib;
      use Tcl.Tk.Ada.Widgets.Toplevel.MainWindow;

      Overwrite_Item: Boolean := False;
   begin
      if Copy_Items_List.Length > 0
        and then
          Containing_Directory
            (Name => To_String(Source => Copy_Items_List(1))) =
          To_String(Source => Destination_Directory) then
         Copy_Items_List.Clear;
         Show_Preview;
         Toggle_Tool_Buttons(Action => New_Action, Finished => True);
         return TCL_OK;
      end if;
      if Copy_Items_List.Length = 0 then
         Copy_Items_List := Selected_Items;
         Source_Directory := Common.Current_Directory;
         New_Action := COPY;
         Toggle_Tool_Buttons(Action => New_Action);
         Show_Destination;
         Bind_To_Main_Window
           (Interp => Interp, Sequence => "<Escape>",
            Script =>
              "{.mainframe.toolbars.actiontoolbar.cancelbutton invoke}");
         return TCL_OK;
      end if;
      if not Is_Write_Accessible_File
          (Name => To_String(Source => Common.Current_Directory)) then
         Show_Message
           (Message =>
              Mc
                (Interp => Interp,
                 Src_String =>
                   "{You don't have permissions to copy selected items here.}"));
         return TCL_OK;
      end if;
      New_Action := COPY;
      Update_Progress_Bar(Amount => Positive(Copy_Items_List.Length));
      Copy_Selected(Overwrite => Overwrite_Item);
      return TCL_OK;
   end Copy_Data_Command;

   procedure Copy_Selected(Overwrite: in out Boolean) is
      use Tcl.Tk.Ada;
      use LoadData.UI;
      use MainWindow;
      use Preferences;
      use RefreshData;

   begin
      if not Copy_Items
          (Interpreter => Get_Context, Overwrite => Overwrite) then
         return;
      end if;
      if Settings.Show_Finished_Info then
         Show_Message
           (Message =>
              Mc
                (Interp => Get_Context,
                 Src_String =>
                   "{All selected files and directories have been copied.}"),
            Message_Type => "message");
      end if;
      Common.Current_Directory :=
        (if Settings.Stay_In_Old then Source_Directory
         else Destination_Directory);
      Load_Directory
        (Directory_Name => To_String(Source => Common.Current_Directory));
      New_Action := CREATEFILE;
      Update_Directory_List(Clear => True);
      Update_Watch(Path => To_String(Source => Common.Current_Directory));
      Show_Preview;
      Toggle_Tool_Buttons(Action => New_Action, Finished => True);
   end Copy_Selected;

   procedure Skip_Copying is
      Overwrite_Item: Boolean := False;
   begin
      Copy_Items_List.Delete(Index => 1);
      Update_Progress_Bar;
      Copy_Selected(Overwrite => Overwrite_Item);
   end Skip_Copying;

   procedure Create_Copy_Ui is
      use Utils;

   begin
      Add_Command(Name => "CopyData", Ada_Command => Copy_Data_Command'Access);
   end Create_Copy_Ui;

end CopyItems.UI;
