text: // Generated by CoffeeScript 1.7.1
  (function() {
    var EventEmitter, LineBreaker, LineWrapper,
      __hasProp = {}.hasOwnProperty,
      __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
  
    EventEmitter = require('events').EventEmitter;
  
    LineBreaker = require('linebreak');
  
    LineWrapper = (function(_super) {
      __extends(LineWrapper, _super);
  
      function LineWrapper(document, options) {
        var _ref;
        this.document = document;
        this.indent = options.indent || 0;
        this.charSpacing = options.characterSpacing || 0;
        this.wordSpacing = options.wordSpacing === 0;
        this.columns = options.columns || 1;
        this.columnGap = (_ref = options.columnGap) != null ? _ref : 18;
        this.lineWidth = (options.width - (this.columnGap * (this.columns - 1))) / this.columns;
        this.startX = this.document.x;
        this.startY = this.document.y;
        this.column = 1;
        this.ellipsis = options.ellipsis;
        this.continuedX = 0;
        if (options.height != null) {
          this.height = options.height;
          this.maxY = this.startY + options.height;
        } else {
          this.maxY = this.document.page.maxY();
        }
        this.on('firstLine', (function(_this) {
          return function(options) {
            var indent;
            indent = _this.continuedX || _this.indent;
            _this.document.x += indent;
            _this.lineWidth -= indent;
            return _this.once('line', function() {
              _this.document.x -= indent;
              _this.lineWidth += indent;
              if (!options.continued) {
                return _this.continuedX = 0;
              }
            });
          };
        })(this));
        this.on('lastLine', (function(_this) {
          return function(options) {
            var align;
            align = options.align;
            if (align === 'justify') {
              options.align = 'left';
            }
            _this.lastLine = true;
            return _this.once('line', function() {
              _this.document.y += options.paragraphGap || 0;
              options.align = align;
              return _this.lastLine = false;
            });
          };
        })(this));
      }
  
      LineWrapper.prototype.wordWidth = function(word) {
        return this.document.widthOfString(word, this) + this.charSpacing + this.wordSpacing;
      };
  
      LineWrapper.prototype.eachWord = function(text, fn) {
        var bk, breaker, fbk, l, last, lbk, shouldContinue, w, word, wordWidths;
        breaker = new LineBreaker(text);
        last = null;
        wordWidths = {};
        while (bk = breaker.nextBreak()) {
          word = text.slice((last != null ? last.position : void 0) || 0, bk.position);
          w = wordWidths[word] != null ? wordWidths[word] : wordWidths[word] = this.wordWidth(word);
          if (w > this.lineWidth) {
            lbk = last;
            fbk = {};
            while (word.length) {
              l = word.length;
              while (w > this.spaceLeft) {
                w = this.wordWidth(word.slice(0, --l));
              }
              fbk.required = l < word.length;
              shouldContinue = fn(word.slice(0, l), w, fbk, lbk);
              lbk = {
                required: false
              };
              word = word.slice(l);
              w = this.wordWidth(word);
              if (shouldContinue === false) {
                break;
              }
            }
          } else {
            shouldContinue = fn(word, w, bk, last);
          }
          if (shouldContinue === false) {
            break;
          }
          last = bk;
        }
      };
  
      LineWrapper.prototype.wrap = function(text, options) {
        var buffer, emitLine, lc, nextY, textWidth, wc, y;
        if (options.indent != null) {
          this.indent = options.indent;
        }
        if (options.characterSpacing != null) {
          this.charSpacing = options.characterSpacing;
        }
        if (options.wordSpacing != null) {
          this.wordSpacing = options.wordSpacing;
        }
        if (options.ellipsis != null) {
          this.ellipsis = options.ellipsis;
        }
        nextY = this.document.y + this.document.currentLineHeight(true);
        if (this.document.y > this.maxY || nextY > this.maxY) {
          this.nextSection();
        }
        buffer = '';
        textWidth = 0;
        wc = 0;
        lc = 0;
        y = this.document.y;
        emitLine = (function(_this) {
          return function() {
            options.textWidth = textWidth + _this.wordSpacing * (wc - 1);
            options.wordCount = wc;
            options.lineWidth = _this.lineWidth;
            y = _this.document.y;
            _this.emit('line', buffer, options, _this);
            return lc++;
          };
        })(this);
        this.emit('sectionStart', options, this);
        this.eachWord(text, (function(_this) {
          return function(word, w, bk, last) {
            var lh, shouldContinue;
            if ((last == null) || last.required) {
              _this.emit('firstLine', options, _this);
              _this.spaceLeft = _this.lineWidth;
            }
            if (w <= _this.spaceLeft) {
              buffer += word;
              textWidth += w;
              wc++;
            }
            if (bk.required || w > _this.spaceLeft) {
              if (bk.required) {
                _this.emit('lastLine', options, _this);
              }
              lh = _this.document.currentLineHeight(true);
              if ((_this.height != null) && _this.ellipsis && _this.document.y + lh * 2 > _this.maxY && _this.column >= _this.columns) {
                if (_this.ellipsis === true) {
                  _this.ellipsis = '…';
                }
                buffer = buffer.replace(/\s+$/, '');
                textWidth = _this.wordWidth(buffer + _this.ellipsis);
                while (textWidth > _this.lineWidth) {
                  buffer = buffer.slice(0, -1).replace(/\s+$/, '');
                  textWidth = _this.wordWidth(buffer + _this.ellipsis);
                }
                buffer = buffer + _this.ellipsis;
              }
              emitLine();
              if (_this.document.y + lh > _this.maxY) {
                shouldContinue = _this.nextSection();
                if (!shouldContinue) {
                  wc = 0;
                  buffer = '';
                  return false;
                }
              }
              if (bk.required) {
                if (w > _this.spaceLeft) {
                  buffer = word;
                  textWidth = w;
                  wc = 1;
                  emitLine();
                }
                _this.spaceLeft = _this.lineWidth;
                buffer = '';
                textWidth = 0;
                return wc = 0;
              } else {
                _this.spaceLeft = _this.lineWidth - w;
                buffer = word;
                textWidth = w;
                return wc = 1;
              }
            } else {
              return _this.spaceLeft -= w;
            }
          };
        })(this));
        if (wc > 0) {
          this.emit('lastLine', options, this);
          emitLine();
        }
        this.emit('sectionEnd', options, this);
        if (options.continued === true) {
          if (lc > 1) {
            this.continuedX = 0;
          }
          this.continuedX += options.textWidth;
          return this.document.y = y;
        } else {
          return this.document.x = this.startX;
        }
      };
  
      LineWrapper.prototype.nextSection = function(options) {
        var _ref;
        this.emit('sectionEnd', options, this);
        if (++this.column > this.columns) {
          if (this.height != null) {
            return false;
          }
          this.document.addPage();
          this.column = 1;
          this.startY = this.document.page.margins.top;
          this.maxY = this.document.page.maxY();
          this.document.x = this.startX;
          if (this.document._fillColor) {
            (_ref = this.document).fillColor.apply(_ref, this.document._fillColor);
          }
          this.emit('pageBreak', options, this);
        } else {
          this.document.x += this.lineWidth + this.columnGap;
          this.document.y = this.startY;
          this.emit('columnBreak', options, this);
        }
        this.emit('sectionStart', options, this);
        return true;
      };
  
      return LineWrapper;
  
    })(EventEmitter);
  
    module.exports = LineWrapper;
  
  }).call(this);
  