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    
020    package org.crsh.text.ui;
021    
022    import org.crsh.text.Chunk;
023    import org.crsh.text.Renderer;
024    import org.crsh.text.Style;
025    import org.crsh.text.Text;
026    import org.crsh.util.Utils;
027    
028    import java.util.Iterator;
029    
030    public 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 Renderer 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    }