/*
 * Copyright (C) 2018-2020 Western Digital Corporation or its affiliates
 * Copyright (C) 2017-2018 Wearable, Inc.
 * Copyright (C) 2000-2012 leJOS Contributors
 * Copyright (C) 2000 Jose H. Solorzano and TinyVM Contributors
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 * 
 * This Source Code Form is “Incompatible With Secondary Licenses”,
 * as defined by the Mozilla Public License, v. 2.0.
 */

package java.lang;

import org.naniteproject.VM;

/**
 * All classes extend this one, implicitly.
 */
public class Object
{
    /**
     * Creates a shallow copy of the supplied Object
     * @param old Object to clone
     * @return A shallow copy of the Object
     */
    private static final native Object cloneObject(Object old);
    
    /**
	 * Wake up one thread blocked on a wait(). Must be synchronized on
	 * this object otherwise an IllegalMonitorStateException will be thrown.
	 * <P>
	 * If multiple threads are waiting, higher priority threads will be woken
	 * in preference, otherwise the thread that gets woken is essentially
	 * random. 
	 */
	public final native void notify();
	
	/**
	 * Wait until notified. Must be synchronized on this object otherwise
	 * an IllegalMonitorStateException will be thrown. The wait can
	 * terminate if one of the following things occurs:
	 * <ol>
	 * <li>notify() or notifyAll() is called.
	 * <li>The calling thread is interrupted.
	 * <li>The timeout expires.
	 * </ol>
	 * @param timeout maximum time in milliseconds to wait. Zero means forever.
	 */
	public final native void wait(long timeout) throws InterruptedException;
	
	
	/**
	 * Wake up all threads blocked on a wait(). Must be synchronized on
	 * this object otherwise an IllegalMonitorStateException will be thrown.
	 */
	public final native void notifyAll();

    /**
     * Create a copy of this object, using a shallow copy.
     * @return The new copy of the Object
     * @throws java.lang.CloneNotSupportedException
     */
	protected Object clone() throws CloneNotSupportedException
	{
		if (this instanceof Cloneable)
        	return cloneObject(this);

		throw new CloneNotSupportedException();
	}
	
	public boolean equals (Object aOther)
	{
		return this == aOther;
	}
	
	/**
	 * @deprecated not implemented 
	 */
	@Deprecated
	protected void finalize()
	{
		//nothing
	}

	public final native Class<?> getClass();

	public int hashCode()
	{
		return System.identityHashCode(this);
	}

	public String toString()
	{
		int hash = System.identityHashCode(this);
		return getClass().toString() + "@" + Integer.toHexString(hash);
	}
	
	public final void wait() throws InterruptedException
	{
		wait(0);
	}
	
	public final void wait(long timeout, int nanos) throws InterruptedException
	{
		//rounding up
		if (nanos > 0)
			timeout++;
		
		this.wait(timeout);
	}
}







