// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The tabwriter package implements a write filter (tabwriter.Writer)
// that translates tabbed columns in input into properly aligned text,
// using the Elastic Tabstops algorithm described at
// http://nickgravgaard.com/elastictabstops/index.html.
//
package tabwriter

import (
	"bytes";
	"container/vector";
	"io";
	"os";
	"utf8";
)


// ----------------------------------------------------------------------------
// Filter implementation

// A cell represents a segment of text delineated by tabs, form-feed,
// or newline chars. The text itself is stored in a separate buffer;
// cell only describes the segment's size in bytes and width in runes.
//
type cell struct {
	size int;  // cell size in bytes
	width int;  // cell width in runes
}


// A Writer is a filter that inserts padding around
// tab-delimited columns in its input to align them
// in the output.
//
// The Writer treats incoming bytes as UTF-8 encoded text
// consisting of tab-terminated cells. Cells in adjacent lines
// constitute a column. The Writer inserts padding as needed
// to make all cells in a column have the same width, effectively
// aligning the columns. Note that cells are tab-terminated,
// not tab-separated: trailing non-tab text at the end of a line
// is not part of any cell.
//
// The Writer assumes that all characters have the same width;
// this may not be true in some fonts, especially with certain
// UTF-8 characters.
//
// If a Writer is configured to filter HTML, HTML tags and entities
// are simply passed through. The widths of tags and entities are
// assumed to be zero (tags) and one (entities) for formatting purposes.
//
// The form feed character ('\f') acts like a newline but it also
// terminates all columns in the current line (effectively calling
// Flush). Cells in the next line start new columns. Unless found
// inside an HTML tag, form feed characters appear as newlines in
// the output.
//
// The Writer must buffer input internally, because proper spacing
// of one line may depend on the cells in future lines. Clients must
// call Flush when done calling Write.
//
type Writer struct {
	// configuration
	output io.Writer;
	cellwidth int;
	padding int;
	padbytes [8]byte;
	flags uint;

	// current state
	buf bytes.Buffer;  // collected text w/o tabs, newlines, or form feed chars
	pos int;  // buffer position up to which width of incomplete cell has been computed
	cell cell;  // current incomplete cell; cell.width is up to buf[pos] w/o ignored sections
	html_char byte;  // terminating char of html tag/entity, or 0 ('>', ';', or 0)
	lines vector.Vector;  // list if lines; each line is a list of cells
	widths vector.IntVector;  // list of column widths in runes - re-used during formatting
}


func (b *Writer) addLine() {
	b.lines.Push(vector.New(0));
}


func (b *Writer) line(i int) *vector.Vector {
	return b.lines.At(i).(*vector.Vector);
}


// Reset the current state.
func (b *Writer) reset() {
	b.buf.Reset();
	b.pos = 0;
	b.cell = cell{};
	b.html_char = 0;
	b.lines.Init(0);
	b.widths.Init(0);
	b.addLine();
}


// Internal representation (current state):
//
// - all text written is appended to buf; form feed chars, tabs and newlines are stripped away
// - at any given time there is a (possibly empty) incomplete cell at the end
//   (the cell starts after a tab, form feed, or newline)
// - size is the number of bytes belonging to the cell so far
// - width is text width in runes of that cell from the start of the cell to
//   position pos; html tags and entities are excluded from this width if html
//   filtering is enabled
// - the sizes and widths of processed text are kept in the lines_size and
//   lines_width arrays, which contain an array of sizes or widths for each line
// - the widths array is a temporary array with current widths used during
//   formatting; it is kept in Writer because it's re-used
//
//                    |<---------- size ---------->|
//                    |                            |
//                    |<- width ->|<- ignored ->|  |
//                    |           |             |  |
// [---processed---tab------------<tag>...</tag>...]
// ^                  ^                         ^
// |                  |                         |
// buf                start of incomplete cell  pos


// Formatting can be controlled with these flags.
const (
	// Ignore html tags and treat entities (starting with '&'
	// and ending in ';') as single characters (width = 1).
	FilterHTML = 1 << iota;

	// Force right-alignment of cell content.
	// Default is left-alignment.
	AlignRight;
)


// A Writer must be initialized with a call to Init. The first parameter (output)
// specifies the filter output. The remaining parameters control the formatting:
//
//	cellwidth	minimal cell width
//	padding		additional cell padding
//	padchar		ASCII char used for padding
//				if padchar == '\t', the Writer will assume that the
//				width of a '\t' in the formatted output is cellwidth,
//				and cells are left-aligned independent of align_left
//				(for correct-looking results, cellwidth must correspond
//				to the tab width in the viewer displaying the result)
//	flags		formatting control
//
func (b *Writer) Init(output io.Writer, cellwidth, padding int, padchar byte, flags uint) *Writer {
	if cellwidth < 0 {
		panic("negative cellwidth");
	}
	if padding < 0 {
		panic("negative padding");
	}
	b.output = output;
	b.cellwidth = cellwidth;
	b.padding = padding;
	for i := len(b.padbytes) - 1; i >= 0; i-- {
		b.padbytes[i] = padchar;
	}
	if padchar == '\t' {
		// tab enforces left-alignment
		flags &^= AlignRight;
	}
	b.flags = flags;

	b.reset();

	return b;
}


// debugging support (keep code around)
/*
func (b *Writer) dump() {
	pos := 0;
	for i := 0; i < b.lines_size.Len(); i++ {
		line_size, line_width := b.line(i);
		print("(", i, ") ");
		for j := 0; j < line_size.Len(); j++ {
			s := line_size.At(j);
			print("[", string(b.buf.slice(pos, pos + s)), "]");
			pos += s;
		}
		print("\n");
	}
	print("\n");
}
*/


func (b *Writer) write0(buf []byte) os.Error {
	n, err := b.output.Write(buf);
	if n != len(buf) && err == nil {
		err = os.EIO;
	}
	return err;
}


var newline = []byte{'\n'}

func (b *Writer) writePadding(textw, cellw int) os.Error {
	if b.padbytes[0] == '\t' {
		// make cell width a multiple of cellwidth
		cellw = ((cellw + b.cellwidth - 1) / b.cellwidth) * b.cellwidth;
	}

	n := cellw - textw;
	if n < 0 {
		panic("internal error");
	}

	if b.padbytes[0] == '\t' {
		n = (n + b.cellwidth - 1) / b.cellwidth;
	}

	for n > len(b.padbytes) {
		if err := b.write0(&b.padbytes); err != nil {
			return err;
		}
		n -= len(b.padbytes);
	}

	return b.write0(b.padbytes[0 : n]);
}


func (b *Writer) writeLines(pos0 int, line0, line1 int) (int, os.Error) {
	pos := pos0;
	for i := line0; i < line1; i++ {
		line := b.line(i);
		for j := 0; j < line.Len(); j++ {
			c := line.At(j).(cell);

			switch {
			default: // align left

				if err := b.write0(b.buf.Bytes()[pos : pos + c.size]); err != nil {
					return pos, err;
				}
				pos += c.size;
				if j < b.widths.Len() {
					if err := b.writePadding(c.width, b.widths.At(j)); err != nil {
						return pos, err;
					}
				}

			case b.flags & AlignRight != 0:  // align right

				if j < b.widths.Len() {
					if err := b.writePadding(c.width, b.widths.At(j)); err != nil {
						return pos, err;
					}
				}
				if err := b.write0(b.buf.Bytes()[pos : pos + c.size]); err != nil {
					return pos, err;
				}
				pos += c.size;
			}
		}

		if i+1 == b.lines.Len() {
			// last buffered line - we don't have a newline, so just write
			// any outstanding buffered data
			if err := b.write0(b.buf.Bytes()[pos : pos + b.cell.size]); err != nil {
				return pos, err;
			}
			pos += b.cell.size;
		} else {
			// not the last line - write newline
			if err := b.write0(newline); err != nil {
				return pos, err;
			}
		}
	}
	return pos, nil;
}


func (b *Writer) format(pos0 int, line0, line1 int) (pos int, err os.Error) {
	pos = pos0;
	column := b.widths.Len();
	last := line0;
	for this := line0; this < line1; this++ {
		line := b.line(this);

		if column < line.Len() - 1 {
			// cell exists in this column
			// (note that the last cell per line is ignored)

			// print unprinted lines until beginning of block
			pos, err = b.writeLines(pos, last, this);
			if err != nil {
				return pos, err;
			}
			last = this;

			// column block begin
			width := b.cellwidth;  // minimal width
			for ; this < line1; this++ {
				line = b.line(this);
				if column < line.Len() - 1 {
					// cell exists in this column => update width
					w := line.At(column).(cell).width + b.padding;
					if w > width {
						width = w;
					}
				} else {
					break
				}
			}
			// column block end

			// format and print all columns to the right of this column
			// (we know the widths of this column and all columns to the left)
			b.widths.Push(width);
			pos, err = b.format(pos, last, this);
			b.widths.Pop();
			last = this;
		}
	}

	// print unprinted lines until end
	return b.writeLines(pos, last, line1);
}


// Append text to current cell. Only update the cell width if updateWidth
// is set (the cell width can only be updated if we know that we cannot be
// in the middle of a UTF-8 encoded Unicode character).
//
func (b *Writer) append(text []byte, updateWidth bool) {
	b.buf.Write(text);
	b.cell.size += len(text);
	if updateWidth {
		b.cell.width += utf8.RuneCount(b.buf.Bytes()[b.pos : b.buf.Len()]);
		b.pos = b.buf.Len();
	}
}


// Start HTML-escape mode.
func (b *Writer) startHTML(ch byte) {
	if ch == '<' {
		b.html_char = '>';
	} else {
		b.html_char = ';';
	}
}


// Terminate HTML-escape mode. If the HTML text was an entity, its width
// is assumed to be one for formatting purposes; otherwise it assumed to
// be zero.
//
func (b *Writer) terminateHTML() {
	if b.html_char == ';' {
		// was entity, count as one rune
		b.cell.width++;
	}
	b.pos = b.buf.Len();
	b.html_char = 0;
}


// Terminate the current cell by adding it to the list of cells of the
// current line. Returns the number of cells in that line.
//
func (b *Writer) terminateCell() int {
	line := b.line(b.lines.Len() - 1);
	line.Push(b.cell);
	b.cell = cell{};
	return line.Len();
}


// Flush should be called after the last call to Write to ensure
// that any data buffered in the Writer is written to output. Any
// incomplete HTML tag or entity at the end is simply considered
// complete for formatting purposes.
//
func (b *Writer) Flush() os.Error {
	// add current cell if not empty
	if b.cell.size > 0 {
		if b.html_char != 0 {
			// inside html tag/entity - terminate it even if incomplete
			b.terminateHTML();
		}
		b.terminateCell();
	}

	// format contents of buffer
	_, err := b.format(0, 0, b.lines.Len());

	// reset, even in the presence of errors
	b.reset();

	return err;
}


// Write writes buf to the writer b.
// The only errors returned are ones encountered
// while writing to the underlying output stream.
//
func (b *Writer) Write(buf []byte) (written int, err os.Error) {
	// split text into cells
	i0 := 0;
	for i, ch := range buf {
		if b.html_char == 0 {
			// outside html tag/entity
			switch ch {
			case '\t', '\n', '\f':
				// end of cell
				b.append(buf[i0 : i], true);
				i0 = i+1;  // exclude ch from (next) cell
				ncells := b.terminateCell();
				if ch != '\t' {
					// terminate line
					b.addLine();
					if ch == '\f' || ncells == 1 {
						// A '\f' always forces a flush. Otherwise, if the previous
						// line has only one cell which does not have an impact on
						// the formatting of the following lines (the last cell per
						// line is ignored by format()), thus we can flush the
						// Writer contents.
						if err = b.Flush(); err != nil {
							return i0, err;
						}
					}
				}

			case '<', '&':
				// possibly an html tag/entity
				if b.flags & FilterHTML != 0 {
					// begin of tag/entity
					b.append(buf[i0 : i], true);
					i0 = i;
					b.startHTML(ch);
				}
			}

		} else {
			// inside html tag/entity
			if ch == b.html_char {
				// end of tag/entity
				b.append(buf[i0 : i+1], false);
				i0 = i+1;  // exclude ch from (next) cell
				b.terminateHTML();
			}
		}
	}

	// append leftover text
	b.append(buf[i0 : len(buf)], false);
	return len(buf), nil;
}


// NewWriter allocates and initializes a new tabwriter.Writer.
// The parameters are the same as for the the Init function.
//
func NewWriter(output io.Writer, cellwidth, padding int, padchar byte, flags uint) *Writer {
	return new(Writer).Init(output, cellwidth, padding, padchar, flags)
}
