module opt_delete
    
    use parameters
    use subroutines
    use elements
    use neighbors

    implicit none 

    real(kind=dp) :: rc_off
    logical :: first

    public  
    contains

    subroutine run_delete(arg_pos)  

        integer, intent(inout) :: arg_pos

        rc_off = -lim_zero
        !Main calling function for delete option.
        print *, '-----------------------Option Delete------------------------'

        call parse_delete(arg_pos)

        if (rc_off > 0.0_dp) call delete_overlap
    end subroutine run_delete

    subroutine parse_delete(arg_pos)
        !Parse the delete command

        integer, intent(inout) :: arg_pos

        integer :: arg_len 
        character(len=100) :: textholder
        arg_pos = arg_pos + 1

        first = .true.
        call get_command_argument(arg_pos, textholder, arg_len)
        if(arg_len==0) stop "Missing argument to delete command"

        select case(textholder)
            case('overlap')
                arg_pos=arg_pos + 1
                call get_command_argument(arg_pos, textholder, arg_len)
                if(arg_len==0) stop "Missing argument to delete overlap command"
                read(textholder, *) rc_off
            case default
                print *, "Command ", trim(adjustl(textholder)), " is not accepted for option delete"
                stop 3
        end select 

        arg_pos = arg_pos + 1

        do while(.true.)
            if(arg_pos > command_argument_count()) exit
            !Pull out the next argument which should either be a keyword or an option
            arg_pos=arg_pos+1
            call get_command_argument(arg_pos, textholder)
            textholder=adjustl(textholder)

            select case(trim(textholder))
            case('first')
                first=.true.
            case('last')
                first=.false.
            case default
                !if it isn't an available option to opt_group then we just exit
                exit 
            end select
        end do
    end subroutine parse_delete

    subroutine delete_overlap
        !This subroutine deletes all overlapping atoms, which is defined as atoms which are separated by a distance of 
        !less then rc_off

        integer :: i, c(3), ci, cj, ck, num_nei, nei, delete_num
        integer, dimension(atom_num) :: for_delete

        !These are the variables containing the cell list information
        integer, dimension(3) :: cell_num
        integer, allocatable :: num_in_cell(:,:,:), which_cell(:,:)
        integer, allocatable :: cell_list(:,:,:,:)
        logical :: deleted_atom(atom_num)
        
        allocate(which_cell(3,atom_num))

        !First pass the atom list and atom num to the algorithm which builds the cell list
        call build_cell_list(atom_num, r_atom, rc_off, cell_num, num_in_cell, cell_list, which_cell)

        !Now loop over every atom and figure out if it has neighbors within the rc_off
        delete_num = 0
        deleted_atom=.false.
        atom_loop: do i = 1, atom_num
            
            !c is the position of the cell that the atom belongs to 
            c = which_cell(:,i)

            !Check to make sure it hasn't already been deleted
            if(all(c /= 0)) then 
                !Now loop over all neighboring cells
                do ci = -1, 1, 1
                    do cj = -1, 1, 1
                        do ck = -1, 1, 1  

                            if (any((c + (/ ck, cj, ci /)) == 0)) cycle 

                            if( (c(1) + ck > cell_num(1)).or.(c(2) + cj > cell_num(2)).or. &
                                (c(3) + ci > cell_num(3))) cycle


                            do num_nei = 1, num_in_cell(c(1) + ck, c(2) + cj, c(3) + ci)
                                nei = cell_list(num_nei,c(1) + ck, c(2) + cj, c(3) + ci)

                                !Check to make sure the atom isn't the same index as the atom we are checking 
                                !and that the neighbor hasn't already been deleted
                                if((nei /= i).and.(.not.deleted_atom(nei))) then 

                                    !Now check to see if it is in the cutoff radius, if it is add it to the delete code
                                    if (norm2(r_atom(:,nei)-r_atom(:,i)) < rc_off) then 
                                        
                                        delete_num = delete_num + 1
                                        if(first) then
                                            for_delete(delete_num) = min(i,nei)
                                            deleted_atom(min(i,nei)) = .true.
                                        else
                                            for_delete(delete_num) = max(i,nei)
                                            deleted_atom(max(i,nei)) = .true.
                                        end if

                                        !Now zero out the larger index
                                        if(first) then 
                                            if(i < nei) then 
                                                which_cell(:,i) = 0
                                                cycle atom_loop
                                            else
                                                which_cell(:,nei) = 0 
                                                cell_list(num_nei,c(1) + ck, c(2) + cj, c(3) + ci) = 0
                                            end if
                                        else
                                            if(i > nei) then 
                                                which_cell(:,i) = 0
                                                cycle atom_loop
                                            else
                                                which_cell(:,nei) = 0 
                                                cell_list(num_nei,c(1) + ck, c(2) + cj, c(3) + ci) = 0
                                            end if
                                        end if

                                    end if
                                end if
                            end do 
                        end do
                    end do 
                end do 
            end if

        end do atom_loop

        print *, "Overlap command deletes ", delete_num, " atoms"
        !Now delete all the atoms
        call delete_atoms(delete_num, for_delete(1:delete_num))
    end subroutine delete_overlap
end module opt_delete
