AppleCommander/app/cli-acx/src/main/java/io/github/applecommander/acx/command/DiskMapCommand.java

116 lines
4.1 KiB
Java

/*
* AppleCommander - An Apple ][ image utility.
* Copyright (C) 2019-2022 by Robert Greene and others
* robgreene at users.sourceforge.net
*
* 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 2 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, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package io.github.applecommander.acx.command;
import java.util.Arrays;
import java.util.function.Function;
import com.webcodepro.applecommander.storage.FormattedDisk;
import com.webcodepro.applecommander.storage.FormattedDisk.DiskUsage;
import io.github.applecommander.acx.base.ReadOnlyDiskImageCommandOptions;
import picocli.CommandLine.Command;
@Command(name = "diskmap", description = "Show disk usage map.",
aliases = { "map" })
public class DiskMapCommand extends ReadOnlyDiskImageCommandOptions {
@Override
public int handleCommand() throws Exception {
Arrays.asList(disk.getFormattedDisks()).forEach(this::showDiskMap);
return 0;
}
public void showDiskMap(FormattedDisk formattedDisk) {
final int[] dimensions = formattedDisk.getBitmapDimensions();
final int length = formattedDisk.getBitmapLength();
final int width,height;
final Function<Integer,Integer> leftNumFn, rightNumFn;
if (dimensions != null && dimensions.length == 2) {
height = dimensions[0];
width = dimensions[1];
// This is expected to be Track, so same number on left and right.
leftNumFn = rightNumFn = i -> i;
} else {
width = 70;
height= (length + width - 1) / width;
// This is expected to be blocks, so show start of range of
// left and end of range on right.
leftNumFn = i -> i * width;
rightNumFn = i -> (i + 1) * width - 1;
}
title(formattedDisk.getBitmapLabels());
header1(width); // 10's position
header2(width); // 1's position
header3(width); // divider
DiskUsage diskUsage = formattedDisk.getDiskUsage();
for (int y=0; y<height; y++) {
System.out.printf("%5d|", leftNumFn.apply(y));
for (int x=0; x<width; x++) {
if (diskUsage.hasNext()) {
diskUsage.next();
System.out.print(diskUsage.isUsed() ? '*' : '.');
} else {
System.out.print(" ");
}
}
System.out.printf("|%d", rightNumFn.apply(y));
System.out.println();
}
header3(width);
header2(width);
header1(width);
}
void title(String[] labels) {
System.out.print(" ");
if (labels.length == 2) {
System.out.printf("X=%s, Y=%s", labels[1], labels[0]);
}
else {
System.out.printf("By %s", String.join(", ", labels));
}
System.out.println();
}
void header1(final int width) {
System.out.print(" ");
for (int i=0; i<width; i++) {
System.out.print(i % 10 == 0 ? Character.forDigit(i%10, 10) : ' ');
}
System.out.println();
}
void header2(final int width) {
System.out.print(" ");
for (int i=0; i<width; i++) {
System.out.print(i%10);
}
System.out.println();
}
void header3(final int width) {
System.out.print(" ");
for (int i=0; i<width; i++) {
System.out.print(i%5 == 0 ? '+' : '-');
}
System.out.println();
}
}