/*
 * [The "BSD licence"]
 * Copyright (c) 2005-2008 Terence Parr
 * All rights reserved.
 *
 * Conversion to C#:
 * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

namespace Antlr.Runtime {
    using NonSerialized = System.NonSerializedAttribute;
    using Regex = System.Text.RegularExpressions.Regex;
    using Serializable = System.SerializableAttribute;

    [Serializable]
    public class CommonToken : IToken {
        int type;
        int line;
        int charPositionInLine = -1; // set to invalid position
        int channel = TokenChannels.Default;
        [NonSerialized]
        ICharStream input;

        /** <summary>
         *  We need to be able to change the text once in a while.  If
         *  this is non-null, then getText should return this.  Note that
         *  start/stop are not affected by changing this.
         *  </summary>
          */
        string text;

        /** <summary>What token number is this from 0..n-1 tokens; &lt; 0 implies invalid index</summary> */
        int index = -1;

        /** <summary>The char position into the input buffer where this token starts</summary> */
        int start;

        /** <summary>The char position into the input buffer where this token stops</summary> */
        int stop;

        public CommonToken() {
        }

        public CommonToken(int type) {
            this.type = type;
        }

        public CommonToken(ICharStream input, int type, int channel, int start, int stop) {
            this.input = input;
            this.type = type;
            this.channel = channel;
            this.start = start;
            this.stop = stop;
        }

        public CommonToken(int type, string text) {
            this.type = type;
            this.channel = TokenChannels.Default;
            this.text = text;
        }

        public CommonToken(IToken oldToken) {
            text = oldToken.Text;
            type = oldToken.Type;
            line = oldToken.Line;
            index = oldToken.TokenIndex;
            charPositionInLine = oldToken.CharPositionInLine;
            channel = oldToken.Channel;
            input = oldToken.InputStream;
            if (oldToken is CommonToken) {
                start = ((CommonToken)oldToken).start;
                stop = ((CommonToken)oldToken).stop;
            }
        }

        #region IToken Members
        public string Text {
            get {
                if (text != null)
                    return text;
                if (input == null)
                    return null;

                if (start < input.Count && stop < input.Count)
                    text = input.Substring(start, stop - start + 1);
                else
                    text = "<EOF>";

                return text;
            }
            set {
                /** Override the text for this token.  getText() will return this text
                 *  rather than pulling from the buffer.  Note that this does not mean
                 *  that start/stop indexes are not valid.  It means that that input
                 *  was converted to a new string in the token object.
                 */
                text = value;
            }
        }

        public int Type {
            get {
                return type;
            }
            set {
                type = value;
            }
        }

        public int Line {
            get {
                return line;
            }
            set {
                line = value;
            }
        }

        public int CharPositionInLine {
            get {
                return charPositionInLine;
            }
            set {
                charPositionInLine = value;
            }
        }

        public int Channel {
            get {
                return channel;
            }
            set {
                channel = value;
            }
        }

        public int StartIndex {
            get {
                return start;
            }
            set {
                start = value;
            }
        }

        public int StopIndex {
            get {
                return stop;
            }
            set {
                stop = value;
            }
        }

        public int TokenIndex {
            get {
                return index;
            }
            set {
                index = value;
            }
        }

        public ICharStream InputStream {
            get {
                return input;
            }
            set {
                input = value;
            }
        }

        #endregion

        public override string ToString() {
            string channelStr = "";
            if (channel > 0) {
                channelStr = ",channel=" + channel;
            }
            string txt = Text;
            if (txt != null) {
                txt = Regex.Replace(txt, "\n", "\\\\n");
                txt = Regex.Replace(txt, "\r", "\\\\r");
                txt = Regex.Replace(txt, "\t", "\\\\t");
            } else {
                txt = "<no text>";
            }
            return "[@" + TokenIndex + "," + start + ":" + stop + "='" + txt + "',<" + type + ">" + channelStr + "," + line + ":" + CharPositionInLine + "]";
        }

        [System.Runtime.Serialization.OnSerializing]
        internal void OnSerializing(System.Runtime.Serialization.StreamingContext context) {
            if (text == null)
                text = Text;
        }
    }
}
