using System;
using System.Collections;
using System.Collections.Generic;

using System.Text;







namespace Rokojori
{
  public class JSONObject:JSONData
  {
    List<string> _keys = new List<string>();
    List<JSONData> _values = new List<JSONData>();

    public override JSONDataType dataType 
    {
      get { return JSONDataType.OBJECT; }
    }

    public List<string> keys { get { return _keys; }}
    public List<JSONData> values { get { return _values; }}

    public int size { get { return _keys.Count; } }

    public JSONData Get( string key )     
    {
      var index = _keys.IndexOf( key );
      return index == -1 ? null : _values[ index ];  
    }

    public string GetString( string key ){ return Get( key ).stringValue; }
    public double GetNumber( string key ){ return Get( key ).numberValue; }
    public int GetInt( string key ){ return Get( key ).intValue; }
    public float GetFloat( string key ){ return Get( key ).floatValue; }
    public bool GetBoolean( string key ){ return Get( key ).booleanValue; }

    public T GetEnum<T>( string key )
    {
      var value = System.Enum.Parse( typeof( T ), GetString( key ) );
      return (T) value;
    }

    public double GetNumberOr( string key, double defaultFallback )
    {
      var index = _keys.IndexOf( key );

      if ( index != -1 )
      {
        var value = _values[ index ];
        return value.isNumber ? value.numberValue : defaultFallback;
      }

      return defaultFallback;
    }

    public bool Contains( string key )
    {
      return _keys.Contains( key );
    }

    public void Delete( string key )
    {
      var index = _keys.IndexOf( key );
      
      if ( index != -1 )
      {
        _keys.RemoveAt( index );
        _values.RemoveAt( index );
      }
    }

    public void Set( string key, JSONData value )
    {
      var index = _keys.IndexOf( key );
      
      if ( index == -1 ) 
      {
        _keys.Add( key );
        _values.Add( value );
      }
      else
      {
        _values[ index ] = value;
      }

    }

    public void Set( string key, double value ){ Set( key, new JSONValue( value ) ); } 
    public void Set( string key, string value ){ Set( key, new JSONValue( value ) ); } 
    public void Set( string key, bool value ){ Set( key, new JSONValue( value ) ); } 
    public void SetEnum<T>( string key, object value)
    {
      var stringValue = System.Enum.GetName( typeof( T ), value );
      Set( key, stringValue );
    }
   
    public override string Stringify( StringifyOptions options )
    {
      options.increaseIndent();
      var builder = new StringBuilder();

      if ( values.Count == 0 )
      {
        builder.Append( "{}" );
        options.decreaseIndent();
        return builder.ToString();
      }

      
      builder.Append( "{\n" );      

      if ( values.Count > 0 )
      {
        builder.Append( options.indent );
        JSONStringConverter.Write( builder, keys[ 0 ] );
        builder.Append( ": " );
        builder.Append( values[ 0 ].Stringify( options ) );
      }

      for ( var i = 1; i < values.Count; i++ )
      {
        builder.Append( ",\n" );
        builder.Append( options.indent );
        JSONStringConverter.Write( builder, keys[ i ] );
        builder.Append( ": " );
        builder.Append( values[ i ].Stringify( options ) );
      }

      options.decreaseIndent();
      builder.Append( "\n" );
      builder.Append( options.indent );
      builder.Append( "}" );
      
      

      return builder.ToString();
    }


  }
}