001/*
002 * Copyright (C) 2012 eXo Platform SAS.
003 *
004 * This is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU Lesser General Public License as
006 * published by the Free Software Foundation; either version 2.1 of
007 * the License, or (at your option) any later version.
008 *
009 * This software is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public
015 * License along with this software; if not, write to the Free
016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018 */
019
020package org.crsh.text.ui;
021
022import org.crsh.text.Chunk;
023import org.crsh.text.LineRenderer;
024import org.crsh.text.Style;
025import org.crsh.text.Text;
026import org.crsh.util.Utils;
027
028import java.util.Iterator;
029
030public class TextElement extends Element {
031
032  /** . */
033  final Iterable<Chunk> stream;
034
035  /** . */
036  final int minWidth;
037
038  /** . */
039  final int width;
040
041  private static int width(int width, Iterator<Chunk> stream, Text current, Integer from) {
042    while (current == null) {
043      if (stream.hasNext()) {
044        Chunk next = stream.next();
045        if (next instanceof Text) {
046          current = (Text)next;
047          from = 0;
048        }
049      } else {
050        break;
051      }
052    }
053    if (current == null) {
054      return width;
055    } else {
056      int pos = Utils.indexOf(current.getText(), from, '\n');
057      if (pos == -1) {
058        return width(width + current.getText().length() - from, stream, current, from);
059      } else {
060        return Math.max(width + pos - from, width(0, stream, null, 0));
061      }
062    }
063  }
064
065  public TextElement(Iterable<Chunk> stream, int minWidth) {
066    if (minWidth < 0) {
067      throw new IllegalArgumentException("No negative min size allowed");
068    }
069
070    // Determine width
071    int width = width(0, stream.iterator(), null, null);
072
073    //
074    this.minWidth = Math.min(width, minWidth);
075    this.stream = stream;
076    this.width = width;
077  }
078
079  public TextElement(Iterable<Chunk> stream) {
080    this(stream, 1);
081  }
082
083  public LineRenderer renderer() {
084    // return new LabelRenderer(this);
085    throw new UnsupportedOperationException();
086  }
087
088  @Override
089  public String toString() {
090    return "TextElement[]";
091  }
092
093  @Override
094  public TextElement style(Style.Composite style) {
095    return (TextElement)super.style(style);
096  }
097}