/*
 * Proxy.java
 *
 * Copyright (c) 2007  Vreixo Formoso
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * See COPYING file for details.
 */

package org.pykix.libburnia.bindings;

import java.lang.ref.WeakReference;
import java.util.HashMap;

/**
 * Wrapper around a native C resource, i.e., a pointer.
 * 
 * <p>
 * This also keeps track of all Java objects that are a wrapper around
 * a C object, to prevent replication of objects when retrieved from C
 * side.
 * 
 * <p>
 * <b>This class is a implementation detail, that should be never user
 * by a developer</b>
 * 
 * @author Vreixo Formoso
 * @since 0.1
 */
public abstract class Proxy {

	/** Pointer to C object. */
	private final long pointer;
	
	/** Keeps track of existing pointers. */
	private static final HashMap<Long, WeakReference<Proxy>> proxies = 
		new HashMap<Long, WeakReference<Proxy>>();
	
	protected Proxy(long ptr) {
		
		assert ptr != 0 : "Can't proxy a NULL pointer";
		assert proxies.get(ptr) == null : 
			"Can't create a pointer for an existing proxy";
		
		pointer = ptr;
		proxies.put( ptr, new WeakReference<Proxy>(this) );
	}
	
	@Override
	protected void finalize() throws Throwable {
		super.finalize();
		proxies.remove(pointer);
	}
	
	/**
	 * Get C pointer for a Proxy.
	 * 
	 * @param obj
	 * @return
	 */
	protected static long pointerOf(Proxy obj) {
		return obj.pointer;
	}
	
	/**
	 * Get the proxy registered for a pointer.
	 * 
	 * @param ptr
	 * 		Pointer
	 * @return
	 * 		The Proxy or <code>null</code> if no Proxy is registered.
	 */
	protected static Proxy proxyFor(long ptr) {
		
		WeakReference<Proxy> ref = proxies.get(ptr);
		return ref == null ? null : ref.get();
	}
	
}
