module children
implicit none

    public
    private::redraw_child, index_from_id

    ! Allow no more than 32 windows
    integer, parameter::max_windows = 32
    
    ! Width and height of our child window
    integer, parameter::wc = 180
    integer, parameter::hc = 80
    
    
    ! Array of child window ids and the system times at which each was created
    integer, volatile, dimension(max_windows)::child_ids
    real, volatile, dimension(max_windows)::child_create_time
    
contains

    ! Creates a childwindow and assigns its id to an available slot in our
    ! global array of child window ids
    subroutine create_child()
    use appgraphics
    implicit none
        
        integer::child_index
        character(40)::title
        integer::close_button
        
        ! Loop to find an available slot
        do child_index=1, max_windows
        
            ! If the array of children is a negative one, it is available for 
            ! storing a child id
            if(child_ids(child_index) .EQ. -1) then
            
                ! Create a title for this window
                Write(title, '(A5,1X,I3)') "Child", child_index
            
                ! Create the window, making sure that "closeflag" is false
                child_ids(child_index) = initwindow(wc, hc, &
                                                    title=title, &
                                                    closeflag=.FALSE.)
                
                ! Set up some styles for this window
                call settextstyle(WINDOWS_FONT, HORIZ_DIR, 8)
                call setbkcolor(BLACK)
                call setcolor(WHITE)
                
                ! Store a zero as "when it was created" for now
                child_create_time(child_index) = 0.0
                
                ! One button to close this child
                close_button = createbutton(wc-50, hc-40, 40, 30, &
                                            "Close", close_child)
                                            
                exit
                
            end if
        end do
    
    end subroutine create_child
    
    ! Routine to redraw a single child window
    !
    ! This routine accepts an index into our global array of child ids,
    ! not a child id itself.
    subroutine redraw_child(child_index, time_now)
    use appgraphics
    implicit none
    
        integer, intent(in)::child_index
        real, intent(in)::time_now
        integer::child_id
        character(40)::text
        integer::longevity
        integer::previous_current

        ! Get the child id from our array
        child_id = child_ids(child_index)
        if(child_id .GE. 0) then
        
            ! If its create time is zero, store the system time now
            if(child_create_time(child_index) .EQ. 0.0) then
            
                child_create_time(child_index) = time_now
                longevity = 0

            ! Otherwise, calculate the difference in times
            else
            
                longevity = int(time_now - child_create_time(child_index))
            
            end if
            
            ! Write out how old this window is
            write(text, '(A19,1X,I4,1X,A7)') "I've been alive for", &
                                             longevity, &
                                             "seconds"
            
            !  Store the "current" window for good measure
            previous_current = getcurrentwindow()
            
            ! Select this window as current and display the text in the window
            call setcurrentwindow(child_id)
            call clearviewport()
            call outtextxy(10, 10, text)
            
            !  Reset the current window to its previous state
            call setcurrentwindow(previous_current)

        end if
    
    end subroutine redraw_child
    
    ! Loops through all child windows and redraws them
    subroutine redraw_children(time_now)
    implicit none
    
        real, intent(in)::time_now
        integer::i
        
        do i = 1, max_windows
            call redraw_child(i, time_now)        
        end do
        
    end subroutine redraw_children
    
    ! Closes a child window and erases traces of it from our arrays of
    ! child windows and thier creation times
    subroutine close_child
    use appgraphics
    implicit none
    
        integer::child_id
        integer::child_index
        
        ! This call determines the id of the window that executed this
        ! callback
        child_id = getsignallingwindow()
        
        ! And we'll retrieve theindex of this window in our global
        ! arrays
        child_index = index_from_id(child_id)
        
        ! Mark this chold window slot as available for a new child
        if(child_index .GT. -1) then
            child_ids(child_index) = -1
            child_create_time(child_index) = 0.0
        end if
        
        if(child_id .GT. -1) then
            call closewindow(child_id)
        end if
            
    end subroutine close_child
    
    ! Function to find a child id in our global array and return
    ! the index of said window id
    pure function index_from_id(child_id) result(child_index)
    implicit none
    
        integer, intent(in)::child_id
        integer::child_index
        
        if(child_id .EQ. -1) then
            child_index = -1
        
        else
        
            do child_index = 1, max_windows
                if(child_ids(child_index) .EQ. child_id) then
                    exit
                end if
            end do
            
            if(child_index .GT. max_windows) then
                child_index = -1
            end if
            
        end if
        
    end function index_from_id
    
end module children
