/// <summary>Style the tag for a particular channel this style</summary>
 /// <param name="channel">The channel to style</param>
 /// <param name="style">The style to use</param>
 public virtual void StyleChannel(string channel, Edu.Stanford.Nlp.Util.Logging.Style style)
 {
     if (this.channelStyles == null)
     {
         this.channelStyles = Generics.NewHashMap();
     }
     this.channelStyles[channel.ToLower(Locale.English)] = style;
 }
 /// <summary>Format a channel</summary>
 /// <param name="b">The StringBuilder to append to</param>
 /// <param name="channelStr">
 /// The [possibly truncated and/or modified] string
 /// to actually print to the StringBuilder
 /// </param>
 /// <param name="channel">The original channel</param>
 /// <returns>|true| if the channel was printed (that is, appended to the StringBuilder)</returns>
 protected internal virtual bool FormatChannel(StringBuilder b, string channelStr, object channel)
 {
     if (this.channelColors == null && this.channelStyles == null)
     {
         //(regular concat)
         b.Append(channelStr);
     }
     else
     {
         string channelToString = channel.ToString().ToLower(Locale.English);
         //(default: no style)
         Color color = Color.None;
         Edu.Stanford.Nlp.Util.Logging.Style style = Edu.Stanford.Nlp.Util.Logging.Style.None;
         //(get color)
         if (this.channelColors != null)
         {
             Color candColor = this.channelColors[channelToString];
             if (candColor != null)
             {
                 //((case: found a color))
                 color = candColor;
             }
             else
             {
                 if (addRandomColors)
                 {
                     //((case: random colors))
                     color = Color.Values()[SloppyMath.PythonMod(channelToString.GetHashCode(), (Color.Values().Length - 3)) + 3];
                     if (channelToString.Equals(Redwood.Err.ToString().ToLower()))
                     {
                         color = Color.Red;
                     }
                     else
                     {
                         if (channelToString.Equals(Redwood.Warn.ToString().ToLower()))
                         {
                             color = Color.Yellow;
                         }
                     }
                     this.channelColors[channelToString] = color;
                 }
             }
         }
         //(get style)
         if (this.channelStyles != null)
         {
             Edu.Stanford.Nlp.Util.Logging.Style candStyle = this.channelStyles[channelToString];
             if (candStyle != null)
             {
                 style = candStyle;
             }
         }
         //(format)
         Style(b, channelStr, color, style);
     }
     return(true);
 }
        /// <summary>
        /// <inheritDoc/>
        ///
        /// </summary>
        public override IList <Redwood.Record> Handle(Redwood.Record record)
        {
            StringBuilder b = new StringBuilder(1024);

            //--Special case for Exceptions
            string[] content;
            if (record.content is Exception)
            {
                //(vars)
                IList <string> lines = new List <string>();
                //(root message)
                Exception exception = (Exception)record.content;
                lines.Add(record.content.ToString());
                StackTraceElement[] trace           = exception.GetStackTrace();
                StackTraceElement   topTraceElement = trace.Length > 0 ? trace[0] : null;
                foreach (StackTraceElement e in exception.GetStackTrace())
                {
                    lines.Add(tab + e.ToString());
                }
                //(causes)
                while (exception.InnerException != null)
                {
                    System.Console.Out.WriteLine("TOP ELEMENT: " + topTraceElement);
                    //((variables))
                    exception = exception.InnerException;
                    trace     = exception.GetStackTrace();
                    lines.Add("Caused by: " + exception.GetType() + ": " + exception.Message);
                    for (int i = 0; i < trace.Length; i++)
                    {
                        //((add trace element))
                        StackTraceElement e_1 = trace[i];
                        lines.Add(tab + e_1.ToString());
                        //((don't print redundant elements))
                        if (topTraceElement != null && e_1.GetClassName().Equals(topTraceElement.GetClassName()) && e_1.GetMethodName().Equals(topTraceElement.GetMethodName()))
                        {
                            lines.Add(tab + "..." + (trace.Length - i - 1) + " more");
                            break;
                        }
                    }
                    //((update top element))
                    topTraceElement = trace.Length > 0 ? trace[0] : null;
                }
                //(set content array)
                content = new string[lines.Count];
                content = Sharpen.Collections.ToArray(lines, content);
            }
            else
            {
                if (record.content == null)
                {
                    content = new string[] { "null" };
                }
                else
                {
                    string toStr;
                    if (record.content is ISupplier)
                    {
                        //noinspection unchecked
                        toStr = ((ISupplier <object>)record.content).Get().ToString();
                    }
                    else
                    {
                        toStr = record.content.ToString();
                    }
                    if (toStr == null)
                    {
                        content = new string[] { "<null toString()>" };
                    }
                    else
                    {
                        content = toStr.Split("\n");
                    }
                }
            }
            //would be nice to get rid of this 'split()' call at some point
            //--Handle Tracks
            UpdateTracks(record.depth);
            if (this.missingOpenBracket)
            {
                this.Style(b, "{\n", trackColor, trackStyle);
                this.missingOpenBracket = false;
            }
            //--Process Record
            //(variables)
            int cursorPos           = 0;
            int contentLinesPrinted = 0;
            //(loop)
            Color color = Color.None;

            Edu.Stanford.Nlp.Util.Logging.Style style = Edu.Stanford.Nlp.Util.Logging.Style.None;
            //(get channels)
            List <object> printableChannels = new List <object>();

            foreach (object chan in record.Channels())
            {
                if (chan is Color)
                {
                    color = (Color)chan;
                }
                else
                {
                    if (chan is Edu.Stanford.Nlp.Util.Logging.Style)
                    {
                        style = (Edu.Stanford.Nlp.Util.Logging.Style)chan;
                    }
                    else
                    {
                        if (chan != Redwood.Force)
                        {
                            printableChannels.Add(chan);
                        }
                    }
                }
            }
            //--Write Channels
            if (leftMargin > 2)
            {
                //don't print if not enough space
                //((print channels)
                b.Append("[");
                cursorPos += 1;
                object lastChan             = null;
                bool   wasAnyChannelPrinted = false;
                for (int i = 0; i < printableChannels.Count; i++)
                {
                    object chan_1 = printableChannels[i];
                    if (chan_1.Equals(lastChan))
                    {
                        continue;
                    }
                    //skip duplicate channels
                    lastChan = chan_1;
                    //(get channel)
                    string toPrint = chan_1.ToString();
                    if (toPrint.Length > leftMargin - 1)
                    {
                        toPrint = Sharpen.Runtime.Substring(toPrint, 0, leftMargin - 2);
                    }
                    if (cursorPos + toPrint.Length >= leftMargin)
                    {
                        //(case: doesn't fit)
                        while (cursorPos < leftMargin)
                        {
                            b.Append(" ");
                            cursorPos += 1;
                        }
                        if (contentLinesPrinted < content.Length)
                        {
                            WriteContent(record.depth, Style(new StringBuilder(), content[contentLinesPrinted], color, style).ToString(), b);
                            contentLinesPrinted += 1;
                        }
                        b.Append("\n ");
                        cursorPos = 1;
                    }
                    //(print flag)
                    bool wasChannelPrinted = FormatChannel(b, toPrint, chan_1);
                    wasAnyChannelPrinted = wasAnyChannelPrinted || wasChannelPrinted;
                    if (wasChannelPrinted && i < printableChannels.Count - 1)
                    {
                        b.Append(channelSeparatorChar);
                        cursorPos += 1;
                    }
                    cursorPos += toPrint.Length;
                }
                if (wasAnyChannelPrinted)
                {
                    b.Append("]");
                    cursorPos += 1;
                }
                else
                {
                    b.Length = b.Length - 1;
                    // remove leading "["
                    cursorPos -= 1;
                }
            }
            //--Content
            //(write content)
            while (contentLinesPrinted < content.Length)
            {
                while (cursorPos < leftMargin)
                {
                    b.Append(" ");
                    cursorPos += 1;
                }
                WriteContent(record.depth, Style(new StringBuilder(), content[contentLinesPrinted], color, style).ToString(), b);
                contentLinesPrinted += 1;
                if (contentLinesPrinted < content.Length)
                {
                    b.Append("\n");
                    cursorPos = 0;
                }
            }
            //(print)
            if (b.Length == 0 || b[b.Length - 1] != '\n')
            {
                b.Append("\n");
            }
            Print(record.Channels(), b.ToString());
            //--Continue
            if (info != null)
            {
                info.numElementsPrinted += 1;
            }
            List <Redwood.Record> rtn = new List <Redwood.Record>();

            rtn.Add(record);
            return(rtn);
        }
 /// <summary>Style a particular String segment, according to a color and style</summary>
 /// <param name="b">The string builder to append to (for efficiency)</param>
 /// <param name="line">The String to be wrapped</param>
 /// <param name="color">The color to color as</param>
 /// <param name="style">The style to use</param>
 /// <returns>The SringBuilder b</returns>
 protected internal virtual StringBuilder Style(StringBuilder b, string line, Color color, Edu.Stanford.Nlp.Util.Logging.Style style)
 {
     if (color != Color.None || style != Edu.Stanford.Nlp.Util.Logging.Style.None)
     {
         if (Redwood.supportsAnsi && this.SupportsAnsi())
         {
             b.Append(color.ansiCode);
             b.Append(style.ansiCode);
         }
         b.Append(line);
         if (Redwood.supportsAnsi && this.SupportsAnsi())
         {
             b.Append("\x21[0m");
         }
     }
     else
     {
         b.Append(line);
     }
     return(b);
 }