001    package org.crsh.text;
002    
003    import org.crsh.util.Safe;
004    import org.crsh.util.Utils;
005    
006    import java.io.IOException;
007    import java.io.Serializable;
008    
009    /**
010     * @author <a href="mailto:alain.defrance@exoplatform.com">Alain Defrance</a>
011     */
012    public abstract class Style implements Serializable {
013    
014      public static final Style reset = new Style(null, null, null) {
015        @Override
016        public void writeAnsiTo(Appendable appendable) throws IOException {
017          appendable.append("\033[0m");
018        }
019      };
020    
021      static class Regular extends Style {
022        Regular(Decoration decoration, Color foreground, Color background) {
023          super(decoration, foreground, background);
024        }
025    
026        @Override
027        public void writeAnsiTo(Appendable appendable) throws IOException {
028          if (decoration != null|| foreground != null || background != null) {
029            appendable.append("\033[");
030            boolean appended = false;
031            if (decoration != null) {
032              appendable.append(Integer.toString(decoration.code));
033              appended = true;
034            }
035            if (foreground != null) {
036              if (appended) {
037                appendable.append(";");
038              }
039              appendable.append(Integer.toString(foreground.code(30)));
040              appended = true;
041            }
042            if (background != null) {
043              if (appended) {
044                appendable.append(";");
045              }
046              appendable.append(Integer.toString(background.code(40)));
047            }
048            appendable.append("m");
049          }
050          else {
051            //
052          }
053        }
054    
055        @Override
056        public boolean equals(Object obj) {
057          if (obj == this) {
058            return true;
059          }
060          if (obj instanceof Regular) {
061            Regular that = (Regular)obj;
062            return Safe.equals(decoration, that.decoration) &&
063                Safe.equals(foreground, that.foreground) &&
064                Safe.equals(background, that.background);
065          }
066          return false;
067        }
068      }
069    
070      public static Style style(Color foreground) {
071        return new Regular(null, foreground, null);
072      }
073    
074      public static Style style(Color foreground, Color background) {
075        return new Regular(null, foreground, background);
076      }
077    
078      public static Style style(Decoration decoration, Color foreground, Color background) {
079        return new Regular(decoration, foreground, background);
080      }
081    
082      public static Style style(Decoration decoration) {
083        return new Regular(decoration, null, null);
084      }
085    
086      public static Style style(Decoration decoration, Color foreground) {
087        return new Regular(decoration, foreground, null);
088      }
089    
090      /** . */
091      protected final Decoration decoration;
092    
093      /** . */
094      protected final Color foreground;
095    
096      /** . */
097      protected final Color background;
098    
099      private Style(Decoration decoration, Color foreground, Color background) {
100        this.decoration = decoration;
101        this.foreground = foreground;
102        this.background = background;
103      }
104    
105      public Decoration getDecoration() {
106        return decoration;
107      }
108    
109      public Color getForeground() {
110        return foreground;
111      }
112    
113      public Color getBackground() {
114        return background;
115      }
116    
117      public Style merge(Style s) throws NullPointerException {
118        if (s == null) {
119          throw new NullPointerException();
120        }
121        if (s == reset) {
122          return reset;
123        } else {
124          Decoration dec = Utils.notNull(s.decoration, decoration);
125          Color fg = Utils.notNull(s.foreground, foreground);
126          Color bg = Utils.notNull(s.background, background);
127          return new Regular(dec, fg, bg);
128        }
129      }
130    
131      public CharSequence toAnsiSequence() {
132        StringBuilder sb = new StringBuilder();
133        try {
134          writeAnsiTo(sb);
135        }
136        catch (IOException e) {
137          // Should not happen
138          throw new AssertionError(e);
139        }
140        return sb.toString();
141      }
142    
143      public abstract void writeAnsiTo(Appendable appendable) throws IOException;
144    
145      @Override
146      public String toString() {
147        return "Style[decoration=" + decoration + ",background=" + background + ",foreground=" + foreground + "]";
148      }
149    }