/*******************************************************************************
* Breakout Cave Survey Visualizer
*
* Copyright (C) 2014 James Edwards
*
* jedwards8 at fastmail dot fm
*
* 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., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*******************************************************************************/
package org.andork.swing.async;
import org.andork.util.Java7;
public class Subtask {
public static Subtask defaultCreate(Task parent) {
return parent != null ? new Subtask(parent) : dummySubtask();
}
public static Subtask dummySubtask() {
return new Subtask(null);
}
private Object parent;
private Subtask child;
private String status;
private boolean indeterminate;
private int completed;
private int total;
private int proportion;
public Subtask() {
parent = null;
proportion = 1;
}
private Subtask(Subtask parent, int proportion) {
this.parent = parent;
this.proportion = proportion;
}
public Subtask(Task parent) {
this.parent = parent;
proportion = 1;
}
public Subtask beginSubtask(int proportion) {
if (proportion < 1) {
throw new IllegalArgumentException("proportion must be >= 1");
}
if (child != null) {
throw new IllegalStateException("there is an incomplete subtask.");
}
return child = new Subtask(this, proportion);
}
public void end() {
if (parent instanceof Subtask) {
Subtask parentSubtask = (Subtask) parent;
parentSubtask.child = null;
parentSubtask.updateParent();
}
}
public Subtask getChild() {
return child;
}
public int getCompleted() {
return completed;
}
public double getCompletedRecursive() {
double result = completed;
if (child != null) {
result += child.getCompletedRecursive();
}
return result * proportion / total;
}
public boolean getIndeterminateRecursive() {
return indeterminate || child != null && child.getIndeterminateRecursive();
}
public Object getParent() {
return parent;
}
public int getProportion() {
return proportion;
}
public String getStatus() {
return status;
}
public String getStatusRecursive() {
String childStatus = child == null ? null : child.getStatusRecursive();
return status == null ? childStatus : childStatus == null ? status + "..." : status + ": " + childStatus;
}
public int getTotal() {
return total;
}
public boolean isCanceling() {
return parent instanceof Task ? ((Task) parent).isCanceling()
: parent instanceof Subtask ? ((Subtask) parent).isCanceling() : null;
}
public boolean isIndeterminate() {
return indeterminate;
}
public void setCompleted(int completed) {
if (this.completed != completed) {
this.completed = completed;
updateParent();
}
}
public void setIndeterminate(boolean indeterminate) {
if (this.indeterminate != indeterminate) {
this.indeterminate = indeterminate;
updateParent();
}
}
public void setStatus(String status) {
if (!Java7.Objects.equals(this.status, status)) {
this.status = status;
updateParent();
}
}
public void setTotal(int total) {
if (this.total != total) {
this.total = total;
updateParent();
}
}
private void updateParent() {
if (parent instanceof Task) {
Task task = (Task) parent;
String status = getStatusRecursive();
if (status != null) {
task.setStatus(status);
}
task.setIndeterminate(getIndeterminateRecursive());
task.setCompleted((int) Math.round(getCompletedRecursive() * task.getTotal()));
} else if (parent instanceof Subtask) {
((Subtask) parent).updateParent();
}
}
}