package ucd.rubicon.network;

import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.Serializable;

/**
 * Describes the generic message used to communicate between multiple RUBICON islands managed by distinct RUBICON Gateways
 * The RubiconGateway allows for seamless transmission of RubiconMessage objects (or their specialization) among multiple islands
 * 
 * @author Mauro Dragone - UCD (<a href="mailto:mauro.dragone@ucd.ie">Contact</a>)
 *
 */
public class RubiconMessage implements Serializable {
	/**
	 * The {@Link RubiconAddress} of the sender
	 */
	protected RubiconAddress sender;
	
	protected int userType = 0;
		

	/**
	 * A user object associated to this message
	 * (to be used when the data to be sent it is not a RubiconMessage.
	 * For example, TinyOS msgs classes generated by mig can be added
	 * as user objects inside a RubiconMessage object.
	 */
	protected Object userObject;
	
	
	/**
	 * Defines a message with a given sender and user object 
	 * @param sender
	 * @param userObject
	 */
	public RubiconMessage(RubiconAddress sender, int userType, Object userObject) {
		this.sender = sender;
		this.userType = userType;
		this.userObject = userObject;
	}

	/**
	 * Defines a message with a given sender and user object 
	 * @param sender
	 * @param userObject
	 */
	public RubiconMessage(RubiconAddress sender, Object userObject) {
		this.sender = sender;
		this.userType = 0;
		this.userObject = userObject;
	}
	
	/**
	 * Copy constructor
	 * @param message
	 */
	public RubiconMessage(RubiconMessage message) {
		this.sender = message.sender;
		this.userObject = message.getUserObject();
	}
	
	/**
	 * Defines a message with a given sender and a null user object 
	 * @param sender
	 */
	public RubiconMessage(RubiconAddress sender) {
		this(sender, 0, null);
	}
	
	/**
	 * Used to retrieve the sender for this message
	 * @return the {@Link RubiconAddress} of the sender
	 */
	public RubiconAddress getSender() {
		return sender;
	}

	/**
	 * Used to retrieve the content of this message
	 * @return the user object of this message
	 */
	public Object getUserObject() {
		return userObject;
	}
	
	/**
	 * Used to retrieve the embedded format version for this message
	 * The default is to return the userObject, if it is an array of bytes
	 * @return
	 */
	public byte[] toEmbeddedFormat() {
		if (userObject instanceof byte[]) {
			return (byte[])userObject;
		} else {
			return null;
		}
	}
		
	public String toString() {
		return "RubiconMessage from sender "+sender.toString();
	}
	
}
