program main
    !**************************** CACmb  ********************  
    !*                  CAC model building toolkit          *
    !*                        ____________                  *
    !*                       /           /                  *    
    !*                      /           /                   *
    !*                     /___________/                    *
    !*       _|_  _|_   _|____________                      *
    !*                   /           /                      *
    !*                  /           /                       *
    !*                 /___________/                        *         
    !*                                                      *
    !********************************************************  

    use parameters
    use elements
    use io
    use caller
    
 
    integer ::  i, end_mode_arg, arg_num, arg_pos
    character(len=100) ::  argument

    !Print introduction text
    print *, '*********************** CACmb  *********************'
    print *, '*            CAC model building toolkit            *'
    print *, '*                        _______                   *'
    print *, '*                       /       /                  *'
    print *, '*                      /       /                   *'
    print *, '*                     /______ /                    *'
    print *, '*       _|_  _|_   _|_______                       *'
    print *, '*                   /       /                      *'
    print *, '*                  /       /                       *'
    print *, '*                 /______ /                        *'
    print *, '*                                                  *'
    print *, '****************************************************'

    !Call initialization functions
    call lattice_init
    call box_init
    call init_random_seed
    force_overwrite=.false.
    norefine=.false.
    wrap_flag = .false.
    all_new = .false.

    end_mode_arg = 0
    
    ! Command line parsing
    arg_num = command_argument_count()

    !First check to see if certain commands are passed, these commands must be known before code 
    !is executed.
    do i = 1, arg_num
        call get_command_argument(i,argument)
        select case(trim(adjustl(argument)))

        !This lets us know if we are overwriting all files
        case('-ow')
            force_overwrite = .true.
            print *, "Overwrite flag passed, output files will be overwritten"

        !This lets us know if we need to wrap atomic positions back into the cell
        case('-wrap')
            wrap_flag=.true.

        case('-norefine')
            norefine=.true.
        
        case('-set_cac')
            call set_cac(i)
        case('-set_types')
            call set_types(i)
        case('-all_new')
            all_new=.true.
        end select 
    end do 
    !Determine if a mode is being used and what it is. The first argument has to be the mode
    !if a mode is being used
    call get_command_argument(1, argument)

    argument = trim(adjustl(argument))
    if (argument(1:2) == '--') then 
        mode = argument
        call call_mode(end_mode_arg)
    end if

    !Check to make sure a mode was called
    if (end_mode_arg==0) then 
        stop "Nothing to do, please run cacmb using an available mode"
    end if
    !Now we loop through all of the arguments and check for passed options or for a filename to be written out
    arg_pos = end_mode_arg
    do while(.true.)
        !Exit the loop if we are done reading
        if(arg_pos > arg_num) exit

        call get_command_argument(arg_pos, argument)

        !Check to see if a filename was passed
        if(scan(argument,'.',.true.) > 0) then 
            call get_out_file(argument)
            arg_pos = arg_pos + 1

        !Check to see if an option has been passed
        else if(argument(1:1) == '-') then 
            call call_option(argument, arg_pos)
        !Otherwise print that the argument is not accepted and move on
        else
            print *, trim(adjustl(argument)), " is not an accepted command."
            stop 3
        end if
    end do

    !If wrap flag was passed then call the wrap atoms command
    if(wrap_flag) then 
        call wrap_atoms
        call wrap_elements
    end if

    !If we called the boundary command then we adjust the box bounds
    if(bound_called) call def_new_box

    !Check to make sure a file was passed to be written out and then write out 
    ! Before building do a check on the file
    if ((trim(adjustl(mode)) /= "--metric").and.(trim(adjustl(mode)) /= "--calc").and.(trim(adjustl(mode)) /= "--da"))then    
        if ((outfilenum == 0)) then
            argument = 'none'
            call get_out_file(argument)
        end if
        call write_out
    end if

    return
end program main
