# Virtual Media Management
use strict;
use warnings;
our (%gui, %hostspec);

sub show_vmm_dialog() {
    &addrow_log("Retrieving media information...");
    &busy_window($gui{windowMain}, 0, 'watch');
    &fill_list_vmmhd();
    &fill_list_vmmdvd();
    &fill_list_vmmfloppy();
    &addrow_log("Retrieved media information.");
    &busy_window($gui{windowMain}, 0);
    $gui{dialogVMM}->run;
    $gui{dialogVMM}->hide;
}

sub recurse_media_snapshot() {
    my ($treestore, $IMedium, $iter, $type) = @_;
    my $citer = $treestore->append($iter);
    my $gnames;
    my $name = IMedium_getName($IMedium);
    my @guuids = IMedium_getMachineIds($IMedium);
    my $MediumState = IMedium_refreshState($IMedium); # Needed otherwise sizes may be 0 etc

    foreach my $id (@guuids) {
        my $snames;
        my $IMachine = IVirtualBox_findMachine($gui{websn}, $id);
        my $mname = IMachine_getName($IMachine);
        my @suuids = IMedium_getSnapshotIds($IMedium, $id);

        foreach my $snapid (@suuids) {
            next if ($snapid eq $id);
            my $ISnapshot = IMachine_findSnapshot($IMachine, $snapid);
            my $snapname = ISnapshot_getName($ISnapshot);
            $snames .= "$snapname, ";
        }

        if ($snames) {
            $snames =~ s/, $//;
            $gnames .= "$mname ($snames), ";}
        else { $gnames .= "$mname, "; }
    }

    $gnames = '<None>' if (!$gnames);
    $gnames =~ s/, $//; # Remove any trailing,

    if ($type eq 'HardDisk') {
        if ($MediumState eq 'Inaccessible') {
            $treestore->set($citer, 0, $name, 1, $IMedium, 2, $gnames, 3, 0, 4, 0, 5, $gui{pixbufstatuserror16},
                                    6, IMedium_getLastAccessError($IMedium));
        }
        else {
            $treestore->set($citer, 0, $name, 1, $IMedium, 2, $gnames, 3, &bytesToX(IMedium_getSize($IMedium)),
                                    4, &bytesToX(IMedium_getLogicalSize($IMedium)));
        }
    }
    elsif ($type eq 'DVD') {
        if ($MediumState eq 'Inaccessible') {
            $treestore->set($citer, 0, $name, 1, $IMedium, 2, $gnames, 3, 0, 4, $gui{pixbufstatuserror16},
                                    5, IMedium_getLastAccessError($IMedium));
        }
        else { $treestore->set($citer, 0, $name, 1, $IMedium, 2, $gnames, 3, &bytesToX(IMedium_getSize($IMedium))); }
    }
    else {
        if ($MediumState eq 'Inaccessible') {
            $treestore->set($citer, 0, $name, 1, $IMedium, 2, $gnames, 3, 0, 4, $gui{pixbufstatuserror16},
                                    5, IMedium_getLastAccessError($IMedium));
        }
        else { $treestore->set($citer, 0, $name, 1, $IMedium, 2, $gnames, 3, &bytesToX(IMedium_getSize($IMedium))); }
    }

    &recurse_media_snapshot($treestore, $_, $citer, $type) foreach (IMedium_getChildren($IMedium));
}

sub vmm_tabchanged() {
    my ($widget, $focus, $page) = @_;
    $gui{entryVMMAttachedTo}->set_text('');
    $gui{entryVMMLocation}->set_text('');
    &sensitive_off($gui{toolbuttonVMMRemove}, $gui{toolbuttonVMMRelease});

    #We need to re-evaluate selection on tab change
    if ($page == 0) {
        $gui{toolbuttonVMMAdd}->set_label('Add Hard Disk');
        &onsel_list_vmmhd() if ($gui{treeviewVMMHD}->get_selection->get_selected());
    }
    elsif ($page == 1) {
        $gui{toolbuttonVMMAdd}->set_label('Add CD/DVD');
        &onsel_list_vmmdvd() if ($gui{treeviewVMMDVD}->get_selection->get_selected());
    }
    else {
        $gui{toolbuttonVMMAdd}->set_label('Add Floppy');
        &onsel_list_vmmfloppy() if ($gui{treeviewVMMFloppy}->get_selection->get_selected());
    }
}

sub vmm_release() {
    my %medium;
    my $page = $gui{notebookVMM}->get_current_page();
    my $warn = 0;

    if ($page == 0) { %medium = &getsel_list_vmmhd(); }
    elsif ($page == 1) { %medium = &getsel_list_vmmdvd(); }
    else { %medium = &getsel_list_vmmfloppy(); }

    my @guuids = IMedium_getMachineIds($medium{IMedium});

    foreach my $id (@guuids) {
        my $IMachine = IVirtualBox_findMachine($gui{websn}, $id);
        my @IMediumAttachment = IMachine_getMediumAttachments($IMachine);

        foreach my $attach (@IMediumAttachment) {
            if ($$attach{medium} eq $medium{IMedium}) {
                my ($ISession, $IMachineM) = &get_mutable_session($IMachine);

                if ($ISession) {
                    IMachine_detachDevice($IMachineM, $$attach{controller}, $$attach{port}, $$attach{device});
                    IMachine_saveSettings($IMachineM);
                    ISession_unlockMachine($ISession);
                }
                else { $warn = 1; }
            }
        }
    }

    if ($warn == 1) { &show_err_msg('mediuminuse', $gui{messagedialogWarning}, " ($medium{Name})"); }
    else { &addrow_log("Medium $medium{Name} released."); }

    if ($page == 0) { &fill_list_vmmhd(); }
    elsif ($page == 1) { &fill_list_vmmdvd(); }
    else { &fill_list_vmmfloppy(); }
}

sub vmm_rem() {
    my $page = $gui{notebookVMM}->get_current_page();

    if ($page == 0) {
        my %hd = &getsel_list_vmmhd();
        my $response = $gui{dialogRemoveDelete}->run;
        $gui{dialogRemoveDelete}->hide;

        if ($response eq '1') { # Deletes Disk
            # Use get state and not refresh state to ensure we have latest info
            my $MediumState = IMedium_refreshState($hd{IMedium});
            if ($MediumState eq 'Created' or $MediumState eq 'Inaccessible') {
                my $IProgress = IMedium_deleteStorage($hd{IMedium});
                &show_progress_window($IProgress, "Deleting hard disk $hd{Name}...", 'cancel', $gui{dialogVMM});
                &addrow_log("Deleted hard disk: $hd{Name}.");
                &fill_list_vmmhd();
            }
            else { &show_err_msg('deletemedium', $gui{messagedialogWarning}, " ( $hd{Name})"); }
        }
        elsif ($response eq '2') { # Removes Disk
            IMedium_close($hd{IMedium});
            &addrow_log("Storage $hd{Name} removed.");
            &fill_list_vmmhd();
        }
    }
    elsif ($page == 1) {
        my %dvd = &getsel_list_vmmdvd();
        IMedium_close($dvd{IMedium});
        &addrow_log("Storage $dvd{Name} removed.");
        &fill_list_vmmdvd();
    }
    else {
        my %floppy = &getsel_list_vmmfloppy();
        IMedium_close($floppy{IMedium});
        &addrow_log("Storage $floppy{Name} removed.");
        &fill_list_vmmfloppy();
    }
}

sub vmm_add() {
    my ($location) = @_;
    my $page = $gui{notebookVMM}->get_current_page();

    if ($location) {
        if ($page == 0) {
            IVirtualBox_openMedium($gui{websn}, $location, 'HardDisk', 'ReadWrite');
            &fill_list_vmmhd();
        }
        elsif ($page == 1) {
            IVirtualBox_openMedium($gui{websn}, $location, 'DVD', 'ReadOnly');
            &fill_list_vmmdvd();
        }
        else {
            IVirtualBox_openMedium($gui{websn}, $location, 'Floppy', 'ReadWrite');
            &fill_list_vmmfloppy();
        }
    }
}

1;