/*
 * Copyright 1999-2011 Alibaba Group.
 *  
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *  
 *      http://www.apache.org/licenses/LICENSE-2.0
 *  
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.dubbo.common.json;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * JSONObject.
 * 
 * @author qian.lei
 */

public class JSONObject implements JSONNode
{
	private Map<String,Object> mMap = new HashMap<String,Object>();

	/**
	 * get.
	 * 
	 * @param key key.
	 * @return boolean or long or double or String or JSONArray or JSONObject or null.
	 */
	public Object get(String key)
	{
		return mMap.get(key);
	}

	/**
	 * get boolean value.
	 * 
	 * @param key key.
	 * @param def default value.
	 * @return value or default value.
	 */
	public boolean getBoolean(String key, boolean def)
	{
		Object tmp = mMap.get(key);
		return tmp != null && tmp instanceof Boolean ? (Boolean)tmp : def;
	}

	/**
	 * get int value.
	 * 
	 * @param key key.
	 * @param def default value.
	 * @return value or default value.
	 */
	public int getInt(String key, int def)
	{
		Object tmp = mMap.get(key);
		return tmp != null && tmp instanceof Number ? ((Number)tmp).intValue() : def;
	}

	/**
	 * get long value.
	 * 
	 * @param key key.
	 * @param def default value.
	 * @return value or default value.
	 */
	public long getLong(String key, long def)
	{
		Object tmp = mMap.get(key);
		return tmp != null && tmp instanceof Number ? ((Number)tmp).longValue() : def;
	}

	/**
	 * get float value.
	 * 
	 * @param key key.
	 * @param def default value.
	 * @return value or default value.
	 */
	public float getFloat(String key, float def)
	{
		Object tmp = mMap.get(key);
		return tmp != null && tmp instanceof Number ? ((Number)tmp).floatValue() : def;
	}

	/**
	 * get double value.
	 * 
	 * @param key key.
	 * @param def default value.
	 * @return value or default value.
	 */
	public double getDouble(String key, double def)
	{
		Object tmp = mMap.get(key);
		return tmp != null && tmp instanceof Number ? ((Number)tmp).doubleValue() : def;
	}

	/**
	 * get string value.
	 * 
	 * @param key key.
	 * @return value or default value.
	 */
	public String getString(String key)
	{
		Object tmp = mMap.get(key);
		return tmp == null ? null : tmp.toString();
	}

	/**
	 * get JSONArray value.
	 * 
	 * @param key key.
	 * @return value or default value.
	 */
	public JSONArray getArray(String key)
	{
		Object tmp = mMap.get(key);
		return tmp == null ? null : tmp instanceof JSONArray ? (JSONArray)tmp : null;
	}

	/**
	 * get JSONObject value.
	 * 
	 * @param key key.
	 * @return value or default value.
	 */
	public JSONObject getObject(String key)
	{
		Object tmp = mMap.get(key);
		return tmp == null ? null : tmp instanceof JSONObject ? (JSONObject)tmp : null;
	}

	/**
	 * get key iterator.
	 * 
	 * @return key iterator.
	 */
	public Iterator<String> keys()
	{
		return mMap.keySet().iterator();
	}

	/**
	 * contains key.
	 * 
	 * @param key key.
	 * @return contains or not.
	 */
	public boolean contains(String key)
	{
		return mMap.containsKey(key);
	}

	/**
	 * put value.
	 * 
	 * @param name name.
	 * @param value value.
	 */
	public void put(String name, Object value)
	{
		mMap.put(name, value);
	}

	/**
	 * put all.
	 * 
	 * @param names name array.
	 * @param values value array.
	 */
	public void putAll(String[] names, Object[] values)
	{
		for(int i=0,len=Math.min(names.length, values.length);i<len;i++)
			mMap.put(names[i], values[i]);
	}

	/**
	 * put all.
	 * 
	 * @param map map.
	 */
	public void putAll(Map<String, Object> map)
	{
		for( Map.Entry<String, Object> entry : map.entrySet() )
			mMap.put(entry.getKey(), entry.getValue());
	}

	/**
	 * write json.
	 * 
	 * @param jc json converter.
	 * @param jb json builder.
	 */
	public void writeJSON(JSONConverter jc, JSONWriter jb, boolean writeClass) throws IOException
	{
		String key;
		Object value;
		jb.objectBegin();
		for( Map.Entry<String,Object> entry : mMap.entrySet() )
		{
			key = entry.getKey();
			jb.objectItem(key);
			value = entry.getValue();
			if( value == null )
				jb.valueNull();
			else
				jc.writeValue(value, jb, writeClass);
		}
		jb.objectEnd();
	}
}