code: /**
   * Copyright 2017 Alexey Ragozin
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package org.gridkit.util.formating;
  
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.List;
  import java.util.TimeZone;
  
  public class AsciiTableFormatter implements TableFormatter, TabularDataSink {
  
      protected TextTable textTable = new TextTable();
      protected List<String> header = new ArrayList<String>();
      protected List<String> displayHeader = new ArrayList<String>();
      protected List<NumberFormat> numberFormat = new ArrayList<NumberFormat>();
      protected TimeZone timeZone;
  
      public AsciiTableFormatter() {
          this(TimeZone.getDefault());
      }
  
      public AsciiTableFormatter(TimeZone timeZone) {
          this.timeZone = timeZone;
      }
  
      @Override
      public void addCol(String name) {
          header.add(name);
          displayHeader.add(name);
          numberFormat.add(SimpleNumberFormatter.DEFAULT);
      }
  
      @Override
      public void addCol(String name, String displayName) {
          header.add(name);
          displayHeader.add(displayName);
          numberFormat.add(SimpleNumberFormatter.DEFAULT);
      }
  
      @Override
      public void addCol(String name, String displayName, String format) {
          header.add(name);
          displayHeader.add(displayName);
          numberFormat.add(new SimpleNumberFormatter(format, timeZone));
      }
  
      protected String formatDouble(String name, double v) {
          return numberFormat.get(header.indexOf(name)).formatDouble(v);
      }
  
      protected String formatLong(String name, long v) {
          return numberFormat.get(header.indexOf(name)).formatLong(v);
      }
  
      @Override
      public int colByName(String name) {
          return header.indexOf(name);
      }
  
      public String format() {
          return textTable.formatTextTable(512);
      }
  
      @Override
      public void format(Appendable out) throws IOException {
          out.append(format());
      }
  
      @Override
      public void sort(String colId, boolean desc) {
          textTable.sort(colByName(colId), true, desc, null);
      }
  
      @Override
      public void sortNumeric(String colId, boolean desc) {
          textTable.sort(colByName(colId), true, desc, TextTable.NUM_CMP);
      }
  
      @Override
      public void close() {
          // do nothing
      }
  
      protected void addRow(String[] row) {
          if (textTable.rowCount() == 0) {
              textTable.addRow(displayHeader.toArray(new String[0]));
          }
          textTable.addRow(row);
      }
  
      @Override
      public Cursor newCursor() {
          return new Cursor() {
  
              final String[] row = new String[header.size()];
              {
                  clear();
              }
  
              @Override
              public void submit() {
                  addRow(row);
                  clear();
              }
  
              private void clear() {
                  Arrays.fill(row, "");
              }
  
              @Override
              public void setCell(int colNo, double value) {
                  if (colNo >= 0) {
                      row[colNo] = formatDouble(header.get(colNo), value);
                  }
              }
  
              @Override
              public void setCell(int colNo, long value) {
                  if (colNo >= 0) {
                      row[colNo] = formatLong(header.get(colNo), value);
                  }
              }
  
              @Override
              public void setCell(int colNo, String value) {
                  if (colNo >= 0) {
                      row[colNo] = value;
                  }
              }
  
              @Override
              public void setCell(String name, double value) {
                  setCell(colByName(name), value);
              }
  
              @Override
              public void setCell(String name, long value) {
                  setCell(colByName(name), value);
              }
  
              @Override
              public void setCell(String name, String value) {
                  setCell(colByName(name), value);
              }
          };
      }
  }
  