// 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 (
	"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 io.ByteBuffer;  // 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.Data()[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.Data()[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.Data()[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.Data()[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)
}
