/**
 *
 */
package cn.citycraft.GsonAgent.normal;

import java.lang.reflect.Field;
import java.util.AbstractMap;
import java.util.Map;
import java.util.Set;

import com.google.gson.internal.LinkedTreeMap;

import cn.citycraft.GsonAgent.api.JsonObject;
import cn.citycraft.GsonAgent.api.utils.Utils;

/**
 *
 * @since 2016年1月5日 下午1:49:41
 * @author 喵♂呜
 */
public class JsonObjectHandle extends JsonElementHandle implements JsonObject {

	private static Field membersField;

	static {
		try {
			membersField = com.google.gson.JsonObject.class.getDeclaredField("members");
			membersField.setAccessible(true);
		} catch (final Exception e) {
			e.printStackTrace();
		}
	}

	private final com.google.gson.JsonObject handle;

	private AbstractMap<String, com.google.gson.JsonElement> members;

	public JsonObjectHandle() {
		this(new com.google.gson.JsonObject());
	}

	@SuppressWarnings("unchecked")
	protected JsonObjectHandle(final com.google.gson.JsonObject handle) {
		this.handle = handle;
		try {
			members = (AbstractMap<String, com.google.gson.JsonElement>) membersField.get(this.handle);
		} catch (final Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void add(final String property, final cn.citycraft.GsonAgent.api.JsonElement value) {
		handle.add(property, ((JsonElementHandle) value).getHandle());
	}

	@Override
	public void addProperty(final String property, final Boolean value) {
		handle.addProperty(property, value);
	}

	@Override
	public void addProperty(final String property, final Character value) {
		handle.addProperty(property, value);
	}

	@Override
	public void addProperty(final String property, final Number value) {
		handle.addProperty(property, value);
	}

	@Override
	public void addProperty(final String property, final String value) {
		handle.addProperty(property, value);
	}

	@Override
	public cn.citycraft.GsonAgent.api.JsonObject deepCopy() {
		return new JsonObjectHandle(Utils.deepCopyObject(this.handle));
	}

	@Override
	public Set<Map.Entry<String, cn.citycraft.GsonAgent.api.JsonElement>> entrySet() {
		try {
			final Map<String, cn.citycraft.GsonAgent.api.JsonElement> result = new LinkedTreeMap<>();
			for (final Map.Entry<String, com.google.gson.JsonElement> entry : members.entrySet()) {
				result.put(entry.getKey(), new JsonElementHandle(entry.getValue()));
			}
			return result.entrySet();
		} catch (final Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public boolean equals(final Object o) {
		return handle.equals(o);
	}

	@Override
	public JsonElementHandle get(final String memberName) {
		return new JsonElementHandle(handle.get(memberName));
	}

	@Override
	public JsonArrayHandle getAsJsonArray(final String memberName) {
		return new JsonArrayHandle(handle.getAsJsonArray(memberName));
	}

	@Override
	public JsonObjectHandle getAsJsonObject(final String memberName) {
		return new JsonObjectHandle(handle.getAsJsonObject(memberName));
	}

	@Override
	public JsonPrimitiveHandle getAsJsonPrimitive(final String memberName) {
		return new JsonPrimitiveHandle(handle.getAsJsonPrimitive(memberName));
	}

	@Override
	public boolean has(final String memberName) {
		return handle.has(memberName);
	}

	@Override
	public int hashCode() {
		return handle.hashCode();
	}

	@Override
	public JsonElementHandle remove(final String property) {
		return new JsonElementHandle(handle.remove(property));
	}
}
