using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using IO;

namespace HaloPlugins
{
    public class Value : IMetaNode
    {
        object Val = 0;
        Type t;
        string Name = "Value";

        public Value(string Name, Type t)
        {
            this.Name = Name;
            this.t = t;
        }

        #region MetaNode Members

        public void Read(EndianReader br)
        {
            if (t == typeof(byte))
                Val = br.ReadByte();
            else if (t == typeof(short))
                Val = br.ReadInt16();
            else if (t == typeof(ushort))
                Val = br.ReadUInt16();
            else if (t == typeof(int))
                Val = br.ReadInt32();
            else if (t == typeof(uint))
                Val = br.ReadUInt32();
            else if (t == typeof(float))
                Val = br.ReadInt32(); // ReadSingle();
        }

        public void Read(EndianReader br, int Magic)
        {
            if (t == typeof(byte))
                Val = br.ReadByte();
            else if (t == typeof(short))
                Val = br.ReadInt16();
            else if (t == typeof(ushort))
                Val = br.ReadUInt16();
            else if (t == typeof(int))
                Val = br.ReadInt32();
            else if (t == typeof(uint))
                Val = br.ReadUInt32();
            else if (t == typeof(float))
                Val = br.ReadInt32(); // ReadSingle();
        }

        public void Write(EndianWriter bw)
        {
            if (t == typeof(byte))
                bw.Write(byte.Parse(Val.ToString()));
            else if (t == typeof(short))
                bw.Write(short.Parse(Val.ToString()));
            else if (t == typeof(ushort))
                bw.Write(ushort.Parse(Val.ToString()));
            else if (t == typeof(int))
                bw.Write(int.Parse(Val.ToString()));
            else if (t == typeof(uint))
                bw.Write(uint.Parse(Val.ToString()));
            else if (t == typeof(float))
                bw.Write(int.Parse(Val.ToString()));  //ms.bw.Write(float.Parse(Val.ToString()));
        }

        public object GetValue()
        {
            if (t == typeof(byte))
                return byte.Parse(Val.ToString());
            else if (t == typeof(short))
                return short.Parse(Val.ToString());
            else if (t == typeof(ushort))
                return ushort.Parse(Val.ToString());
            else if (t == typeof(int))
                return int.Parse(Val.ToString());
            else if (t == typeof(uint))
                return uint.Parse(Val.ToString());
            else if (t == typeof(float))
                return int.Parse(Val.ToString()); //return float.Parse(Val.ToString());
            else
                return null;
        }

        public void SetValue(object Value)
        {
            this.Val = Value;
        }

        public int GetSize()
        {
            int size = 0;

            if (t == typeof(byte))
                size = 1;
            else if (t == typeof(short) || t == typeof(ushort))
                size = 2;
            else if (t == typeof(int) || t == typeof(uint) || t == typeof(float))
                size = 4;


            return size;
        }

        public void Compile(EndianWriter bw, int Magic)
        {
            if (t == typeof(byte))
                bw.Write(byte.Parse(Val.ToString()));
            else if (t == typeof(short))
                bw.Write(short.Parse(Val.ToString()));
            else if (t == typeof(ushort))
                bw.Write(ushort.Parse(Val.ToString()));
            else if (t == typeof(int))
                bw.Write(int.Parse(Val.ToString()));
            else if (t == typeof(uint))
                bw.Write(uint.Parse(Val.ToString()));
            else if (t == typeof(float))
                bw.Write(int.Parse(Val.ToString()));  //ms.bw.Write(float.Parse(Val.ToString()));
        }

        public void Decompile(EndianWriter bw, int Magic)
        {
            if (t == typeof(byte))
                bw.Write(byte.Parse(Val.ToString()));
            else if (t == typeof(short))
                bw.Write(short.Parse(Val.ToString()));
            else if (t == typeof(ushort))
                bw.Write(ushort.Parse(Val.ToString()));
            else if (t == typeof(int))
                bw.Write(int.Parse(Val.ToString()));
            else if (t == typeof(uint))
                bw.Write(uint.Parse(Val.ToString()));
            else if (t == typeof(float))
                bw.Write(int.Parse(Val.ToString())); //ms.bw.Write(float.Parse(Val.ToString()));
        }

        public string GetName()
        {
            return Name;
        }

        #endregion

        #region ICloneable Members

        public object Clone()
        {
            Value v = new Value(this.Name, this.t);
            v.Val = this.Val;
            return v;
        }

        #endregion

        #region ToString

        public override string ToString()
        {
            return "Value: " + Name.ToString() + ", Type: " + t.ToString() + ", Value: " + Val.ToString();
        }

        #endregion
    }
}
