import { __exports as output } from '../../../../../../../../_virtual/output.js';

/*jshint node:true */

var hasRequiredOutput;

function requireOutput () {
	if (hasRequiredOutput) return output;
	hasRequiredOutput = 1;

	function OutputLine(parent) {
	  this.__parent = parent;
	  this.__character_count = 0;
	  // use indent_count as a marker for this.__lines that have preserved indentation
	  this.__indent_count = -1;
	  this.__alignment_count = 0;
	  this.__wrap_point_index = 0;
	  this.__wrap_point_character_count = 0;
	  this.__wrap_point_indent_count = -1;
	  this.__wrap_point_alignment_count = 0;

	  this.__items = [];
	}

	OutputLine.prototype.clone_empty = function() {
	  var line = new OutputLine(this.__parent);
	  line.set_indent(this.__indent_count, this.__alignment_count);
	  return line;
	};

	OutputLine.prototype.item = function(index) {
	  if (index < 0) {
	    return this.__items[this.__items.length + index];
	  } else {
	    return this.__items[index];
	  }
	};

	OutputLine.prototype.has_match = function(pattern) {
	  for (var lastCheckedOutput = this.__items.length - 1; lastCheckedOutput >= 0; lastCheckedOutput--) {
	    if (this.__items[lastCheckedOutput].match(pattern)) {
	      return true;
	    }
	  }
	  return false;
	};

	OutputLine.prototype.set_indent = function(indent, alignment) {
	  if (this.is_empty()) {
	    this.__indent_count = indent || 0;
	    this.__alignment_count = alignment || 0;
	    this.__character_count = this.__parent.get_indent_size(this.__indent_count, this.__alignment_count);
	  }
	};

	OutputLine.prototype._set_wrap_point = function() {
	  if (this.__parent.wrap_line_length) {
	    this.__wrap_point_index = this.__items.length;
	    this.__wrap_point_character_count = this.__character_count;
	    this.__wrap_point_indent_count = this.__parent.next_line.__indent_count;
	    this.__wrap_point_alignment_count = this.__parent.next_line.__alignment_count;
	  }
	};

	OutputLine.prototype._should_wrap = function() {
	  return this.__wrap_point_index &&
	    this.__character_count > this.__parent.wrap_line_length &&
	    this.__wrap_point_character_count > this.__parent.next_line.__character_count;
	};

	OutputLine.prototype._allow_wrap = function() {
	  if (this._should_wrap()) {
	    this.__parent.add_new_line();
	    var next = this.__parent.current_line;
	    next.set_indent(this.__wrap_point_indent_count, this.__wrap_point_alignment_count);
	    next.__items = this.__items.slice(this.__wrap_point_index);
	    this.__items = this.__items.slice(0, this.__wrap_point_index);

	    next.__character_count += this.__character_count - this.__wrap_point_character_count;
	    this.__character_count = this.__wrap_point_character_count;

	    if (next.__items[0] === " ") {
	      next.__items.splice(0, 1);
	      next.__character_count -= 1;
	    }
	    return true;
	  }
	  return false;
	};

	OutputLine.prototype.is_empty = function() {
	  return this.__items.length === 0;
	};

	OutputLine.prototype.last = function() {
	  if (!this.is_empty()) {
	    return this.__items[this.__items.length - 1];
	  } else {
	    return null;
	  }
	};

	OutputLine.prototype.push = function(item) {
	  this.__items.push(item);
	  var last_newline_index = item.lastIndexOf('\n');
	  if (last_newline_index !== -1) {
	    this.__character_count = item.length - last_newline_index;
	  } else {
	    this.__character_count += item.length;
	  }
	};

	OutputLine.prototype.pop = function() {
	  var item = null;
	  if (!this.is_empty()) {
	    item = this.__items.pop();
	    this.__character_count -= item.length;
	  }
	  return item;
	};


	OutputLine.prototype._remove_indent = function() {
	  if (this.__indent_count > 0) {
	    this.__indent_count -= 1;
	    this.__character_count -= this.__parent.indent_size;
	  }
	};

	OutputLine.prototype._remove_wrap_indent = function() {
	  if (this.__wrap_point_indent_count > 0) {
	    this.__wrap_point_indent_count -= 1;
	  }
	};
	OutputLine.prototype.trim = function() {
	  while (this.last() === ' ') {
	    this.__items.pop();
	    this.__character_count -= 1;
	  }
	};

	OutputLine.prototype.toString = function() {
	  var result = '';
	  if (this.is_empty()) {
	    if (this.__parent.indent_empty_lines) {
	      result = this.__parent.get_indent_string(this.__indent_count);
	    }
	  } else {
	    result = this.__parent.get_indent_string(this.__indent_count, this.__alignment_count);
	    result += this.__items.join('');
	  }
	  return result;
	};

	function IndentStringCache(options, baseIndentString) {
	  this.__cache = [''];
	  this.__indent_size = options.indent_size;
	  this.__indent_string = options.indent_char;
	  if (!options.indent_with_tabs) {
	    this.__indent_string = new Array(options.indent_size + 1).join(options.indent_char);
	  }

	  // Set to null to continue support for auto detection of base indent
	  baseIndentString = baseIndentString || '';
	  if (options.indent_level > 0) {
	    baseIndentString = new Array(options.indent_level + 1).join(this.__indent_string);
	  }

	  this.__base_string = baseIndentString;
	  this.__base_string_length = baseIndentString.length;
	}

	IndentStringCache.prototype.get_indent_size = function(indent, column) {
	  var result = this.__base_string_length;
	  column = column || 0;
	  if (indent < 0) {
	    result = 0;
	  }
	  result += indent * this.__indent_size;
	  result += column;
	  return result;
	};

	IndentStringCache.prototype.get_indent_string = function(indent_level, column) {
	  var result = this.__base_string;
	  column = column || 0;
	  if (indent_level < 0) {
	    indent_level = 0;
	    result = '';
	  }
	  column += indent_level * this.__indent_size;
	  this.__ensure_cache(column);
	  result += this.__cache[column];
	  return result;
	};

	IndentStringCache.prototype.__ensure_cache = function(column) {
	  while (column >= this.__cache.length) {
	    this.__add_column();
	  }
	};

	IndentStringCache.prototype.__add_column = function() {
	  var column = this.__cache.length;
	  var indent = 0;
	  var result = '';
	  if (this.__indent_size && column >= this.__indent_size) {
	    indent = Math.floor(column / this.__indent_size);
	    column -= indent * this.__indent_size;
	    result = new Array(indent + 1).join(this.__indent_string);
	  }
	  if (column) {
	    result += new Array(column + 1).join(' ');
	  }

	  this.__cache.push(result);
	};

	function Output(options, baseIndentString) {
	  this.__indent_cache = new IndentStringCache(options, baseIndentString);
	  this.raw = false;
	  this._end_with_newline = options.end_with_newline;
	  this.indent_size = options.indent_size;
	  this.wrap_line_length = options.wrap_line_length;
	  this.indent_empty_lines = options.indent_empty_lines;
	  this.__lines = [];
	  this.previous_line = null;
	  this.current_line = null;
	  this.next_line = new OutputLine(this);
	  this.space_before_token = false;
	  this.non_breaking_space = false;
	  this.previous_token_wrapped = false;
	  // initialize
	  this.__add_outputline();
	}

	Output.prototype.__add_outputline = function() {
	  this.previous_line = this.current_line;
	  this.current_line = this.next_line.clone_empty();
	  this.__lines.push(this.current_line);
	};

	Output.prototype.get_line_number = function() {
	  return this.__lines.length;
	};

	Output.prototype.get_indent_string = function(indent, column) {
	  return this.__indent_cache.get_indent_string(indent, column);
	};

	Output.prototype.get_indent_size = function(indent, column) {
	  return this.__indent_cache.get_indent_size(indent, column);
	};

	Output.prototype.is_empty = function() {
	  return !this.previous_line && this.current_line.is_empty();
	};

	Output.prototype.add_new_line = function(force_newline) {
	  // never newline at the start of file
	  // otherwise, newline only if we didn't just add one or we're forced
	  if (this.is_empty() ||
	    (!force_newline && this.just_added_newline())) {
	    return false;
	  }

	  // if raw output is enabled, don't print additional newlines,
	  // but still return True as though you had
	  if (!this.raw) {
	    this.__add_outputline();
	  }
	  return true;
	};

	Output.prototype.get_code = function(eol) {
	  this.trim(true);

	  // handle some edge cases where the last tokens
	  // has text that ends with newline(s)
	  var last_item = this.current_line.pop();
	  if (last_item) {
	    if (last_item[last_item.length - 1] === '\n') {
	      last_item = last_item.replace(/\n+$/g, '');
	    }
	    this.current_line.push(last_item);
	  }

	  if (this._end_with_newline) {
	    this.__add_outputline();
	  }

	  var sweet_code = this.__lines.join('\n');

	  if (eol !== '\n') {
	    sweet_code = sweet_code.replace(/[\n]/g, eol);
	  }
	  return sweet_code;
	};

	Output.prototype.set_wrap_point = function() {
	  this.current_line._set_wrap_point();
	};

	Output.prototype.set_indent = function(indent, alignment) {
	  indent = indent || 0;
	  alignment = alignment || 0;

	  // Next line stores alignment values
	  this.next_line.set_indent(indent, alignment);

	  // Never indent your first output indent at the start of the file
	  if (this.__lines.length > 1) {
	    this.current_line.set_indent(indent, alignment);
	    return true;
	  }

	  this.current_line.set_indent();
	  return false;
	};

	Output.prototype.add_raw_token = function(token) {
	  for (var x = 0; x < token.newlines; x++) {
	    this.__add_outputline();
	  }
	  this.current_line.set_indent(-1);
	  this.current_line.push(token.whitespace_before);
	  this.current_line.push(token.text);
	  this.space_before_token = false;
	  this.non_breaking_space = false;
	  this.previous_token_wrapped = false;
	};

	Output.prototype.add_token = function(printable_token) {
	  this.__add_space_before_token();
	  this.current_line.push(printable_token);
	  this.space_before_token = false;
	  this.non_breaking_space = false;
	  this.previous_token_wrapped = this.current_line._allow_wrap();
	};

	Output.prototype.__add_space_before_token = function() {
	  if (this.space_before_token && !this.just_added_newline()) {
	    if (!this.non_breaking_space) {
	      this.set_wrap_point();
	    }
	    this.current_line.push(' ');
	  }
	};

	Output.prototype.remove_indent = function(index) {
	  var output_length = this.__lines.length;
	  while (index < output_length) {
	    this.__lines[index]._remove_indent();
	    index++;
	  }
	  this.current_line._remove_wrap_indent();
	};

	Output.prototype.trim = function(eat_newlines) {
	  eat_newlines = (eat_newlines === undefined) ? false : eat_newlines;

	  this.current_line.trim();

	  while (eat_newlines && this.__lines.length > 1 &&
	    this.current_line.is_empty()) {
	    this.__lines.pop();
	    this.current_line = this.__lines[this.__lines.length - 1];
	    this.current_line.trim();
	  }

	  this.previous_line = this.__lines.length > 1 ?
	    this.__lines[this.__lines.length - 2] : null;
	};

	Output.prototype.just_added_newline = function() {
	  return this.current_line.is_empty();
	};

	Output.prototype.just_added_blankline = function() {
	  return this.is_empty() ||
	    (this.current_line.is_empty() && this.previous_line.is_empty());
	};

	Output.prototype.ensure_empty_line_above = function(starts_with, ends_with) {
	  var index = this.__lines.length - 2;
	  while (index >= 0) {
	    var potentialEmptyLine = this.__lines[index];
	    if (potentialEmptyLine.is_empty()) {
	      break;
	    } else if (potentialEmptyLine.item(0).indexOf(starts_with) !== 0 &&
	      potentialEmptyLine.item(-1) !== ends_with) {
	      this.__lines.splice(index + 1, 0, new OutputLine(this));
	      this.previous_line = this.__lines[this.__lines.length - 2];
	      break;
	    }
	    index--;
	  }
	};

	output.Output = Output;
	return output;
}

export { requireOutput as __require };
//# sourceMappingURL=output.js.map
