using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Globalization;
using CommonLang.Xml;
using System.Xml;

namespace CommonLang.IO
{


    public class TextOutputStream : IOutputStream
    {
        private StringWriter output;
        public TextOutputStream(StringWriter output, IExternalizableFactory factory = null)
            : base(factory)
        {
            this.output = output;
        }

        private void PutNext(Object src)
        {
            output.Write(src + ",");
        }

        public override long GetBuffPos()
        {
            return 0;
        }

        public override void PutUTF(String str)
        {
            if (string.IsNullOrEmpty(str))
            {
                output.Write("0,,");
            }
            else
            {
                output.Write(str.Length + ",");
                output.Write(str + ",");
            }
        }

        public override void PutS8(sbyte value)
        {
            PutNext(value);
        }

        public override void PutU8(byte value)
        {
            PutNext(value);
        }

        public override void PutBool(bool value)
        {
            PutNext(value);
        }

        public override void PutS16(short value)
        {
            PutNext(value);
        }

        public override void PutU16(ushort value)
        {
            PutNext(value);
        }

        public override void PutS32(int value)
        {
            PutNext(value);
        }

        public override void PutU32(uint value)
        {
            PutNext(value);
        }

        public override void PutS64(long value)
        {
            PutNext(value);
        }

        public override void PutU64(ulong value)
        {
            PutNext(value);
        }

        public override void PutF32(float value)
        {
            PutNext(value);
        }

        public override void PutF64(double value)
        {
            PutNext(value);
        }

        public override void PutUnicode(char value)
        {
            PutNext(value);
        }

        public override void PutBytes(byte[] bytes)
        {
            PutS32(bytes.Length);
            if (bytes != null && bytes.Length > 0)
            {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < bytes.Length; i++)
                {
                    sb.Append(bytes[i].ToString());
                    if (i < bytes.Length - 1)
                    {
                        sb.Append(',');
                    }
                }
                PutUTF(sb.ToString());
            }
        }

        public override void PutRawData(byte[] bytes, int offset, int count)
        {
            throw new NotImplementedException();
        }
    }


    public class TextInputStream : IInputStream
    {
        private StringReader input;
        public TextInputStream(StringReader input, IExternalizableFactory factory = null)
            : base(factory)
        {
            this.input = input;
        }


        private String GetNext()
        {
            StringBuilder sb = new StringBuilder();
            while (true)
            {
                int r = input.Read();
                if (r == -1)
                    break;
                if (r == ',')
                    break;
                sb.Append((char)r);
            }
            return sb.ToString();


        }

        public override String GetUTF()
        {
            int stringLen = GetS32();
            char[] chars = new char[stringLen];
            input.Read(chars, 0, stringLen);
            if (input.Read() != ',')
            {
                //System.err.println("bat ending for : " + in);
            }
            return new String(chars);
        }

        public override sbyte GetS8()
        {
            return sbyte.Parse(GetNext());
        }

        public override byte GetU8()
        {
            return byte.Parse(GetNext());
        }

        public override bool GetBool()
        {
            String read = GetNext();
            try
            {
                return bool.Parse(read);
            }
            catch (Exception err)
            {
				Console.WriteLine("GetBool 1: " + read + ", catch: " + err);
				return Byte.Parse(read) != 0;
            }
        }

        public override short GetS16()
        {
            return short.Parse(GetNext());
        }

        public override ushort GetU16()
        {
            return ushort.Parse(GetNext());

        }

        public override int GetS32()
        {
            return int.Parse(GetNext());
        }

        public override uint GetU32()
        {
            return uint.Parse(GetNext());
        }

        public override long GetS64()
        {
            return long.Parse(GetNext(), System.Globalization.CultureInfo.InvariantCulture);
        }

        public override ulong GetU64()
        {
            return ulong.Parse(GetNext());
        }

        public override float GetF32()
        {
            return float.Parse(GetNext(), System.Globalization.CultureInfo.InvariantCulture);
        }

        public override double GetF64()
        {
            return double.Parse(GetNext(), System.Globalization.CultureInfo.InvariantCulture);
        }

        public override char GetUnicode()
        {
            return char.Parse(GetNext());
        }

        public override byte[] GetBytes()
        {
            int count = GetS32();
            byte[] ret = new byte[count];
            string utf = GetUTF();
            string[] utfs = utf.Split(',');
            for (int i = 0; i < utfs.Length; i++)
            {
                ret[i] = byte.Parse(utfs[i]);
            }
            return ret;
        }

        public override void GetRawData(byte[] buff, int offset, int count)
        {
            throw new NotImplementedException();
        }
    }


}