/*
 * ConsoleFormatter.java
 *
 * Created on October 7, 2004, 10:00 AM
 */

/** This class exists to make the toString() output from the
 * PCComponent class look good in a console session.
 * @author Timothy Paul Fox
 */
public class ConsoleFormatter {
    private String allSpaces;
    private int tabWidth = 4;
    private int costTabPos = 65;
    
    /** Creates a new instance of ConsoleFormatter */
    public ConsoleFormatter() {
        allSpaces = 
        "                                                             " +
        "                                                             " ;
    }

    /** expands embedded tabs to spaces, right-justifies remainder of
     * the line after a ^B character.
     * @param tabbed a String with embedded TAB characters, optionally 
     * terminated with a ^B followed by a cost value.
     * @return the input string with TABs and ^B replaced by spaces.
     */
    public String expandTabbedString(String tabbed) {
        if (null == tabbed) return "";
        int inLength = tabbed.length();
        if (inLength < 3) return tabbed;
        
        StringBuffer sb = new StringBuffer(80);
        StringBuffer work = new StringBuffer();
        int nextEOL = 0, lastTabPos, tabPos, padWidth;
        int nextStart = 0;
        
        do {
            nextEOL = tabbed.indexOf('\n', nextStart);
            if (nextEOL < 0) 
                nextEOL = inLength -1;
            work.setLength(0);
            work.append(tabbed.substring(nextStart, nextEOL + 1));
            lastTabPos = -1;
            tabPos = work.indexOf("\t");
            // expand the tabs in work
            while (tabPos > lastTabPos) {
                padWidth = 1 + tabWidth - (tabPos % tabWidth);
                work.deleteCharAt(tabPos);
                work.insert(tabPos, allSpaces.substring(0, padWidth));
                lastTabPos = tabPos;
                tabPos = work.toString().indexOf('\t', lastTabPos);
            }
            // expand decimal tab, if any
            tabPos = work.indexOf("\u0002");
            if (tabPos > 0) {
                work.deleteCharAt(tabPos);
                padWidth = costTabPos - work.length();
                if (work.charAt(work.length() - 1) != '\n')
                    padWidth--;
                if (padWidth > 0) {
                    work.insert(tabPos, allSpaces.substring(0, padWidth));
                }
            }

            // copy this chunk to the output buffer
            sb.append(work);
            nextStart = nextEOL + 1;
        // } while (nextEOL >= 0);
        } while (nextStart < inLength);
        return sb.toString();
    }
    
    /** sets the distance between TAB stops. The default TAB width is 4.
     * @param width an integer 1..9
     */    
    public void setTabWidth(int width) {
        if (width > 0 && width < 10)
            tabWidth = width;
    }
    
    /** sets the right margin for lines that contain a ^B character
     * @param rightTab an integer between 40 and 80
     */    
    public void setCostTabPos(int rightTab) {
        if (rightTab >= 40 && rightTab <= 80)
            costTabPos = rightTab;
    }
}