package com.redhat.ceylon.common;
public class StatusPrinter {
private int lineWidth;
private int remaining;
private final static char abbreviationChar = '…';
private final static String abbreviationString = "…";
private StringBuilder currentLine;
private String capturedLine;
public StatusPrinter(){
this(Integer.getInteger("com.redhat.ceylon.common.tool.terminal.width", 80));
}
public StatusPrinter(int i) {
this.lineWidth = i;
this.remaining = i;
this.currentLine = new StringBuilder(lineWidth);
}
public void clearLine(){
if(currentLine.length() == 0)
return;
StringBuilder sb = new StringBuilder(lineWidth+2);
sb.append('\r');
for(int i=0;i<lineWidth;i++){
sb.append(' ');
}
sb.append('\r');
System.err.print(sb.toString());
System.err.flush();
currentLine.setLength(0);
remaining = lineWidth;
}
private void print(String part) {
System.err.print(part);
currentLine.append(part);
remaining -= part.codePointCount(0, part.length());
System.err.flush();
}
public void log(String str){
print(part(str));
}
public void log(String str, int sizeLimit){
print(part(str, sizeLimit));
}
public void logRight(String str){
print(partRight(str));
}
public void logRight(String str, int sizeLimit){
print(partRight(str, sizeLimit));
}
public String part(String str, int sizeLimit){
if(remaining == 0)
return "";
int codePoints = str.codePointCount(0, str.length());
int max = Math.min(codePoints, sizeLimit);
if(remaining >= max){
if(codePoints != max)
return limit(str, max);
else
return str;
}else{
return limit(str, remaining);
}
}
public String partRight(String str, int sizeLimit){
if(remaining == 0)
return "";
int codePoints = str.codePointCount(0, str.length());
int max = Math.min(codePoints, sizeLimit);
if(remaining >= max){
if(codePoints != max)
return leftPad(limit(str, max), remaining - max);
else
return leftPad(str, remaining - codePoints);
}else{
return limit(str, remaining);
}
}
public String part(String str){
if(remaining == 0)
return "";
int codePoints = str.codePointCount(0, str.length());
if(remaining >= codePoints){
return str;
}else{
return limit(str, remaining);
}
}
public String partRight(String str){
if(remaining == 0)
return "";
int codePoints = str.codePointCount(0, str.length());
if(remaining >= codePoints){
return leftPad(str, remaining-codePoints);
}else{
return limit(str, remaining);
}
}
private String leftPad(String str, int count) {
if(count == 0)
return str;
// normal length works here because we dont change its code point length, every
// space is 1 code point
StringBuilder b = new StringBuilder(str.length()+count);
for(int i=0;i<count;i++)
b.append(' ');
b.append(str);
return b.toString();
}
public int remainingForPercentage(double percentage){
return (int) Math.floor(remaining * percentage);
}
public String limit(String str, int sizeLimit){
int codePoints = str.codePointCount(0, str.length());
if(codePoints <= sizeLimit)
return str;
if(sizeLimit == 0)
return "";
if(sizeLimit == 1)
return abbreviationString;
StringBuilder sb = new StringBuilder();
double half = (sizeLimit-1) / 2.0;
int before = (int) Math.ceil(half);
int after = (int) Math.floor(half);
for(int c=0;c<before;c++)
sb.appendCodePoint(str.codePointAt(c));
sb.append(abbreviationChar);
for(int c=codePoints-after;c<codePoints;c++)
sb.appendCodePoint(str.codePointAt(c));
return sb.toString();
}
public void captureLine() {
capturedLine = currentLine.toString();
}
public void logCapturedLine(){
clearLine();
log(capturedLine);
}
public static boolean canPrint() {
return System.console() != null;
}
public int getRemaining() {
return remaining;
}
}